From 5d5b841374411e945a6d72ae674a475fd243aece Mon Sep 17 00:00:00 2001
From: Oleg Iakovlev <olegikovlev.pg@gmail.com>
Date: Fri, 28 Feb 2025 15:33:50 +0300
Subject: [PATCH 1/2] Update DataBase with new func and more

---
 .idea/misc.xml                                |  16 -
 .../java/com/example/radio2/ChatActivity.kt   | 290 ++++++++++--------
 .../example/radio2/Data/HandlersStorage.kt    |   4 +
 .../main/java/com/example/radio2/DataBase.kt  | 163 ++++++++--
 gradle/libs.versions.toml                     |   2 +-
 5 files changed, 314 insertions(+), 161 deletions(-)
 delete mode 100644 .idea/misc.xml

diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 2cff95b..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<project version="4">
-  <component name="ExternalStorageConfigurationManager" enabled="true" />
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
-    <output url="file://$PROJECT_DIR$/build/classes" />
-  </component>
-  <component name="ProjectType">
-    <option name="id" value="Android" />
-  </component>
-  <component name="VisualizationToolProject">
-    <option name="state">
-      <ProjectState>
-        <option name="scale" value="0.5654885654885655" />
-      </ProjectState>
-    </option>
-  </component>
-</project>
\ No newline at end of file
diff --git a/app/src/main/java/com/example/radio2/ChatActivity.kt b/app/src/main/java/com/example/radio2/ChatActivity.kt
index 3903bca..a25e78d 100644
--- a/app/src/main/java/com/example/radio2/ChatActivity.kt
+++ b/app/src/main/java/com/example/radio2/ChatActivity.kt
@@ -1,68 +1,43 @@
 package com.example.radio2
 
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.content.ServiceConnection
-import android.content.SharedPreferences
-import android.os.Bundle
-import android.os.IBinder
-import android.text.Editable
-import android.text.TextWatcher
+import android.content.*
+import android.os.*
 import android.util.Log
 import android.view.KeyEvent
 import android.view.MenuItem
-import android.view.inputmethod.EditorInfo
-
 import android.widget.Button
 import android.widget.TextView
 import androidx.activity.enableEdgeToEdge
 import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.ViewModel
 import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.viewModelScope
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import androidx.room.Entity
-import androidx.room.PrimaryKey
+import com.example.radio2.Data.userDataStorage
 import com.example.radio2.com.example.radio2.AppDatabase
-import com.example.radio2.com.example.radio2.MessageViewModel
+import com.example.radio2.com.example.radio2.ChatRepository
 import com.example.radio2.service.WebSocketService
 import com.google.android.material.textfield.TextInputEditText
-import com.google.common.reflect.TypeToken
 import kotlinx.coroutines.launch
