Compare commits
10 Commits
415e6f8849
...
e79b508531
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e79b508531 | ||
|
|
8c5696b6aa | ||
|
|
abb6929e19 | ||
|
|
ee39acbeec | ||
|
|
af21f6d16e | ||
|
|
d8cdee91fe | ||
|
|
b0e23312d8 | ||
|
|
43ab81e8d1 | ||
|
|
9300488d2b | ||
|
|
053d7e5855 |
335
UPDATE_SERVER_README.md
Normal file
335
UPDATE_SERVER_README.md
Normal file
@@ -0,0 +1,335 @@
|
||||
# 🚀 Umbrix Update Server - Инструкция
|
||||
|
||||
## 📋 Обзор
|
||||
|
||||
Umbrix использует систему автообновлений через **Sparkle Appcast XML**. Приложение проверяет файл `appcast.xml` на вашем сервере и уведомляет пользователей о новых версиях.
|
||||
|
||||
## 🏗️ Структура системы обновлений
|
||||
|
||||
### 1. **appcast.xml** - Манифест обновлений
|
||||
Находится: `/home/vodorod/dorod/hiddify-umbrix-v1.7.0/appcast.xml`
|
||||
|
||||
```xml
|
||||
<item>
|
||||
<title>Umbrix 2.5.8</title>
|
||||
<description>🚀 Новые функции...</description>
|
||||
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
|
||||
<sparkle:version>2.5.8</sparkle:version>
|
||||
|
||||
<!-- Linux DEB -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-deb"
|
||||
type="application/x-debian-package" />
|
||||
</item>
|
||||
```
|
||||
|
||||
### 2. **Настройки в коде**
|
||||
Файл: `lib/core/model/constants.dart`
|
||||
|
||||
```dart
|
||||
// URL вашего сервера appcast.xml
|
||||
static const appCastUrl = "http://localhost:8000/api/appcast.xml";
|
||||
|
||||
// Для публичного домена:
|
||||
// static const appCastUrl = "https://updates.umbrix.net/appcast.xml";
|
||||
```
|
||||
|
||||
## 📂 Структура веб-сервера
|
||||
|
||||
```
|
||||
/home/vodorod/update-server/
|
||||
├── api/
|
||||
│ └── appcast.xml # Копия из проекта
|
||||
├── downloads/ # Файлы обновлений
|
||||
│ ├── umbrix-2.5.8-linux.deb
|
||||
│ ├── umbrix-2.5.8-linux.rpm
|
||||
│ ├── umbrix-2.5.8-linux.AppImage
|
||||
│ └── umbrix-2.5.8-windows.exe
|
||||
└── admin/ # Ваш Update Manager (localhost:8000/admin/)
|
||||
└── index.html
|
||||
```
|
||||
|
||||
## 🔄 Процесс публикации обновления
|
||||
|
||||
### Шаг 1: Собрать новую версию
|
||||
```bash
|
||||
cd ~/dorod/hiddify-umbrix-v1.7.0
|
||||
./build-all-packages.sh
|
||||
```
|
||||
|
||||
### Шаг 2: Скопировать файлы на сервер
|
||||
```bash
|
||||
# Создать папку для версии
|
||||
mkdir -p /home/vodorod/update-server/downloads/
|
||||
|
||||
# Скопировать пакеты
|
||||
cp dist/2.5.8+258/umbrix-2.5.8+258-linux.deb \
|
||||
/home/vodorod/update-server/downloads/umbrix-2.5.8-linux.deb
|
||||
|
||||
cp dist/2.5.8+258/umbrix-2.5.8+258-linux.rpm \
|
||||
/home/vodorod/update-server/downloads/umbrix-2.5.8-linux.rpm
|
||||
|
||||
cp dist/2.5.8+258/umbrix-2.5.8+258-linux.AppImage \
|
||||
/home/vodorod/update-server/downloads/umbrix-2.5.8-linux.AppImage
|
||||
```
|
||||
|
||||
### Шаг 3: Обновить appcast.xml
|
||||
|
||||
Раскомментируйте и измените секцию в `appcast.xml`:
|
||||
|
||||
```xml
|
||||
<item>
|
||||
<title>Umbrix 2.5.8</title>
|
||||
<description>🚀 Новые функции:
|
||||
- Улучшена стабильность
|
||||
- Исправлены ошибки</description>
|
||||
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
|
||||
<sparkle:version>2.5.8</sparkle:version>
|
||||
<sparkle:shortVersionString>2.5.8</sparkle:shortVersionString>
|
||||
<sparkle:minimumSystemVersion>2.0.0</sparkle:minimumSystemVersion>
|
||||
|
||||
<!-- Linux DEB (Debian/Ubuntu) -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-deb"
|
||||
type="application/x-debian-package"
|
||||
length="30000000" />
|
||||
|
||||
<!-- Linux RPM (Fedora/CentOS) -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.rpm"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-rpm"
|
||||
type="application/x-rpm"
|
||||
length="36000000" />
|
||||
|
||||
<!-- Linux AppImage (Universal) -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.AppImage"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-appimage"
|
||||
type="application/x-appimage"
|
||||
length="38000000" />
|
||||
</item>
|
||||
```
|
||||
|
||||
### Шаг 4: Скопировать appcast.xml на сервер
|
||||
```bash
|
||||
cp appcast.xml /home/vodorod/update-server/api/appcast.xml
|
||||
```
|
||||
|
||||
## 🌐 Запуск локального сервера
|
||||
|
||||
### Вариант 1: Python HTTP сервер (простой)
|
||||
```bash
|
||||
cd /home/vodorod/update-server
|
||||
python3 -m http.server 8000
|
||||
```
|
||||
|
||||
Доступ:
|
||||
- Appcast: `http://localhost:8000/api/appcast.xml`
|
||||
- Скачивания: `http://localhost:8000/downloads/`
|
||||
- Admin: `http://localhost:8000/admin/`
|
||||
|
||||
### Вариант 2: Nginx (продакшн)
|
||||
```nginx
|
||||
server {
|
||||
listen 8000;
|
||||
server_name localhost;
|
||||
root /home/vodorod/update-server;
|
||||
|
||||
location /api/appcast.xml {
|
||||
add_header Content-Type application/xml;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
|
||||
location /downloads/ {
|
||||
autoindex on;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 Про поле "URL для скачивания APK" в веб-интерфейсе
|
||||
|
||||
**ВАЖНО**: Это поле осталось от оригинального Hiddify (Android приложение). Для **Umbrix Linux десктоп** оно **НЕ используется**.
|
||||
|
||||
Umbrix для Linux использует:
|
||||
- ✅ **DEB пакеты** (Debian/Ubuntu)
|
||||
- ✅ **RPM пакеты** (Fedora/CentOS)
|
||||
- ✅ **AppImage** (универсальный формат)
|
||||
|
||||
Поле "APK" в веб-интерфейсе можно:
|
||||
1. **Игнорировать** (оставить пустым)
|
||||
2. **Переименовать** в "URL для скачивания DEB/RPM/AppImage"
|
||||
3. **Удалить** из веб-интерфейса
|
||||
|
||||
## 🔐 Безопасность
|
||||
|
||||
### Для продакшн (публичный домен):
|
||||
|
||||
1. **HTTPS обязателен**:
|
||||
```dart
|
||||
static const appCastUrl = "https://updates.umbrix.net/appcast.xml";
|
||||
```
|
||||
|
||||
2. **Подписывание обновлений** (Sparkle поддерживает):
|
||||
```bash
|
||||
# Генерация ключей
|
||||
openssl genrsa -out private_key.pem 2048
|
||||
openssl rsa -in private_key.pem -pubout > public_key.pem
|
||||
|
||||
# Подпись файла
|
||||
openssl dgst -sha256 -sign private_key.pem \
|
||||
umbrix-2.5.8-linux.deb > signature.txt
|
||||
```
|
||||
|
||||
3. **Добавить signature в appcast.xml**:
|
||||
```xml
|
||||
<enclosure
|
||||
url="https://updates.umbrix.net/downloads/umbrix-2.5.8-linux.deb"
|
||||
sparkle:dsaSignature="MC0CFQCqfTq..." />
|
||||
```
|
||||
|
||||
## 🧪 Тестирование
|
||||
|
||||
### 1. Проверить доступность appcast.xml
|
||||
```bash
|
||||
curl http://localhost:8000/api/appcast.xml
|
||||
```
|
||||
|
||||
### 2. Проверить в приложении
|
||||
- Запустить Umbrix
|
||||
- Зайти в Настройки → Проверить обновления
|
||||
- Приложение скачает appcast.xml и покажет уведомление о новой версии
|
||||
|
||||
### 3. Логи отладки
|
||||
В коде установлен `_debugUpgrader = true`, логи будут в консоли:
|
||||
```
|
||||
[UPGRADER] Checking appcast: http://localhost:8000/api/appcast.xml
|
||||
[UPGRADER] Current version: 1.7.0
|
||||
[UPGRADER] Latest version: 2.5.8
|
||||
[UPGRADER] Update available!
|
||||
```
|
||||
|
||||
## 📊 Мониторинг скачиваний
|
||||
|
||||
### Вариант 1: Nginx access.log
|
||||
```bash
|
||||
tail -f /var/log/nginx/access.log | grep "/downloads/"
|
||||
```
|
||||
|
||||
### Вариант 2: Python скрипт с логированием
|
||||
```python
|
||||
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||
import datetime
|
||||
|
||||
class LoggingHandler(SimpleHTTPRequestHandler):
|
||||
def log_message(self, format, *args):
|
||||
print(f"[{datetime.datetime.now()}] {args[0]}")
|
||||
|
||||
HTTPServer(('', 8000), LoggingHandler).serve_forever()
|
||||
```
|
||||
|
||||
## 🚀 Миграция на публичный домен
|
||||
|
||||
Когда будете готовы к продакшну:
|
||||
|
||||
1. **Купить домен**: `updates.umbrix.net`
|
||||
|
||||
2. **Настроить DNS**:
|
||||
```
|
||||
A updates.umbrix.net → 123.45.67.89
|
||||
```
|
||||
|
||||
3. **Изменить в коде**:
|
||||
```dart
|
||||
static const appCastUrl = "https://updates.umbrix.net/appcast.xml";
|
||||
```
|
||||
|
||||
4. **Пересобрать и выпустить обновление**:
|
||||
```bash
|
||||
./build-all-packages.sh
|
||||
```
|
||||
|
||||
5. **Все последующие версии** будут проверять новый домен
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
### Q: Как часто приложение проверяет обновления?
|
||||
A: Раз в 12 часов (настройка `durationUntilAlertAgain`)
|
||||
|
||||
### Q: Можно ли принудительно проверить обновления?
|
||||
A: Да, через меню "Настройки → Проверить обновления"
|
||||
|
||||
### Q: Что делать, если обновление не находится?
|
||||
A: Проверьте:
|
||||
1. Доступен ли `appcast.xml` по URL
|
||||
2. Версия в `<sparkle:version>` больше текущей
|
||||
3. Логи отладки в консоли приложения
|
||||
|
||||
### Q: Как откатить обновление?
|
||||
A: Удалите или закомментируйте `<item>` новой версии в `appcast.xml`
|
||||
|
||||
## 📝 Пример полного appcast.xml
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
|
||||
<channel>
|
||||
<title>Umbrix Updates</title>
|
||||
<description>Umbrix VPN автообновления</description>
|
||||
<link>http://localhost:8000</link>
|
||||
<language>ru</language>
|
||||
|
||||
<!-- Новая версия 2.5.8 -->
|
||||
<item>
|
||||
<title>Umbrix 2.5.8</title>
|
||||
<description>🚀 Новые функции:
|
||||
- Улучшена стабильность
|
||||
- Исправлены ошибки
|
||||
- Добавлена поддержка новых протоколов</description>
|
||||
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
|
||||
<sparkle:version>2.5.8</sparkle:version>
|
||||
<sparkle:shortVersionString>2.5.8</sparkle:shortVersionString>
|
||||
<sparkle:minimumSystemVersion>2.0.0</sparkle:minimumSystemVersion>
|
||||
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-deb"
|
||||
type="application/x-debian-package"
|
||||
length="30000000" />
|
||||
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.rpm"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-rpm"
|
||||
type="application/x-rpm"
|
||||
length="36000000" />
|
||||
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.AppImage"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-appimage"
|
||||
type="application/x-appimage"
|
||||
length="38000000" />
|
||||
</item>
|
||||
|
||||
<!-- Текущая версия 1.7.0 -->
|
||||
<item>
|
||||
<title>Umbrix 1.7.0</title>
|
||||
<description>Стабильный релиз</description>
|
||||
<pubDate>Fri, 17 Jan 2026 08:49:07 +0000</pubDate>
|
||||
<sparkle:version>1.7.0</sparkle:version>
|
||||
<sparkle:shortVersionString>1.7.0</sparkle:shortVersionString>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
```
|
||||
|
||||
## 🎯 Готово!
|
||||
|
||||
Теперь система обновлений полностью настроена и готова к использованию!
|
||||
60
appcast.xml
60
appcast.xml
@@ -2,6 +2,64 @@
|
||||
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
|
||||
<channel>
|
||||
<title>Umbrix Updates</title>
|
||||
<!-- No updates available - this is Umbrix, not Hiddify -->
|
||||
<description>Umbrix VPN автообновления</description>
|
||||
<link>http://localhost:8000</link>
|
||||
<language>ru</language>
|
||||
|
||||
<!-- Пример структуры для обновления версии 2.5.8 -->
|
||||
<!-- Раскомментируйте и измените, когда будет новая версия -->
|
||||
<!--
|
||||
<item>
|
||||
<title>Umbrix 2.5.8</title>
|
||||
<description>🚀 Новые функции:
|
||||
- Улучшена стабильность
|
||||
- Исправлены ошибки</description>
|
||||
<pubDate>Sat, 18 Jan 2026 06:00:00 +0000</pubDate>
|
||||
<sparkle:version>2.5.8</sparkle:version>
|
||||
<sparkle:shortVersionString>2.5.8</sparkle:shortVersionString>
|
||||
<sparkle:minimumSystemVersion>2.0.0</sparkle:minimumSystemVersion>
|
||||
|
||||
<!-- Linux DEB (Debian/Ubuntu) -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.deb"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-deb"
|
||||
type="application/x-debian-package"
|
||||
length="30000000" />
|
||||
|
||||
<!-- Linux RPM (Fedora/CentOS) -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.rpm"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-rpm"
|
||||
type="application/x-rpm"
|
||||
length="36000000" />
|
||||
|
||||
<!-- Linux AppImage (Universal) -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-linux.AppImage"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="linux-appimage"
|
||||
type="application/x-appimage"
|
||||
length="38000000" />
|
||||
|
||||
<!-- Windows EXE -->
|
||||
<enclosure
|
||||
url="http://localhost:8000/downloads/umbrix-2.5.8-windows.exe"
|
||||
sparkle:version="2.5.8"
|
||||
sparkle:os="windows"
|
||||
type="application/x-msdownload"
|
||||
length="45000000" />
|
||||
</item>
|
||||
-->
|
||||
|
||||
<!-- Текущая версия 1.7.0 (без обновлений) -->
|
||||
<item>
|
||||
<title>Umbrix 1.7.0</title>
|
||||
<description>Стабильный релиз</description>
|
||||
<pubDate>Fri, 17 Jan 2026 08:49:07 +0000</pubDate>
|
||||
<sparkle:version>1.7.0</sparkle:version>
|
||||
<sparkle:shortVersionString>1.7.0</sparkle:shortVersionString>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
|
||||
@@ -61,6 +61,7 @@ echo -e "${GREEN}✓${NC} Custom libcore integrated: $NEW_SIZE"
|
||||
# Step 5: Add icon and prepare data directory
|
||||
echo -e "\n${YELLOW}[5/6]${NC} Preparing bundle assets..."
|
||||
cp -f "$PROJECT_DIR/logo/ic_launcher_playstore.png" "$BUNDLE_DIR/umbrix.png"
|
||||
chmod 644 "$BUNDLE_DIR/umbrix.png"
|
||||
mkdir -p "$BUNDLE_DIR/data"
|
||||
echo -e "${GREEN}✓${NC} Icon and data directory ready"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ abstract class Constants {
|
||||
static const githubUrl = "https://github.com/umbrix-app/umbrix";
|
||||
static const githubReleasesApiUrl = "https://api.github.com/repos/umbrix-app/umbrix/releases";
|
||||
static const githubLatestReleaseUrl = "https://github.com/umbrix-app/umbrix/releases/latest";
|
||||
static const appCastUrl = "https://raw.githubusercontent.com/umbrix-app/umbrix/main/appcast.xml";
|
||||
static const appCastUrl = "http://localhost:8000/api/appcast.xml";
|
||||
static const telegramChannelUrl = "https://t.me/umbrix_app";
|
||||
static const privacyPolicyUrl = "https://umbrix.net/privacy.html";
|
||||
static const termsAndConditionsUrl = "https://umbrix.net/terms.html";
|
||||
@@ -15,9 +15,10 @@ abstract class Constants {
|
||||
// Собственный сервер обновлений (для приватного репозитория)
|
||||
// 📝 ИНСТРУКЦИЯ: Замените на URL вашего API сервера
|
||||
// Пример: "https://api.umbrix.net/api/latest"
|
||||
// 🧪 Для тестирования в эмуляторе используйте: "http://10.0.2.2:8000/api.php"
|
||||
// 🖥️ Для Linux десктопа используйте: "http://localhost:8000/api/appcast.xml"
|
||||
// 📱 Для Android эмулятора используйте: "http://10.0.2.2:8000/api/appcast.xml"
|
||||
// См. документацию в папке: update-server/README.md
|
||||
static const customUpdateServerUrl = "http://10.0.2.2:8000/api.php";
|
||||
static const customUpdateServerUrl = "http://localhost:8000/api/appcast.xml";
|
||||
|
||||
// Использовать собственный сервер обновлений вместо GitHub
|
||||
// true = использовать customUpdateServerUrl (для приватного репозитория)
|
||||
|
||||
@@ -50,26 +50,26 @@ GoRouter router(RouterRef ref) {
|
||||
}
|
||||
|
||||
final tabLocations = [
|
||||
const HomeRoute().location, // 0: Главная
|
||||
const ProxiesRoute().location, // 1: Локации
|
||||
const PerAppProxyRoute().location, // 2: Исключения
|
||||
const SettingsRoute().location, // 3: Настройки
|
||||
const AboutRoute().location, // 4: О программе
|
||||
const HomeRoute().location, // 0: Главная
|
||||
const ProxiesRoute().location, // 1: Локации
|
||||
const PerAppProxyRoute().location, // 2: Исключения
|
||||
const SettingsRoute().location, // 3: Настройки
|
||||
const AboutRoute().location, // 4: О программе
|
||||
];
|
||||
|
||||
int getCurrentIndex(BuildContext context) {
|
||||
final String location = GoRouterState.of(context).uri.path;
|
||||
|
||||
|
||||
// Проверяем точное совпадение для главной
|
||||
if (location == const HomeRoute().location) return 0;
|
||||
|
||||
|
||||
// Проверяем остальные маршруты по порядку
|
||||
// ВАЖНО: более длинные пути проверяем раньше!
|
||||
if (location.startsWith(const PerAppProxyRoute().location)) return 2; // /settings/per-app-proxy
|
||||
if (location.startsWith(const ProxiesRoute().location)) return 1; // /proxies
|
||||
if (location.startsWith(const SettingsRoute().location)) return 3; // /settings
|
||||
if (location.startsWith(const AboutRoute().location)) return 4; // /about
|
||||
|
||||
if (location.startsWith(const ProxiesRoute().location)) return 1; // /proxies
|
||||
if (location.startsWith(const SettingsRoute().location)) return 3; // /settings
|
||||
if (location.startsWith(const AboutRoute().location)) return 4; // /about
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:umbrix/core/app_info/app_info_provider.dart';
|
||||
import 'package:umbrix/core/localization/locale_preferences.dart';
|
||||
import 'package:umbrix/core/model/constants.dart';
|
||||
import 'package:umbrix/core/preferences/preferences_provider.dart';
|
||||
import 'package:umbrix/core/utils/preferences_utils.dart';
|
||||
import 'package:umbrix/features/app_update/data/app_update_data_providers.dart';
|
||||
@@ -18,7 +19,7 @@ const _debugUpgrader = true;
|
||||
|
||||
@riverpod
|
||||
Upgrader upgrader(UpgraderRef ref) => Upgrader(
|
||||
// Removed appcastConfig - no updates for Umbrix
|
||||
appcastConfig: AppcastConfiguration(url: Constants.appCastUrl),
|
||||
debugLogging: _debugUpgrader && kDebugMode,
|
||||
durationUntilAlertAgain: const Duration(hours: 12),
|
||||
messages: UpgraderMessages(
|
||||
|
||||
@@ -172,49 +172,49 @@ class _CustomAdaptiveScaffold extends HookConsumerWidget {
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
children: [
|
||||
// О программе
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final t = ref.watch(translationsProvider);
|
||||
return _DrawerMenuItem(
|
||||
icon: FluentIcons.info_24_regular,
|
||||
selectedIcon: FluentIcons.info_24_filled,
|
||||
label: t.about.pageTitle,
|
||||
isSelected: false,
|
||||
onTap: () {
|
||||
RootScaffold.stateKey.currentState?.closeDrawer();
|
||||
const AboutRoute().push(context);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
// Настройки
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final t = ref.watch(translationsProvider);
|
||||
return _DrawerMenuItem(
|
||||
icon: FluentIcons.settings_24_regular,
|
||||
selectedIcon: FluentIcons.settings_24_filled,
|
||||
label: t.settings.pageTitle,
|
||||
isSelected: false,
|
||||
onTap: () {
|
||||
RootScaffold.stateKey.currentState?.closeDrawer();
|
||||
const SettingsRoute().push(context);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(),
|
||||
const _DrawerThemeItem(),
|
||||
const _DrawerLanguageItem(),
|
||||
const _DrawerLicensesItem(),
|
||||
],
|
||||
),
|
||||
// О программе
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final t = ref.watch(translationsProvider);
|
||||
return _DrawerMenuItem(
|
||||
icon: FluentIcons.info_24_regular,
|
||||
selectedIcon: FluentIcons.info_24_filled,
|
||||
label: t.about.pageTitle,
|
||||
isSelected: false,
|
||||
onTap: () {
|
||||
RootScaffold.stateKey.currentState?.closeDrawer();
|
||||
const AboutRoute().push(context);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
// Настройки
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final t = ref.watch(translationsProvider);
|
||||
return _DrawerMenuItem(
|
||||
icon: FluentIcons.settings_24_regular,
|
||||
selectedIcon: FluentIcons.settings_24_filled,
|
||||
label: t.settings.pageTitle,
|
||||
isSelected: false,
|
||||
onTap: () {
|
||||
RootScaffold.stateKey.currentState?.closeDrawer();
|
||||
const SettingsRoute().push(context);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(),
|
||||
const _DrawerThemeItem(),
|
||||
const _DrawerLanguageItem(),
|
||||
const _DrawerLicensesItem(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: AdaptiveLayout(
|
||||
primaryNavigation: SlotLayout(
|
||||
config: <Breakpoint, SlotLayoutConfig>{
|
||||
|
||||
@@ -67,16 +67,16 @@ class PerAppProxyPage extends HookConsumerWidget with PresLogger {
|
||||
tooltip: localizations.searchFieldLabel,
|
||||
),
|
||||
],
|
||||
bottom: PlatformUtils.isDesktop
|
||||
? null // На Desktop только вкладка "Домены"
|
||||
: TabBar(
|
||||
controller: tabController,
|
||||
onTap: (index) => currentTab.value = index,
|
||||
tabs: [
|
||||
Tab(text: t.settings.network.excludedDomains.domainsTab),
|
||||
Tab(text: t.settings.network.excludedDomains.appsTab),
|
||||
],
|
||||
),
|
||||
bottom: PlatformUtils.isDesktop
|
||||
? null // На Desktop только вкладка "Домены"
|
||||
: TabBar(
|
||||
controller: tabController,
|
||||
onTap: (index) => currentTab.value = index,
|
||||
tabs: [
|
||||
Tab(text: t.settings.network.excludedDomains.domainsTab),
|
||||
Tab(text: t.settings.network.excludedDomains.appsTab),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
final searchAppBar = SliverAppBar(
|
||||
|
||||
@@ -19,11 +19,6 @@ class WindowNotifier extends _$WindowNotifier with AppLogger {
|
||||
Future<void> build() async {
|
||||
if (!PlatformUtils.isDesktop) return;
|
||||
|
||||
// if (Platform.isWindows) {
|
||||
// loggy.debug("ensuring single instance");
|
||||
// await WindowsSingleInstance.ensureSingleInstance([], "Hiddify");
|
||||
// }
|
||||
|
||||
await windowManager.ensureInitialized();
|
||||
await windowManager.setMinimumSize(minimumWindowSize);
|
||||
await windowManager.setSize(defaultWindowSize);
|
||||
|
||||
@@ -108,8 +108,14 @@ install(CODE "
|
||||
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
|
||||
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
|
||||
install(FILES "../libcore/bin/lib/libcore.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
COMPONENT Runtime)
|
||||
# Install custom libcore (49MB with FFI parse function)
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../libcore/bin/lib/libcore.so")
|
||||
install(FILES "../libcore/bin/lib/libcore.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
COMPONENT Runtime)
|
||||
message(STATUS "Custom libcore.so will be installed")
|
||||
else()
|
||||
message(WARNING "Custom libcore.so not found, application may fail at runtime")
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES "../libcore/bin/HiddifyCli"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Name=Umbrix
|
||||
Comment=Cross Platform Multi Protocol Proxy Frontend
|
||||
Exec=umbrix %U
|
||||
Icon=umbrix
|
||||
Icon=/usr/share/icons/hicolor/256x256/apps/umbrix.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Network;
|
||||
|
||||
@@ -14,12 +14,20 @@ struct _MyApplication
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
|
||||
#define ICON_PATH "./umbrix.png"
|
||||
#define ICON_PATH "/usr/share/icons/hicolor/256x256/apps/umbrix.png"
|
||||
|
||||
// Implements GApplication::activate.
|
||||
static void my_application_activate(GApplication *application)
|
||||
{
|
||||
MyApplication *self = MY_APPLICATION(application);
|
||||
|
||||
// Check if window already exists - if so, just present it
|
||||
GList* windows = gtk_application_get_windows(GTK_APPLICATION(application));
|
||||
if (windows) {
|
||||
gtk_window_present(GTK_WINDOW(windows->data));
|
||||
return;
|
||||
}
|
||||
|
||||
GtkWindow *window =
|
||||
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
|
||||
gtk_window_set_icon_from_file(window, ICON_PATH, NULL);
|
||||
|
||||
@@ -11,6 +11,7 @@ essential: false
|
||||
icon: ./logo/ic_launcher_playstore.png
|
||||
|
||||
postinstall_scripts:
|
||||
- chmod 644 /usr/share/icons/hicolor/256x256/apps/umbrix.png
|
||||
- echo "Installed Umbrix VPN"
|
||||
postuninstall_scripts:
|
||||
- echo "Uninstalled Umbrix"
|
||||
|
||||
Reference in New Issue
Block a user