feat: mobile-like window size and always-visible stats

- Changed window size to mobile phone format (400x800)
- Removed width condition for ActiveProxyFooter - now always visible
- Added run-umbrix.sh launch script with icon copying
- Stats cards now display on all screen sizes
This commit is contained in:
Umbrix Developer
2026-01-17 13:09:20 +03:00
parent ec5ebbd54b
commit 76a374950f
245 changed files with 7931 additions and 1315 deletions

View File

@@ -26,7 +26,7 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin,
enum class Trigger(val method: String) {
Setup("setup"),
ParseConfig("parse_config"),
changeHiddifyOptions("change_hiddify_options"),
changeOptions("change_options"),
GenerateConfig("generate_config"),
Start("start"),
Stop("stop"),
@@ -86,7 +86,7 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin,
}
}
Trigger.changeHiddifyOptions.method -> {
Trigger.changeOptions.method -> {
scope.launch {
result.runCatching {
val args = call.arguments as String

View File

@@ -1,19 +1,29 @@
package com.umbrix.app.widget
import android.content.Context
import android.util.Log
import android.widget.RemoteViews
import com.umbrix.app.R
class ConnectionWidget1x1 : ConnectionWidgetProvider() {
companion object {
private const val TAG = "A/ConnectionWidget1x1"
}
override fun getLayout(): Int = R.layout.widget_connection_1x1
override fun updateWidgetUI(context: Context, views: RemoteViews, isConnected: Boolean) {
if (isConnected) {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_pause_circle_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_active)
} else {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_power_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_inactive)
Log.d(TAG, "updateWidgetUI: isConnected=$isConnected")
try {
if (isConnected) {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_pause_circle_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_active)
} else {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_power_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_inactive)
}
} catch (e: Exception) {
Log.e(TAG, "updateWidgetUI error", e)
}
}
}

View File

@@ -2,26 +2,36 @@ package com.umbrix.app.widget
import android.content.Context
import android.graphics.Color
import android.util.Log
import android.widget.RemoteViews
import com.umbrix.app.R
class ConnectionWidget2x2 : ConnectionWidgetProvider() {
companion object {
private const val TAG = "A/ConnectionWidget2x2"
}
override fun getLayout(): Int = R.layout.widget_connection_2x2
override fun updateWidgetUI(context: Context, views: RemoteViews, isConnected: Boolean) {
if (isConnected) {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_pause_circle_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_active)
} else {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_power_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_inactive)
Log.d(TAG, "updateWidgetUI: isConnected=$isConnected")
try {
if (isConnected) {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_pause_circle_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_active)
} else {
views.setImageViewResource(R.id.widget_icon, R.drawable.ic_power_24)
views.setInt(R.id.widget_background, "setBackgroundResource", R.drawable.widget_bg_inactive)
}
// Обновляем текст статуса
val statusText = if (isConnected) "Connected" else "Tap to Connect"
val statusColor = if (isConnected) Color.parseColor("#00BFA5") else Color.parseColor("#9E9E9E")
views.setTextViewText(R.id.widget_status, statusText)
views.setTextColor(R.id.widget_status, statusColor)
} catch (e: Exception) {
Log.e(TAG, "updateWidgetUI error", e)
}
// Обновляем текст статуса
val statusText = if (isConnected) "Connected" else "Tap to Connect"
val statusColor = if (isConnected) Color.parseColor("#00BFA5") else Color.parseColor("#9E9E9E")
views.setTextViewText(R.id.widget_status, statusText)
views.setTextColor(R.id.widget_status, statusColor)
}
}

View File

@@ -6,6 +6,7 @@ import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.RemoteViews
import com.umbrix.app.R
import com.umbrix.app.bg.BoxService
@@ -13,9 +14,11 @@ import com.umbrix.app.bg.BoxService
abstract class ConnectionWidgetProvider : AppWidgetProvider() {
companion object {
private const val TAG = "A/ConnectionWidget"
private const val ACTION_TOGGLE = "com.umbrix.app.widget.TOGGLE"
fun updateAllWidgets(context: Context, isConnected: Boolean) {
Log.d(TAG, "updateAllWidgets: isConnected=$isConnected")
// Обновляем все виджеты 1x1
updateWidgets(context, ConnectionWidget1x1::class.java, isConnected)
// Обновляем все виджеты 2x2
@@ -23,13 +26,19 @@ abstract class ConnectionWidgetProvider : AppWidgetProvider() {
}
private fun updateWidgets(context: Context, widgetClass: Class<out ConnectionWidgetProvider>, isConnected: Boolean) {
val appWidgetManager = AppWidgetManager.getInstance(context)
val componentName = ComponentName(context, widgetClass)
val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
appWidgetIds.forEach { appWidgetId ->
val instance = widgetClass.getDeclaredConstructor().newInstance()
instance.updateAppWidget(context, appWidgetManager, appWidgetId, isConnected)
try {
val appWidgetManager = AppWidgetManager.getInstance(context)
val componentName = ComponentName(context, widgetClass)
val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)
Log.d(TAG, "updateWidgets: ${widgetClass.simpleName}, count=${appWidgetIds.size}")
appWidgetIds.forEach { appWidgetId ->
val instance = widgetClass.getDeclaredConstructor().newInstance()
instance.updateAppWidget(context, appWidgetManager, appWidgetId, isConnected)
}
} catch (e: Exception) {
Log.e(TAG, "updateWidgets error: ${widgetClass.simpleName}", e)
}
}
}
@@ -75,6 +84,7 @@ abstract class ConnectionWidgetProvider : AppWidgetProvider() {
appWidgetIds: IntArray
) {
val isConnected = com.umbrix.app.bg.BoxService.isConnected()
Log.d(TAG, "onUpdate: widgetIds=${appWidgetIds.joinToString()}, isConnected=$isConnected")
appWidgetIds.forEach { appWidgetId ->
updateAppWidget(context, appWidgetManager, appWidgetId, isConnected)
}
@@ -83,16 +93,25 @@ abstract class ConnectionWidgetProvider : AppWidgetProvider() {
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
Log.d(TAG, "onReceive: action=${intent.action}")
when (intent.action) {
ACTION_TOGGLE -> {
if (BoxService.isConnected()) {
BoxService.stop()
} else {
BoxService.start()
try {
val wasConnected = BoxService.isConnected()
Log.d(TAG, "TOGGLE: wasConnected=$wasConnected")
if (wasConnected) {
BoxService.stop()
} else {
BoxService.start()
}
} catch (e: Exception) {
Log.e(TAG, "TOGGLE error", e)
}
}
"com.umbrix.app.SERVICE_STATE_CHANGED" -> {
val isConnected = intent.getBooleanExtra("isConnected", false)
Log.d(TAG, "SERVICE_STATE_CHANGED: isConnected=$isConnected")
updateAllWidgets(context, isConnected)
}
}