package com.schoolmesh.messenger import android.Manifest import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.net.Uri import android.os.Build import android.os.Bundle import android.widget.ArrayAdapter import android.widget.Button import android.widget.EditText import android.widget.ListView import android.widget.TextView import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.google.android.material.switchmaterial.SwitchMaterial import com.schoolmesh.messenger.data.ChatSummary import com.schoolmesh.messenger.data.MeshDatabase import com.schoolmesh.messenger.data.MeshRepository import com.schoolmesh.messenger.mesh.MeshForegroundService import com.schoolmesh.messenger.mesh.MeshServiceContract import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.json.JSONObject import java.net.HttpURLConnection import java.net.URL import java.text.SimpleDateFormat import java.util.ArrayDeque import java.util.Date import java.util.Locale class MainActivity : AppCompatActivity() { private lateinit var repository: MeshRepository private lateinit var statusText: TextView private lateinit var peersText: TextView private lateinit var logsText: TextView private lateinit var activeChatTitle: TextView private lateinit var targetInput: EditText private lateinit var messageInput: EditText private lateinit var chatListView: ListView private lateinit var messageListView: ListView private lateinit var chatsScreen: android.view.View private lateinit var settingsScreen: android.view.View private lateinit var autoUpdateSwitch: SwitchMaterial private val peers = linkedSetOf() private val logs = ArrayDeque() private val chatSummaries = mutableListOf() private val chatItems = mutableListOf() private val messageItems = mutableListOf() private lateinit var chatAdapter: ArrayAdapter private lateinit var messageAdapter: ArrayAdapter private var activePeerId: String? = null private var pendingSend: PendingSend? = null private var pendingStartRequested = false private val prefs by lazy { getSharedPreferences("nnnet_settings", Context.MODE_PRIVATE) } private val meshEventReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action != MeshServiceContract.ACTION_EVENT) return val eventType = intent.getStringExtra(MeshServiceContract.EXTRA_EVENT_TYPE) ?: return val value = intent.getStringExtra(MeshServiceContract.EXTRA_EVENT_VALUE) ?: return when (eventType) { MeshServiceContract.EVENT_STATUS -> updateStatus(value) MeshServiceContract.EVENT_PEER -> addPeer(value) MeshServiceContract.EVENT_LOG -> appendLog(value) MeshServiceContract.EVENT_MESSAGES_CHANGED -> { refreshChats() refreshMessages() } } } } private val permissionLauncher = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { result -> val allGranted = result.values.all { it } if (allGranted) { ensureBluetoothEnabledAndContinue() } else { updateStatus("Нет BLE-разрешений") appendLog("Permissions denied by user") Toast.makeText(this, "Permissions denied", Toast.LENGTH_SHORT).show() } } private val enableBluetoothLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { if (bluetoothAdapter()?.isEnabled == true) { continueAfterBluetoothReady() } else { updateStatus("Bluetooth is disabled") appendLog("Bluetooth enable request denied") Toast.makeText(this, "Bluetooth is required", Toast.LENGTH_SHORT).show() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val database = MeshDatabase.getInstance(applicationContext) repository = MeshRepository(database.messageDao(), database.outboundQueueDao()) statusText = findViewById(R.id.statusText) peersText = findViewById(R.id.peersText) logsText = findViewById(R.id.logsText) activeChatTitle = findViewById(R.id.activeChatTitle) targetInput = findViewById(R.id.targetInput) messageInput = findViewById(R.id.messageInput) chatListView = findViewById(R.id.chatListView) messageListView = findViewById(R.id.messageListView) chatsScreen = findViewById(R.id.chatsScreen) settingsScreen = findViewById(R.id.settingsScreen) autoUpdateSwitch = findViewById(R.id.autoUpdateSwitch) chatAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, chatItems) messageAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, messageItems) chatListView.adapter = chatAdapter messageListView.adapter = messageAdapter findViewById