-import kotlinx.serialization.json.Json
-
 
 class ChatActivity : AppCompatActivity() {
-    val activity = this@ChatActivity
     private var webSocketService: WebSocketService? = null
     private lateinit var chatAdapter: ChatAdapter
     private val messages = mutableListOf<MessageTo>()
     private lateinit var recyclerView: RecyclerView
     private lateinit var messageInput: TextInputEditText
     private lateinit var sharedPreferences: SharedPreferences
-    private val messagesKey = "messages_key"
-    private val sentMessagesKey = "sent_messages_key"
-    private val receivedMessagesKey = "received_messages_key"
-
-    private lateinit var messageViewModel: MessageViewModel
+    private lateinit var database: AppDatabase
+    private lateinit var chatRepository: ChatRepository
+    private var chatId: String? = null  // chatId теперь строка
+    private var userId: String? = null  // userId теперь строка
 
     private val connection = object : ServiceConnection {
         override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
             val binder = service as WebSocketService.WebSocketBinder
             webSocketService = binder.getService()
-            webSocketService?.setCurrentActivity(activity)
-            //Log.d("SubscriberGroupActivity", "Current activity: $this@SubscriberGroupActivity")
-
-            webSocketService?.setMessageCallback { message ->
-                runOnUiThread {
-                    //Log.d("SubscriberGroupActivity", "Received message: $message")
-                }
-            }
+            webSocketService?.setCurrentActivity(this@ChatActivity)
         }
 
-
         override fun onServiceDisconnected(name: ComponentName?) {
             webSocketService = null
         }
@@ -73,19 +48,20 @@ class ChatActivity : AppCompatActivity() {
         Intent(this, WebSocketService::class.java).also { intent ->
             bindService(intent, connection, BIND_AUTO_CREATE)
         }
-        val database = AppDatabase.getInstance(this)
-        val dao = database.messageDao()
-
-        messageViewModel = MessageViewModel(dao)
-
-        lifecycleScope.launch {
-            messageViewModel.saveMessage("Тестовое сообщение")
 
-            val allMessages = messageViewModel.getMessages()
-            allMessages.forEach() { message ->
-                Log.d("ChatActivity", "Message: ${message.text}, ID: ${message.id}");
-            }
-        }
+        val database = AppDatabase.getInstance(this)
+        chatRepository = ChatRepository(
+            userDao = database.userDao(),
+            chatDao = database.chatDao(),
+            chatMemberDao = database.chatMemberDao(),
+            messageDao = database.messageDao()
+        )
+
+        // Загрузка истории чата
+        getMessagesForChat()
+
+        // Загружаем данные пользователя и чата
+        loadUserData()
     }
 
     override fun onStop() {
@@ -95,27 +71,18 @@ class ChatActivity : AppCompatActivity() {
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        enableEdgeToEdge()
         supportActionBar?.setDisplayHomeAsUpEnabled(true)
         setContentView(R.layout.activity_chat)
-        recyclerView = findViewById(R.id.recycler_message)
-        messageInput = findViewById<TextInputEditText>(R.id.et_chat)
 
-        val userId = intent.getStringExtra("USER_ID")
-        val userName = intent.getStringExtra("USER_NAME")
-        if (userName != null && userId != null) {
-            loadChat(userId, userName)
-        }
-        val sendMessageButton = findViewById<Button>(R.id.button)
+        recyclerView = findViewById(R.id.recycler_message)
+        messageInput = findViewById(R.id.et_chat)
 
         recyclerView.layoutManager = LinearLayoutManager(this)
         chatAdapter = ChatAdapter(this, messages)
         recyclerView.adapter = chatAdapter
-        val backButton = findViewById<Button>(R.id.backButton)
 
-        sharedPreferences = getSharedPreferences("chat_prefs", Context.MODE_PRIVATE)
-
-        loadMessages()
+        val sendMessageButton = findViewById<Button>(R.id.button)
+        val backButton = findViewById<Button>(R.id.backButton)
 
         backButton.setOnClickListener {
             finish()
@@ -133,25 +100,52 @@ class ChatActivity : AppCompatActivity() {
                 false
             }
         }
+    }
 
-//        messageInput.addTextChangedListener(object : TextWatcher {
-//            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
-//
-//            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
-//
-//                if (s != null && s.endsWith("\n")) {
-//
-//                    messageInput.setText(s.substring(0, s.length - 1))
-//
-//                    sendMessage()
-//                }
-//            }
-//
-//            override fun afterTextChanged(s: Editable?) {
-//
-//            }
-//        })
-//
+    private fun loadUserData() {
+        lifecycleScope.launch {
+            try {
+                // Получаем текущего пользователя
+                val userIdString = userDataStorage.userId  // Получаем userId как строку
+                if (userIdString.isNullOrBlank()) {
+                    Log.e("ChatActivity", "Ошибка: userId не найден или пуст")
+                    return@launch
+                }
+
+                userId = userIdString  // userId теперь строка
+                Log.d("ChatActivity", "Успешно получен userId: $userId")
+
+                // Получаем ID чата
+                chatId = getChatIdForUser(userId!!)
+                if (chatId.isNullOrBlank()) {
+                    Log.e("ChatActivity", "Ошибка: chatId не найден для userId: $userId")
+                    return@launch
+                }
+
+                Log.d("ChatActivity", "Успешно получен chatId: $chatId")
+
+                val userName = getUserName(userId!!)
+                Log.d("ChatActivity", "Получено имя пользователя: $userName")
+
+                loadChat(userId!!, userName)
+                getMessagesForChat()
+
+                // Логирование базы данных
+                logAllUsers()
+                logAllChats()
+
+            } catch (e: Exception) {
+                Log.e("ChatActivity", "Ошибка при загрузке данных: ${e.message}")
+            }
+        }
+    }
+
+    private suspend fun getChatIdForUser(userId: String): String? {
+        return chatRepository.getChatForUser(userId)
+    }
+
+    private suspend fun getUserName(userId: String): String {
+        return chatRepository.getUserName(userId) ?: "Неизвестный пользователь"
     }
 
     private fun loadChat(userId: String, userName: String) {
@@ -162,40 +156,76 @@ class ChatActivity : AppCompatActivity() {
     private fun sendMessage() {
         val text = messageInput.text.toString().trim()
         if (text.isNotEmpty()) {
-            addUserMessage(text)
-            webSocketService?.sendMessage(text, "0", "23", "0", "test", "test", "0")
-            messageInput.hint = "Message"
-            messageInput.text = null
-        } else {
-            messageInput.hint = "Enter Message"
+            val currentUserId = userId
+            val currentChatId = chatId
+
+            if (currentUserId != null && currentChatId != null) {
+                lifecycleScope.launch {
+                    try {
+                        chatRepository.sendMessage(currentChatId, currentUserId, text)
+                        addUserMessage(text)
+                        messageInput.text = null
+                    } catch (e: Exception) {
+                        Log.e("ChatActivity", "Ошибка при отправке сообщения: ${e.message}")
+                    }
+                }
+            } else {
+                Log.e("ChatActivity", "Ошибка: userId или chatId не инициализированы")
+            }
         }
     }
 
-    private fun saveMessages() {
+    private fun getMessagesForChat() {
+        lifecycleScope.launch {
+            val currentUserId = userId
+            val currentChatId = chatId
+
+            if (currentUserId != null && currentChatId != null) {
+                try {
+                    val chatMessages = chatRepository.getMessagesForChat(currentChatId, currentUserId)
+                    messages.clear()
+                    messages.addAll(chatMessages.map { MessageTo(it.text, MessageType.RECEIVED) })
+                    chatAdapter.notifyDataSetChanged()
+                    recyclerView.scrollToPosition(messages.size - 1)
+                } catch (e: Exception) {
+                    Log.e("ChatActivity", "Ошибка при загрузке сообщений: ${e.message}")
+                }
+            } else {
+                Log.e("ChatActivity", "Ошибка: userId или chatId не инициализированы")
+            }
+        }
+    }
 
-        val editor = sharedPreferences.edit()
-        val userId = intent.getStringExtra("USER_ID") ?: return
-        val serializedMessages = messages.joinToString(",") { "${it.type}:${it.text}" }
-        editor.putString("messages_$userId", serializedMessages)
-        editor.apply()
+    private fun addUserMessage(message: String) {
+        messages.add(MessageTo(message, MessageType.SENT))
+        chatAdapter.notifyItemInserted(messages.size - 1)
+        recyclerView.scrollToPosition(messages.size - 1)
     }
 
-    private fun loadMessages() {
-        val userId = intent.getStringExtra("USER_ID") ?: return
-        val savedMessages = sharedPreferences.getString("messages_$userId", "")
-        savedMessages?.let {
-            if (it.isNotEmpty()) {
-                val loadedMessages = it.split(",").map { msg ->
-                    val parts = msg.split(":")
-                    val type = MessageType.valueOf(parts[0])
-                    val text = parts[1]
-                    MessageTo(text, type)
+    private fun logAllUsers() {
+        lifecycleScope.launch {
+            val users = chatRepository.getAllUsers()
+            if (users.isEmpty()) {
+                Log.d("Database", "В базе данных нет пользователей")
+            } else {
+                users.forEach { user ->
+                    Log.d("Database", "User: id=${user.id}, name=${user.username}")
+                }
+            }
+        }
+    }
+
+    private fun logAllChats() {
+        lifecycleScope.launch {
+            val chats = chatRepository.getAllChats()
+            if (chats.isEmpty()) {
+                Log.d("Database", "В базе данных нет чатов")
+            } else {
+                chats.forEach { chat ->
+                    Log.d("Database", "Chat: id=${chat.id}, title=${chat.title}")
                 }
-                messages.clear()
-                messages.addAll(loadedMessages)
             }
         }
-        chatAdapter.setList(messages)
     }
 
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
@@ -208,25 +238,43 @@ class ChatActivity : AppCompatActivity() {
         }
     }
 
-
-    fun addReceived1Message(message: String) {messages.add(MessageTo(message, MessageType.RECEIVED))}
     fun addReceivedMessage(message: String) {
-
-        addReceived1Message(message)
-
-        chatAdapter.notifyItemInserted(messages.size - 1)
-        recyclerView.scrollToPosition(messages.size - 1)
-        saveMessages()
-
+//        addReceived1Message(message)
+//        chatAdapter.notifyItemInserted(messages.size - 1)
+//        recyclerView.scrollToPosition(messages.size - 1)
+//        saveMessages()
     }
-    fun addUser1Message(message: String) {messages.add(MessageTo(message, MessageType.SENT))}
-    fun addUserMessage(message: String) {
 
-        addUser1Message(message)
-
-        chatAdapter.notifyItemInserted(messages.size - 1)
-        recyclerView.scrollToPosition(messages.size - 1)
-        messageInput.setText("")
-        saveMessages()
-    }
-}
+//    fun addUserMessage(message: String) {
+//        addUser1Message(message)
+//        chatAdapter.notifyItemInserted(messages.size - 1)
+//        recyclerView.scrollToPosition(messages.size - 1)
+//        messageInput.setText("")
+//        saveMessages()
+
+//    private fun saveMessages() {
+//        val editor = sharedPreferences.edit()
+//        val userId = intent.getStringExtra("USER_ID") ?: return
+//        val serializedMessages = messages.joinToString(",") { "${it.type}:${it.text}" }
+//        editor.putString("messages_$userId", serializedMessages)
+//        editor.apply()
+//    }
+//
+//    private fun loadMessages() {
+//        val userId = intent.getStringExtra("USER_ID") ?: return
+//        val savedMessages = sharedPreferences.getString("messages_$userId", "")
+//        savedMessages?.let {
+//            if (it.isNotEmpty()) {
+//                val loadedMessages = it.split(",").map { msg ->
+//                    val parts = msg.split(":")
+//                    val type = MessageType.valueOf(parts[0])
+//                    val text = parts[1]
+//                    MessageTo(text, type)
+//                }
+//                messages.clear()
+//                messages.addAll(loadedMessages)
+//            }
+//        }
+//        chatAdapter.setList(messages)
+//    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/radio2/Data/HandlersStorage.kt b/app/src/main/java/com/example/radio2/Data/HandlersStorage.kt
index e650d5e..fd20082 100644
--- a/app/src/main/java/com/example/radio2/Data/HandlersStorage.kt
+++ b/app/src/main/java/com/example/radio2/Data/HandlersStorage.kt
@@ -10,3 +10,7 @@ object AudioConfigStorage {
     var sequenceNumber: Int? = 0
 }
 
+object userDataStorage {
+    var userId: String? = null
+}
+
diff --git a/app/src/main/java/com/example/radio2/DataBase.kt b/app/src/main/java/com/example/radio2/DataBase.kt
index 9a6cebe..15fd918 100644
--- a/app/src/main/java/com/example/radio2/DataBase.kt
+++ b/app/src/main/java/com/example/radio2/DataBase.kt
@@ -11,24 +11,28 @@ import androidx.room.Insert
 import androidx.room.PrimaryKey
 import androidx.room.Query
 import androidx.room.ForeignKey
+import androidx.room.OnConflictStrategy
 import androidx.room.Room
 import androidx.room.RoomDatabase
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
+import java.util.UUID
 
 // Таблица юзера
 @Entity(tableName = "users")
 data class User(
-    @PrimaryKey(autoGenerate = true) val id: Int = 0, //id юзера
+    @PrimaryKey val id: String, // id теперь строка
     val username: String // Название юзера
 )
 
 //Таблица с чатами
 @Entity(tableName = "chats")
 data class Chat(
-    @PrimaryKey(autoGenerate = true) val id: Int = 0, // id чата
-    val title: String? = null // Название чата, ока оставлю
+    @PrimaryKey val id: String, // chatId теперь строка
+    val title: String? = null // Название чата
 )
 
 // Таблица с участниками чата, где главные id чата и id юзера
@@ -41,8 +45,8 @@ data class Chat(
     ]
 )
 data class ChatMember(
-    val chatId: Int, // id чата
-    val userId: Int  // id юзера
+    val chatId: String, // chatId теперь строка
+    val userId: String  // userId теперь строка
 )
 
 @Entity(
@@ -53,12 +57,13 @@ data class ChatMember(
 )
 data class Message(
     @PrimaryKey(autoGenerate = true) val id: Int = 0, // уникальный id сообщения
-    val chatId: Int, // id чата, к которому принадлежит сообщение
-    val senderId: Int, // id юзера, отправившего сообщение
+    val chatId: String, // chatId теперь строка
+    val senderId: String, // senderId теперь строка
     val text: String, // Сам текст
     val timestamp: Long = System.currentTimeMillis() // Метка со временем
 )
 
+
 //Data Access Objects - управление пользователями
 @Dao
 interface UserDao {
@@ -66,10 +71,13 @@ interface UserDao {
     suspend fun insertUser(user: User): Long
 
     @Query("SELECT * FROM users WHERE id = :userId")
-    suspend fun getUserById(userId: Int): User
+    suspend fun getUserById(userId: String): User // userId теперь строка
 
     @Query("SELECT * FROM users")
     suspend fun getAllUsers(): List<User>
+
+    @Query("SELECT username FROM users WHERE id = :userId LIMIT 1")
+    suspend fun getUserNameById(userId: String): String? // userId теперь строка
 }
 
 //Data Access Objects - управление чатами
@@ -95,27 +103,109 @@ interface ChatMemberDao {
         SELECT * FROM chats 
         WHERE id IN (SELECT chatId FROM chat_members WHERE userId = :userId)
     """)
-    suspend fun getChatsForUser(userId: Int): List<Chat>
+    suspend fun getChatsForUser(userId: String): List<Chat> // userId теперь строка
 
     @Query("""
         SELECT * FROM users 
         WHERE id IN (SELECT userId FROM chat_members WHERE chatId = :chatId)
     """)
-    suspend fun getUsersInChat(chatId: Int): List<User>
+    suspend fun getUsersInChat(chatId: String): List<User> // chatId теперь строка
+
+    @Query("SELECT chatId FROM chat_members WHERE userId = :userId LIMIT 1")
+    suspend fun getChatIdByUserId(userId: String): String? // userId теперь строка
 }
 
 //Data Access Objects - управление сообщениями
 @Dao
 interface MessageDao {
-    @Insert
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
     suspend fun insertMessage(message: Message)
 
     @Query("SELECT * FROM messages WHERE chatId = :chatId ORDER BY timestamp ASC")
-    suspend fun getMessagesForChat(chatId: Int): List<Message>
+    suspend fun getMessagesForChat(chatId: String): List<Message> // chatId теперь строка
+}
+
+val MIGRATION_1_2 = object : Migration(1, 2) {
+    override fun migrate(database: SupportSQLiteDatabase) {
+        // Миграция для users
+        database.execSQL("""
+            CREATE TABLE IF NOT EXISTS `users_temp` (
+                `id` TEXT NOT NULL PRIMARY KEY,
+                `username` TEXT NOT NULL
+            )
+        """)
+        database.execSQL("""
+            INSERT INTO `users_temp` (`id`, `username`)
+            SELECT `id`, `username` FROM `users`
+        """)
+        database.execSQL("DROP TABLE `users`")
+        database.execSQL("ALTER TABLE `users_temp` RENAME TO `users`")
+
+        // Миграция для chats
+        database.execSQL("""
+            CREATE TABLE IF NOT EXISTS `chats_temp` (
+                `id` TEXT NOT NULL PRIMARY KEY,
+                `title` TEXT
+            )
+        """)
+        database.execSQL("""
+            INSERT INTO `chats_temp` (`id`, `title`)
+            SELECT `id`, `title` FROM `chats`
+        """)
+        database.execSQL("DROP TABLE `chats`")
+        database.execSQL("ALTER TABLE `chats_temp` RENAME TO `chats`")
+
+        // Миграция для chat_members
+        database.execSQL("""
+            CREATE TABLE IF NOT EXISTS `chat_members_temp` (
+                `chatId` TEXT NOT NULL,
+                `userId` TEXT NOT NULL,
+                PRIMARY KEY(`chatId`, `userId`),
+                FOREIGN KEY(`chatId`) REFERENCES `chats`(`id`) ON DELETE NO ACTION,
+                FOREIGN KEY(`userId`) REFERENCES `users`(`id`) ON DELETE NO ACTION
+            )
+        """)
+
+        // Копируем данные из старой таблицы в новую для chat_members
+        database.execSQL("""
+            INSERT INTO `chat_members_temp` (`chatId`, `userId`)
+            SELECT `chatId`, `userId` FROM `chat_members`
+        """)
+
+        // Удаляем старую таблицу
+        database.execSQL("DROP TABLE `chat_members`")
+
+        // Переименовываем новую таблицу в старое имя
+        database.execSQL("ALTER TABLE `chat_members_temp` RENAME TO `chat_members`")
+
+        // Миграция для messages
+        database.execSQL("""
+            CREATE TABLE IF NOT EXISTS `messages_temp` (
+                `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+                `chatId` TEXT NOT NULL,
+                `senderId` TEXT NOT NULL,
+                `text` TEXT NOT NULL,
+                `timestamp` INTEGER NOT NULL,
+                FOREIGN KEY(`chatId`) REFERENCES `chats`(`id`) ON DELETE NO ACTION
+            )
+        """)
+
+        // Копируем данные из старой таблицы в новую для messages
+        database.execSQL("""
+            INSERT INTO `messages_temp` (`id`, `chatId`, `senderId`, `text`, `timestamp`)
+            SELECT `id`, `chatId`, `senderId`, `text`, `timestamp` FROM `messages`
+        """)
+
+        // Удаляем старую таблицу
+        database.execSQL("DROP TABLE `messages`")
+
+        // Переименовываем новую таблицу в старое имя
+        database.execSQL("ALTER TABLE `messages_temp` RENAME TO `messages`")
+    }
 }
 
 // Сама база данных
-@Database(entities = [User::class, Chat::class, ChatMember::class, Message::class], version = 1)
+@Database(entities = [User::class, Chat::class, ChatMember::class, Message::class], version = 2)
 abstract class AppDatabase : RoomDatabase() {
     abstract fun userDao(): UserDao
     abstract fun chatDao(): ChatDao
@@ -131,7 +221,9 @@ abstract class AppDatabase : RoomDatabase() {
                     context.applicationContext,
                     AppDatabase::class.java,
                     "app_database"
-                ).build()
+                )
+                    .addMigrations(MIGRATION_1_2)  // Применение миграции
+                    .build()
                 INSTANCE = instance
                 instance
             }
@@ -149,15 +241,19 @@ class ChatRepository(
     // 1. Создать нового пользователя
     suspend fun createUser(username: String): Long {
         return withContext(Dispatchers.IO) {
-            userDao.insertUser(User(username = username))
+            val user = User(id = generateRandomId(), username = username)  // Генерация id теперь строка
+            userDao.insertUser(user)
         }
     }
 
-    // Создать новый чат между несколькими пользователями ( На будущее )
-    suspend fun createChat(chatTitle: String?, userIds: List<Int>): Int {
+    // Создать новый чат между несколькими пользователями
+    suspend fun createChat(chatTitle: String?, userIds: List<String>): String { // chatId теперь строка
         return withContext(Dispatchers.IO) {
             // Делаем чат
-            val chatId = chatDao.insertChat(Chat(title = chatTitle)).toInt()
+            val chatId = generateRandomId()  // Генерация chatId теперь строка
+
+            // Добавляем чат в базу
+            chatDao.insertChat(Chat(id = chatId, title = chatTitle))
 
             // Добавляем юзера в чат
             userIds.forEach { userId ->
@@ -168,7 +264,7 @@ class ChatRepository(
     }
 
     // Отправить сообщение в чат
-    suspend fun sendMessage(chatId: Int, senderId: Int, text: String) {
+    suspend fun sendMessage(chatId: String, senderId: String, text: String) { // chatId и senderId теперь строки
         withContext(Dispatchers.IO) {
             // Проверяем, является ли отправитель юзером чата
             val usersInChat = chatMemberDao.getUsersInChat(chatId).map { it.id }
@@ -176,7 +272,7 @@ class ChatRepository(
                 throw IllegalArgumentException("Пользователь с ID $senderId не является участником этого диалога")
             }
 
-            // Добавить
+            // Добавить сообщение
             messageDao.insertMessage(
                 Message(chatId = chatId, senderId = senderId, text = text)
             )
@@ -184,14 +280,14 @@ class ChatRepository(
     }
 
     // Получить список чатов для юзера
-    suspend fun getChatsForUser(userId: Int): List<Chat> {
+    suspend fun getChatsForUser(userId: String): List<Chat> { // userId теперь строка
         return withContext(Dispatchers.IO) {
             chatMemberDao.getChatsForUser(userId)
         }
     }
 
     // Получить сообщения для чата
-    suspend fun getMessagesForChat(chatId: Int, userId: Int): List<Message> {
+    suspend fun getMessagesForChat(chatId: String, userId: String): List<Message> { // chatId и userId теперь строки
         return withContext(Dispatchers.IO) {
             // Проверяем, является ли юзер участником чата
             val usersInChat = chatMemberDao.getUsersInChat(chatId).map { it.id }
@@ -205,7 +301,7 @@ class ChatRepository(
     }
 
     // Если надо добавить участника в уже существующий чат
-    suspend fun addUserToChat(chatId: Int, userId: Int) {
+    suspend fun addUserToChat(chatId: String, userId: String) { // chatId и userId теперь строки
         withContext(Dispatchers.IO) {
             // Проверка, есть ли юзер в этом чате
             val usersInChat = chatMemberDao.getUsersInChat(chatId).map { it.id }
@@ -217,4 +313,25 @@ class ChatRepository(
             chatMemberDao.addMember(ChatMember(chatId = chatId, userId = userId))
         }
     }
+
+    suspend fun getChatForUser(userId: String): String? { // userId теперь строка
+        return chatMemberDao.getChatIdByUserId(userId)
+    }
+
+    suspend fun getUserName(userId: String): String? { // userId теперь строка
+        return userDao.getUserNameById(userId)
+    }
+
+    suspend fun getAllUsers(): List<User> {
+        return userDao.getAllUsers()
+    }
+
+    suspend fun getAllChats(): List<Chat> {
+        return chatDao.getAllChats()
+    }
+
+    // Функция для генерации случайного строкового ID
+    fun generateRandomId(): String {
+        return UUID.randomUUID().toString()
+    }
 }
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index cb9532c..c3f4f9f 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -63,6 +63,6 @@ androidx-datastore-core-android = { group = "androidx.datastore", name = "datast
 
 [plugins]
 android-application = { id = "com.android.application", version.ref = "agp" }
-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version = "1.9.24" }
 kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinx-serialization" }
 kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
-- 
GitLab


From dc0dd3094707fa02971597f03f692574d2472e91 Mon Sep 17 00:00:00 2001
From: Oleg Iakovlev <olegikovlev.pg@gmail.com>
Date: Fri, 28 Feb 2025 15:49:49 +0300
Subject: [PATCH 2/2] Update DataBase with new func and more

---
 app/src/main/java/com/example/radio2/ChatActivity.kt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/java/com/example/radio2/ChatActivity.kt b/app/src/main/java/com/example/radio2/ChatActivity.kt
index a25e78d..cb511c5 100644
--- a/app/src/main/java/com/example/radio2/ChatActivity.kt
+++ b/app/src/main/java/com/example/radio2/ChatActivity.kt
@@ -277,4 +277,4 @@ class ChatActivity : AppCompatActivity() {
 //        }
 //        chatAdapter.setList(messages)
 //    }
-}
\ No newline at end of file
+}
-- 
GitLab