From 644bcf9895b69679c3f4ad064ac9b001f7739b89 Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 28 Jul 2026 20:45:30 +0300 Subject: [PATCH] add chat basics --- .../androidApp/build.gradle.kts | 2 +- apps/experimentarium/shared/build.gradle.kts | 2 +- apps/experimentarium/web/build.gradle.kts | 2 +- apps/vbox/backend/build.gradle.kts | 2 +- apps/vbox/client/androidApp/build.gradle.kts | 4 +- apps/vbox/client/shared/build.gradle.kts | 4 +- apps/vbox/client/web/build.gradle.kts | 4 +- .../chat/chat-backend}/.gitignore | 0 feature/chat/chat-backend/build.gradle.kts | 12 +++ .../chat/backend/BackendChatModule.kt | 10 ++ .../chat/backend/data/GigaChatService.kt | 97 +++++++++++++++++++ .../chat/backend/data/GigaChatTokenManager.kt | 58 +++++++++++ .../chat/backend/domain/ChatService.kt | 7 ++ .../chat/backend/domain/MessageStorage.kt | 8 ++ .../domain/ProcessUserMessageUseCase.kt | 35 +++++++ .../chat/chat-client}/.gitignore | 0 feature/chat/chat-client/build.gradle.kts | 30 ++++++ .../chat/chat-common}/.gitignore | 0 feature/chat/chat-common/build.gradle.kts | 16 +++ .../chat/domain/ChatRepository.kt | 9 ++ .../ru/shadowsparky/chat/domain/ChatRoles.kt | 7 ++ .../ru/shadowsparky/chat/domain/Message.kt | 11 +++ feature/updater/updater-client/.gitignore | 2 + .../updater/updater-client/build.gradle.kts | 2 +- .../src/androidMain/AndroidManifest.xml | 0 .../updater/data/AndroidUpdateInstaller.kt | 0 .../updater/data/KtorUpdateDownloader.kt | 0 .../presentation/UpdateInstalledReceiver.kt | 0 .../src/androidMain/res/xml/file_paths.xml | 0 .../composeResources/values/strings.xml | 0 .../ru/shadowsparky/updater/UpdaterModule.kt | 0 .../updater/domain/UpdateDownloader.kt | 0 .../updater/domain/UpdateInstaller.kt | 0 .../updater/domain/UpdateInteractor.kt | 0 .../updater/domain/UpdateState.kt | 0 .../updater/presentation/UpdateComponent.kt | 0 .../updater/presentation/UpdateDialog.kt | 0 feature/updater/updater-common/.gitignore | 2 + .../updater/updater-common/build.gradle.kts | 0 .../src/commonMain/kotlin/UpdateFetcher.kt | 0 .../src/commonMain/kotlin/UpdateInfo.kt | 0 feature/video-player/.gitignore | 2 + .../video-player/build.gradle.kts | 0 .../videoplayer/AndroidPlayerController.kt | 0 .../videoplayer/ExternalPlayer.android.kt | 0 .../videoplayer/ui/PictureInPicture.kt | 0 .../videoplayer/ui/VideoCanvas.android.kt | 0 .../composeResources/drawable/lock_24px.xml | 0 .../drawable/lock_open_24px.xml | 0 .../drawable/music_note_24px.xml | 0 .../composeResources/drawable/pause_24px.xml | 0 .../drawable/play_arrow_24px.xml | 0 .../composeResources/drawable/replay_24px.xml | 0 .../composeResources/values/strings.xml | 0 .../videoplayer/AudioTrackInfo.kt | 0 .../shadowsparky/videoplayer/CanvasEvent.kt | 0 .../shadowsparky/videoplayer/ControlsState.kt | 0 .../videoplayer/ExternalPlayer.kt | 0 .../videoplayer/PlayerController.kt | 0 .../shadowsparky/videoplayer/PlayerEvent.kt | 0 .../shadowsparky/videoplayer/PlayerState.kt | 0 .../videoplayer/VideoPlayerModule.kt | 0 .../videoplayer/VideoScaleType.kt | 0 .../videoplayer/ui/DefaultControls.kt | 0 .../videoplayer/ui/VideoCanvas.kt | 0 .../videoplayer/ui/VideoPlayer.kt | 0 .../videoplayer/ExternalPlayer.desktop.kt | 0 .../videoplayer/ui/VideoCanvas.desktop.kt | 0 .../videoplayer/ExternalPlayer.wasmJs.kt | 0 .../videoplayer/WasmPlayerController.kt | 0 .../videoplayer/ui/VideoCanvas.wasmJs.kt | 0 settings.gradle.kts | 9 +- 72 files changed, 323 insertions(+), 14 deletions(-) rename {libs/updater/updater-client => feature/chat/chat-backend}/.gitignore (100%) create mode 100644 feature/chat/chat-backend/build.gradle.kts create mode 100644 feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/BackendChatModule.kt create mode 100644 feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatService.kt create mode 100644 feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatTokenManager.kt create mode 100644 feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ChatService.kt create mode 100644 feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/MessageStorage.kt create mode 100644 feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ProcessUserMessageUseCase.kt rename {libs/updater/updater-common => feature/chat/chat-client}/.gitignore (100%) create mode 100644 feature/chat/chat-client/build.gradle.kts rename {libs/video-player => feature/chat/chat-common}/.gitignore (100%) create mode 100644 feature/chat/chat-common/build.gradle.kts create mode 100644 feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRepository.kt create mode 100644 feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRoles.kt create mode 100644 feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/Message.kt create mode 100644 feature/updater/updater-client/.gitignore rename {libs => feature}/updater/updater-client/build.gradle.kts (92%) rename {libs => feature}/updater/updater-client/src/androidMain/AndroidManifest.xml (100%) rename {libs => feature}/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/AndroidUpdateInstaller.kt (100%) rename {libs => feature}/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/KtorUpdateDownloader.kt (100%) rename {libs => feature}/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/presentation/UpdateInstalledReceiver.kt (100%) rename {libs => feature}/updater/updater-client/src/androidMain/res/xml/file_paths.xml (100%) rename {libs => feature}/updater/updater-client/src/commonMain/composeResources/values/strings.xml (100%) rename {libs => feature}/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/UpdaterModule.kt (100%) rename {libs => feature}/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateDownloader.kt (100%) rename {libs => feature}/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInstaller.kt (100%) rename {libs => feature}/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInteractor.kt (100%) rename {libs => feature}/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateState.kt (100%) rename {libs => feature}/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt (100%) rename {libs => feature}/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateDialog.kt (100%) create mode 100644 feature/updater/updater-common/.gitignore rename {libs => feature}/updater/updater-common/build.gradle.kts (100%) rename {libs => feature}/updater/updater-common/src/commonMain/kotlin/UpdateFetcher.kt (100%) rename {libs => feature}/updater/updater-common/src/commonMain/kotlin/UpdateInfo.kt (100%) create mode 100644 feature/video-player/.gitignore rename {libs => feature}/video-player/build.gradle.kts (100%) rename {libs => feature}/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/AndroidPlayerController.kt (100%) rename {libs => feature}/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.android.kt (100%) rename {libs => feature}/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/PictureInPicture.kt (100%) rename {libs => feature}/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.android.kt (100%) rename {libs => feature}/video-player/src/commonMain/composeResources/drawable/lock_24px.xml (100%) rename {libs => feature}/video-player/src/commonMain/composeResources/drawable/lock_open_24px.xml (100%) rename {libs => feature}/video-player/src/commonMain/composeResources/drawable/music_note_24px.xml (100%) rename {libs => feature}/video-player/src/commonMain/composeResources/drawable/pause_24px.xml (100%) rename {libs => feature}/video-player/src/commonMain/composeResources/drawable/play_arrow_24px.xml (100%) rename {libs => feature}/video-player/src/commonMain/composeResources/drawable/replay_24px.xml (100%) rename {libs => feature}/video-player/src/commonMain/composeResources/values/strings.xml (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/AudioTrackInfo.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/CanvasEvent.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ControlsState.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerController.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerEvent.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerState.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoPlayerModule.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoScaleType.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/DefaultControls.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.kt (100%) rename {libs => feature}/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoPlayer.kt (100%) rename {libs => feature}/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.desktop.kt (100%) rename {libs => feature}/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.desktop.kt (100%) rename {libs => feature}/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.wasmJs.kt (100%) rename {libs => feature}/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/WasmPlayerController.kt (100%) rename {libs => feature}/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.wasmJs.kt (100%) diff --git a/apps/experimentarium/androidApp/build.gradle.kts b/apps/experimentarium/androidApp/build.gradle.kts index 950e696..1be3886 100644 --- a/apps/experimentarium/androidApp/build.gradle.kts +++ b/apps/experimentarium/androidApp/build.gradle.kts @@ -27,7 +27,7 @@ dependencies { implementation(libs.activity.compose) implementation(libs.material) implementation(project(":apps:experimentarium:shared")) - implementation(project(":libs:video-player")) + implementation(project(":feature:video-player")) implementation(project(":libs:ui")) implementation(project(":libs:base")) testImplementation(libs.koin.test) diff --git a/apps/experimentarium/shared/build.gradle.kts b/apps/experimentarium/shared/build.gradle.kts index bdb2e8b..b6cbb3d 100644 --- a/apps/experimentarium/shared/build.gradle.kts +++ b/apps/experimentarium/shared/build.gradle.kts @@ -9,7 +9,7 @@ kotlin { sourceSets { commonMain.dependencies { implementation(project(":libs:base")) - implementation(project(":libs:video-player")) + implementation(project(":feature:video-player")) } androidMain.dependencies { } diff --git a/apps/experimentarium/web/build.gradle.kts b/apps/experimentarium/web/build.gradle.kts index 0bcd67e..09f2211 100644 --- a/apps/experimentarium/web/build.gradle.kts +++ b/apps/experimentarium/web/build.gradle.kts @@ -15,7 +15,7 @@ kotlin { dependencies { implementation(project(":libs:base")) implementation(project(":libs:ui")) - implementation(project(":libs:video-player")) + implementation(project(":feature:video-player")) implementation(project(":apps:experimentarium:shared")) } } diff --git a/apps/vbox/backend/build.gradle.kts b/apps/vbox/backend/build.gradle.kts index 4cb8393..8bd9ee3 100644 --- a/apps/vbox/backend/build.gradle.kts +++ b/apps/vbox/backend/build.gradle.kts @@ -20,7 +20,7 @@ dependencies { implementation(project(":libs:backend-base")) implementation(project(":libs:base")) implementation(project(":libs:http-client")) - implementation(project(":libs:updater:updater-common")) + implementation(project(":feature:updater:updater-common")) implementation(libs.ktor.server.core.jvm) implementation(libs.ktor.server.host.common.jvm) diff --git a/apps/vbox/client/androidApp/build.gradle.kts b/apps/vbox/client/androidApp/build.gradle.kts index ad44da7..772573e 100644 --- a/apps/vbox/client/androidApp/build.gradle.kts +++ b/apps/vbox/client/androidApp/build.gradle.kts @@ -26,8 +26,8 @@ dependencies { implementation(project(":libs:base")) implementation(project(":libs:ui")) implementation(project(":libs:http-client")) - implementation(project(":libs:video-player")) - implementation(project(":libs:updater:updater-client")) + implementation(project(":feature:video-player")) + implementation(project(":feature:updater:updater-client")) debugImplementation(libs.ui.tooling) implementation(libs.ui.tooling.preview) testImplementation(libs.koin.test) diff --git a/apps/vbox/client/shared/build.gradle.kts b/apps/vbox/client/shared/build.gradle.kts index a1cabb7..616b70f 100644 --- a/apps/vbox/client/shared/build.gradle.kts +++ b/apps/vbox/client/shared/build.gradle.kts @@ -25,8 +25,8 @@ kotlin { implementation(project(":libs:base")) implementation(project(":libs:ui")) implementation(project(":libs:http-client")) - implementation(project(":libs:video-player")) - implementation(project(":libs:updater:updater-client")) + implementation(project(":feature:video-player")) + implementation(project(":feature:updater:updater-client")) } androidMain.dependencies { implementation(libs.androidx.appcompat) diff --git a/apps/vbox/client/web/build.gradle.kts b/apps/vbox/client/web/build.gradle.kts index 3865bd7..10a91b0 100644 --- a/apps/vbox/client/web/build.gradle.kts +++ b/apps/vbox/client/web/build.gradle.kts @@ -19,8 +19,8 @@ kotlin { implementation(project(":libs:base")) implementation(project(":libs:ui")) implementation(project(":libs:http-client")) - implementation(project(":libs:video-player")) - implementation(project(":libs:updater:updater-client")) + implementation(project(":feature:video-player")) + implementation(project(":feature:updater:updater-client")) } } } diff --git a/libs/updater/updater-client/.gitignore b/feature/chat/chat-backend/.gitignore similarity index 100% rename from libs/updater/updater-client/.gitignore rename to feature/chat/chat-backend/.gitignore diff --git a/feature/chat/chat-backend/build.gradle.kts b/feature/chat/chat-backend/build.gradle.kts new file mode 100644 index 0000000..4d361bc --- /dev/null +++ b/feature/chat/chat-backend/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + alias(libs.plugins.convention.jvm) + alias(libs.plugins.convention.ktor.client) + alias(libs.plugins.convention.koin) + alias(libs.plugins.convention.serialization) +} + +dependencies { + implementation(project(":libs:backend-base")) + implementation(project(":libs:http-client")) + implementation(project(":feature:chat:chat-common")) +} diff --git a/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/BackendChatModule.kt b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/BackendChatModule.kt new file mode 100644 index 0000000..8cb82f8 --- /dev/null +++ b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/BackendChatModule.kt @@ -0,0 +1,10 @@ +package ru.shadowsparky.chat.backend + +import org.koin.core.annotation.ComponentScan +import org.koin.core.annotation.Configuration +import org.koin.core.annotation.Module + +@Module +@ComponentScan +@Configuration +class BackendChatModule diff --git a/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatService.kt b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatService.kt new file mode 100644 index 0000000..cf97b17 --- /dev/null +++ b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatService.kt @@ -0,0 +1,97 @@ +package ru.shadowsparky.chat.backend.data + +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.plugins.auth.Auth +import io.ktor.client.plugins.auth.providers.BearerTokens +import io.ktor.client.plugins.auth.providers.bearer +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.header +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.http.contentType +import io.ktor.serialization.kotlinx.json.json +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import org.koin.core.annotation.Factory +import ru.shadowsparky.chat.backend.domain.ChatService +import ru.shadowsparky.chat.domain.Message +import ru.shadowsparky.http.domain.HttpException +import java.util.UUID + +@Factory +class GigaChatService( + private val tokenManager: GigaChatTokenManager, + private val json: Json +) : ChatService { + private val httpClient by lazy { createGigaChatHttpClient() } + + override suspend fun getCompletion(userId: Long, messages: List): String { + val clientId = "vbox-$userId" + val staticSessionId = UUID.nameUUIDFromBytes(clientId.toByteArray()).toString() + val requestBody = GigaChatRequest( + messages = messages.map { GigaChatMessageDto(role = it.role, content = it.content) } + ) + val response = try { + executeRequest(clientId, staticSessionId, requestBody) + } catch (e: HttpException) { + if (e.httpCode == HttpStatusCode.Unauthorized.value) { + tokenManager.forceRefreshToken() + executeRequest(clientId, staticSessionId, requestBody) + } else { + throw e + } + } + return response.choices.firstOrNull()?.message?.content + ?: error("unexpected response $response") + } + + private suspend fun executeRequest(clientId: String, sessionId: String, body: GigaChatRequest): GigaChatResponse { + return httpClient.post("https://api.giga.chat/v1/chat/completions") { + contentType(ContentType.Application.Json) + header("X-Request-ID", UUID.randomUUID().toString()) + header("X-Session-ID", sessionId) + header("X-Client-ID", clientId) + setBody(body) + }.body() + } + + private fun createGigaChatHttpClient(): HttpClient { + return HttpClient { + install(ContentNegotiation) { json(json) } + install(Auth) { + bearer { + loadTokens { BearerTokens(tokenManager.getToken(), "") } + refreshTokens { + val newToken = tokenManager.forceRefreshToken() + BearerTokens(newToken, "") + } + } + } + } + } + + @Serializable + private data class GigaChatRequest( + val model: String = "GigaChat-2", + val stream: Boolean = false, + @SerialName("update_interval") + val updateInterval: Int = 0, + val messages: List + ) + + @Serializable + private data class GigaChatMessageDto( + val role: String, + val content: String + ) + + @Serializable + private data class GigaChatResponse(val choices: List) + + @Serializable + private data class GigaChatChoiceDto(val message: GigaChatMessageDto) +} diff --git a/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatTokenManager.kt b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatTokenManager.kt new file mode 100644 index 0000000..09d4fc5 --- /dev/null +++ b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/data/GigaChatTokenManager.kt @@ -0,0 +1,58 @@ +package ru.shadowsparky.chat.backend.data + +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.request.forms.FormDataContent +import io.ktor.client.request.header +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import io.ktor.http.ContentType +import io.ktor.http.HttpHeaders +import io.ktor.http.Parameters +import io.ktor.http.contentType +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import org.koin.core.annotation.Single +import ru.shadowsparky.backend.data.EnvFetcher +import java.util.UUID + +@Single +class GigaChatTokenManager( + private val authClient: HttpClient, + private val json: Json, + private val envFetcher: EnvFetcher +) { + private val scope: String = "GIGACHAT_API_PERS" + + private val mutex = Mutex() + private var cachedToken: String? = null + + suspend fun getToken(): String = mutex.withLock { + cachedToken ?: fetchNewToken() + } + + suspend fun forceRefreshToken(): String = mutex.withLock { + fetchNewToken() + } + + private suspend fun fetchNewToken(): String { + val auth = envFetcher.get("GIGA_CHAT_AUTH_TOKEN").ifEmpty { error("auth token not provided") } + val responseString: String = authClient.post("https://ngw.devices.sberbank.ru:9443/api/v2/oauth") { + header(HttpHeaders.Authorization, auth) + header("RqUID", UUID.randomUUID().toString()) + contentType(ContentType.Application.FormUrlEncoded) + setBody(FormDataContent(Parameters.build { + append("scope", scope) + })) + }.body() + val token = json.parseToJsonElement(responseString).jsonObject["access_token"] + ?.jsonPrimitive + ?.content + ?: error("Unable to fetch token. response $responseString") + cachedToken = token + return token + } +} diff --git a/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ChatService.kt b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ChatService.kt new file mode 100644 index 0000000..443d5ee --- /dev/null +++ b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ChatService.kt @@ -0,0 +1,7 @@ +package ru.shadowsparky.chat.backend.domain + +import ru.shadowsparky.chat.domain.Message + +interface ChatService { + suspend fun getCompletion(userId: Long, messages: List): String +} diff --git a/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/MessageStorage.kt b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/MessageStorage.kt new file mode 100644 index 0000000..245a3e7 --- /dev/null +++ b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/MessageStorage.kt @@ -0,0 +1,8 @@ +package ru.shadowsparky.chat.backend.domain + +import ru.shadowsparky.chat.domain.Message + +interface MessageStorage { + suspend fun query(userId: Long, limit: Int): List + suspend fun insert(userId: Long, message: Message): Long +} diff --git a/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ProcessUserMessageUseCase.kt b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ProcessUserMessageUseCase.kt new file mode 100644 index 0000000..911cd96 --- /dev/null +++ b/feature/chat/chat-backend/src/main/kotlin/ru/shadowsparky/chat/backend/domain/ProcessUserMessageUseCase.kt @@ -0,0 +1,35 @@ +package ru.shadowsparky.chat.backend.domain + +import org.koin.core.annotation.Factory +import ru.shadowsparky.chat.domain.ChatRoles +import ru.shadowsparky.chat.domain.Message + +@Factory +class ProcessUserMessageUseCase( + private val storage: MessageStorage, + private val chatService: ChatService +) { + suspend fun execute(userId: Long, userMessage: Message): Message { + storage.insert(userId, userMessage) + val history = storage.query(userId, limit = 10).toList() + val sortedHistory = history.sortedBy { it.timestamp } + val systemMessage = Message( + role = ChatRoles.SYSTEM, + content = SYSTEM_PROMPT, + timestamp = System.currentTimeMillis() + ) + val fullContext = listOf(systemMessage) + sortedHistory + val aiResponseText = chatService.getCompletion(userId, fullContext) + val aiMessage = Message( + role = ChatRoles.ASSISTANT, + content = aiResponseText, + timestamp = System.currentTimeMillis() + ) + val messageId = storage.insert(userId, aiMessage) + return aiMessage.copy(id = messageId) + } + + companion object { + private const val SYSTEM_PROMPT = "Ты ИИ-помощник приложения \"Свиное рыло\". Ищи юзерам фильмы и сериалы. Правила: 1. Называй юзера \"свинорылец\" (Пример: \"Здорово, свинорылец!\"). 2. Общайся по-свойски, с юмором, иронично. 3. Если юзер сомневается, задай 2 наводящих вопроса. 4. Выдавай строго до 5 позиций максимум, даже если просят больше. Описание короткое (1-2 предложения). 5. Каждое название фильма/сериала ВСЕГДА строго оборачивай в теги [MOVIE]Название[/MOVIE]. 6. На нерелевантные темы не общайся, переводи разговор на кино в свиной тематике." + } +} diff --git a/libs/updater/updater-common/.gitignore b/feature/chat/chat-client/.gitignore similarity index 100% rename from libs/updater/updater-common/.gitignore rename to feature/chat/chat-client/.gitignore diff --git a/feature/chat/chat-client/build.gradle.kts b/feature/chat/chat-client/build.gradle.kts new file mode 100644 index 0000000..574cf06 --- /dev/null +++ b/feature/chat/chat-client/build.gradle.kts @@ -0,0 +1,30 @@ +plugins { + alias(libs.plugins.convention.kmp) + alias(libs.plugins.convention.android.lib) + alias(libs.plugins.convention.serialization) + alias(libs.plugins.convention.koin) + alias(libs.plugins.convention.compose) +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":libs:ui")) + implementation(project(":libs:base")) + api(project(":feature:chat:chat-common")) + implementation(libs.ui.tooling.preview) + } + } + val androidMain by getting { + dependencies { + implementation(libs.androidx.core) + } + } + } + android { namespace = "ru.shadowsparky.chat" } +} + +dependencies { + androidRuntimeClasspath(libs.ui.tooling) +} diff --git a/libs/video-player/.gitignore b/feature/chat/chat-common/.gitignore similarity index 100% rename from libs/video-player/.gitignore rename to feature/chat/chat-common/.gitignore diff --git a/feature/chat/chat-common/build.gradle.kts b/feature/chat/chat-common/build.gradle.kts new file mode 100644 index 0000000..6eefd57 --- /dev/null +++ b/feature/chat/chat-common/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + alias(libs.plugins.convention.kmp) + alias(libs.plugins.convention.android.lib) + alias(libs.plugins.convention.serialization) +} + +kotlin { + sourceSets { + val commonMain by getting { + dependencies { + implementation(project(":libs:base")) + } + } + } + android { namespace = "ru.shadowsparky.chat.common" } +} diff --git a/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRepository.kt b/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRepository.kt new file mode 100644 index 0000000..1400566 --- /dev/null +++ b/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRepository.kt @@ -0,0 +1,9 @@ +package ru.shadowsparky.chat.domain + +import kotlinx.coroutines.flow.Flow + +interface ChatRepository { + val messages: Flow + + suspend fun sendMessage(message: Message) +} diff --git a/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRoles.kt b/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRoles.kt new file mode 100644 index 0000000..37409b3 --- /dev/null +++ b/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/ChatRoles.kt @@ -0,0 +1,7 @@ +package ru.shadowsparky.chat.domain + +object ChatRoles { + const val USER = "user" + const val SYSTEM = "system" + const val ASSISTANT = "assistant" +} diff --git a/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/Message.kt b/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/Message.kt new file mode 100644 index 0000000..c34bcfb --- /dev/null +++ b/feature/chat/chat-common/src/commonMain/kotlin/ru/shadowsparky/chat/domain/Message.kt @@ -0,0 +1,11 @@ +package ru.shadowsparky.chat.domain + +import kotlinx.serialization.Serializable + +@Serializable +data class Message( + val id: Long? = null, + val role: String, + val content: String, + val timestamp: Long +) diff --git a/feature/updater/updater-client/.gitignore b/feature/updater/updater-client/.gitignore new file mode 100644 index 0000000..2f230b7 --- /dev/null +++ b/feature/updater/updater-client/.gitignore @@ -0,0 +1,2 @@ +/build +/bin \ No newline at end of file diff --git a/libs/updater/updater-client/build.gradle.kts b/feature/updater/updater-client/build.gradle.kts similarity index 92% rename from libs/updater/updater-client/build.gradle.kts rename to feature/updater/updater-client/build.gradle.kts index bc18027..8d9bae6 100644 --- a/libs/updater/updater-client/build.gradle.kts +++ b/feature/updater/updater-client/build.gradle.kts @@ -12,7 +12,7 @@ kotlin { dependencies { implementation(project(":libs:ui")) implementation(project(":libs:base")) - api(project(":libs:updater:updater-common")) + api(project(":feature:updater:updater-common")) implementation(libs.ui.tooling.preview) } } diff --git a/libs/updater/updater-client/src/androidMain/AndroidManifest.xml b/feature/updater/updater-client/src/androidMain/AndroidManifest.xml similarity index 100% rename from libs/updater/updater-client/src/androidMain/AndroidManifest.xml rename to feature/updater/updater-client/src/androidMain/AndroidManifest.xml diff --git a/libs/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/AndroidUpdateInstaller.kt b/feature/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/AndroidUpdateInstaller.kt similarity index 100% rename from libs/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/AndroidUpdateInstaller.kt rename to feature/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/AndroidUpdateInstaller.kt diff --git a/libs/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/KtorUpdateDownloader.kt b/feature/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/KtorUpdateDownloader.kt similarity index 100% rename from libs/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/KtorUpdateDownloader.kt rename to feature/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/data/KtorUpdateDownloader.kt diff --git a/libs/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/presentation/UpdateInstalledReceiver.kt b/feature/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/presentation/UpdateInstalledReceiver.kt similarity index 100% rename from libs/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/presentation/UpdateInstalledReceiver.kt rename to feature/updater/updater-client/src/androidMain/kotlin/ru/shadowsparky/updater/presentation/UpdateInstalledReceiver.kt diff --git a/libs/updater/updater-client/src/androidMain/res/xml/file_paths.xml b/feature/updater/updater-client/src/androidMain/res/xml/file_paths.xml similarity index 100% rename from libs/updater/updater-client/src/androidMain/res/xml/file_paths.xml rename to feature/updater/updater-client/src/androidMain/res/xml/file_paths.xml diff --git a/libs/updater/updater-client/src/commonMain/composeResources/values/strings.xml b/feature/updater/updater-client/src/commonMain/composeResources/values/strings.xml similarity index 100% rename from libs/updater/updater-client/src/commonMain/composeResources/values/strings.xml rename to feature/updater/updater-client/src/commonMain/composeResources/values/strings.xml diff --git a/libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/UpdaterModule.kt b/feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/UpdaterModule.kt similarity index 100% rename from libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/UpdaterModule.kt rename to feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/UpdaterModule.kt diff --git a/libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateDownloader.kt b/feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateDownloader.kt similarity index 100% rename from libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateDownloader.kt rename to feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateDownloader.kt diff --git a/libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInstaller.kt b/feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInstaller.kt similarity index 100% rename from libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInstaller.kt rename to feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInstaller.kt diff --git a/libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInteractor.kt b/feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInteractor.kt similarity index 100% rename from libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInteractor.kt rename to feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateInteractor.kt diff --git a/libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateState.kt b/feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateState.kt similarity index 100% rename from libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateState.kt rename to feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/domain/UpdateState.kt diff --git a/libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt b/feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt similarity index 100% rename from libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt rename to feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateComponent.kt diff --git a/libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateDialog.kt b/feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateDialog.kt similarity index 100% rename from libs/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateDialog.kt rename to feature/updater/updater-client/src/commonMain/kotlin/ru/shadowsparky/updater/presentation/UpdateDialog.kt diff --git a/feature/updater/updater-common/.gitignore b/feature/updater/updater-common/.gitignore new file mode 100644 index 0000000..2f230b7 --- /dev/null +++ b/feature/updater/updater-common/.gitignore @@ -0,0 +1,2 @@ +/build +/bin \ No newline at end of file diff --git a/libs/updater/updater-common/build.gradle.kts b/feature/updater/updater-common/build.gradle.kts similarity index 100% rename from libs/updater/updater-common/build.gradle.kts rename to feature/updater/updater-common/build.gradle.kts diff --git a/libs/updater/updater-common/src/commonMain/kotlin/UpdateFetcher.kt b/feature/updater/updater-common/src/commonMain/kotlin/UpdateFetcher.kt similarity index 100% rename from libs/updater/updater-common/src/commonMain/kotlin/UpdateFetcher.kt rename to feature/updater/updater-common/src/commonMain/kotlin/UpdateFetcher.kt diff --git a/libs/updater/updater-common/src/commonMain/kotlin/UpdateInfo.kt b/feature/updater/updater-common/src/commonMain/kotlin/UpdateInfo.kt similarity index 100% rename from libs/updater/updater-common/src/commonMain/kotlin/UpdateInfo.kt rename to feature/updater/updater-common/src/commonMain/kotlin/UpdateInfo.kt diff --git a/feature/video-player/.gitignore b/feature/video-player/.gitignore new file mode 100644 index 0000000..2f230b7 --- /dev/null +++ b/feature/video-player/.gitignore @@ -0,0 +1,2 @@ +/build +/bin \ No newline at end of file diff --git a/libs/video-player/build.gradle.kts b/feature/video-player/build.gradle.kts similarity index 100% rename from libs/video-player/build.gradle.kts rename to feature/video-player/build.gradle.kts diff --git a/libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/AndroidPlayerController.kt b/feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/AndroidPlayerController.kt similarity index 100% rename from libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/AndroidPlayerController.kt rename to feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/AndroidPlayerController.kt diff --git a/libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.android.kt b/feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.android.kt similarity index 100% rename from libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.android.kt rename to feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.android.kt diff --git a/libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/PictureInPicture.kt b/feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/PictureInPicture.kt similarity index 100% rename from libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/PictureInPicture.kt rename to feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/PictureInPicture.kt diff --git a/libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.android.kt b/feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.android.kt similarity index 100% rename from libs/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.android.kt rename to feature/video-player/src/androidMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.android.kt diff --git a/libs/video-player/src/commonMain/composeResources/drawable/lock_24px.xml b/feature/video-player/src/commonMain/composeResources/drawable/lock_24px.xml similarity index 100% rename from libs/video-player/src/commonMain/composeResources/drawable/lock_24px.xml rename to feature/video-player/src/commonMain/composeResources/drawable/lock_24px.xml diff --git a/libs/video-player/src/commonMain/composeResources/drawable/lock_open_24px.xml b/feature/video-player/src/commonMain/composeResources/drawable/lock_open_24px.xml similarity index 100% rename from libs/video-player/src/commonMain/composeResources/drawable/lock_open_24px.xml rename to feature/video-player/src/commonMain/composeResources/drawable/lock_open_24px.xml diff --git a/libs/video-player/src/commonMain/composeResources/drawable/music_note_24px.xml b/feature/video-player/src/commonMain/composeResources/drawable/music_note_24px.xml similarity index 100% rename from libs/video-player/src/commonMain/composeResources/drawable/music_note_24px.xml rename to feature/video-player/src/commonMain/composeResources/drawable/music_note_24px.xml diff --git a/libs/video-player/src/commonMain/composeResources/drawable/pause_24px.xml b/feature/video-player/src/commonMain/composeResources/drawable/pause_24px.xml similarity index 100% rename from libs/video-player/src/commonMain/composeResources/drawable/pause_24px.xml rename to feature/video-player/src/commonMain/composeResources/drawable/pause_24px.xml diff --git a/libs/video-player/src/commonMain/composeResources/drawable/play_arrow_24px.xml b/feature/video-player/src/commonMain/composeResources/drawable/play_arrow_24px.xml similarity index 100% rename from libs/video-player/src/commonMain/composeResources/drawable/play_arrow_24px.xml rename to feature/video-player/src/commonMain/composeResources/drawable/play_arrow_24px.xml diff --git a/libs/video-player/src/commonMain/composeResources/drawable/replay_24px.xml b/feature/video-player/src/commonMain/composeResources/drawable/replay_24px.xml similarity index 100% rename from libs/video-player/src/commonMain/composeResources/drawable/replay_24px.xml rename to feature/video-player/src/commonMain/composeResources/drawable/replay_24px.xml diff --git a/libs/video-player/src/commonMain/composeResources/values/strings.xml b/feature/video-player/src/commonMain/composeResources/values/strings.xml similarity index 100% rename from libs/video-player/src/commonMain/composeResources/values/strings.xml rename to feature/video-player/src/commonMain/composeResources/values/strings.xml diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/AudioTrackInfo.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/AudioTrackInfo.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/AudioTrackInfo.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/AudioTrackInfo.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/CanvasEvent.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/CanvasEvent.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/CanvasEvent.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/CanvasEvent.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ControlsState.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ControlsState.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ControlsState.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ControlsState.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerController.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerController.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerController.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerController.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerEvent.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerEvent.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerEvent.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerEvent.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerState.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerState.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerState.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/PlayerState.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoPlayerModule.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoPlayerModule.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoPlayerModule.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoPlayerModule.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoScaleType.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoScaleType.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoScaleType.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/VideoScaleType.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/DefaultControls.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/DefaultControls.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/DefaultControls.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/DefaultControls.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.kt diff --git a/libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoPlayer.kt b/feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoPlayer.kt similarity index 100% rename from libs/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoPlayer.kt rename to feature/video-player/src/commonMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoPlayer.kt diff --git a/libs/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.desktop.kt b/feature/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.desktop.kt similarity index 100% rename from libs/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.desktop.kt rename to feature/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.desktop.kt diff --git a/libs/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.desktop.kt b/feature/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.desktop.kt similarity index 100% rename from libs/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.desktop.kt rename to feature/video-player/src/desktopMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.desktop.kt diff --git a/libs/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.wasmJs.kt b/feature/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.wasmJs.kt similarity index 100% rename from libs/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.wasmJs.kt rename to feature/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ExternalPlayer.wasmJs.kt diff --git a/libs/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/WasmPlayerController.kt b/feature/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/WasmPlayerController.kt similarity index 100% rename from libs/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/WasmPlayerController.kt rename to feature/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/WasmPlayerController.kt diff --git a/libs/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.wasmJs.kt b/feature/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.wasmJs.kt similarity index 100% rename from libs/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.wasmJs.kt rename to feature/video-player/src/wasmJsMain/kotlin/ru/shadowsparky/videoplayer/ui/VideoCanvas.wasmJs.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index 7a44ba5..c35c949 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -42,6 +42,9 @@ include(":libs:backend-base") include(":libs:base") include(":libs:ui") include(":libs:http-client") -include(":libs:video-player") -include(":libs:updater:updater-client") -include(":libs:updater:updater-common") +include(":feature:video-player") +include(":feature:updater:updater-client") +include(":feature:updater:updater-common") +include(":feature:chat:chat-client") +include(":feature:chat:chat-common") +include(":feature:chat:chat-backend")