Compare commits
1 Commits
main
...
v0.8.87-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2742c570ce |
@@ -1 +1,8 @@
|
|||||||
include: package:flutter_lints/flutter.yaml
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
analyzer:
|
||||||
|
exclude:
|
||||||
|
- lib/l10n/intl/**
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
prefer_single_quotes: true
|
||||||
@@ -406,5 +406,20 @@
|
|||||||
"import": "Import",
|
"import": "Import",
|
||||||
"importFile": "Import from file",
|
"importFile": "Import from file",
|
||||||
"importUrl": "Import from URL",
|
"importUrl": "Import from URL",
|
||||||
"autoSetSystemDns": "Auto set system DNS"
|
"autoSetSystemDns": "Auto set system DNS",
|
||||||
|
"details": "{label} details",
|
||||||
|
"creationTime": "Creation time",
|
||||||
|
"progress": "Progress",
|
||||||
|
"host": "Host",
|
||||||
|
"destination": "Destination",
|
||||||
|
"destinationGeoIP": "Destination GeoIP",
|
||||||
|
"destinationIPASN": "Destination IPASN",
|
||||||
|
"specialProxy": "Special proxy",
|
||||||
|
"specialRules": "special rules",
|
||||||
|
"remoteDestination": "Remote destination",
|
||||||
|
"networkType": "Network type",
|
||||||
|
"proxyChains": "Proxy chains",
|
||||||
|
"log": "Log",
|
||||||
|
"connection": "Connection",
|
||||||
|
"request": "Request"
|
||||||
}
|
}
|
||||||
@@ -407,5 +407,20 @@
|
|||||||
"import": "インポート",
|
"import": "インポート",
|
||||||
"importFile": "ファイルからインポート",
|
"importFile": "ファイルからインポート",
|
||||||
"importUrl": "URLからインポート",
|
"importUrl": "URLからインポート",
|
||||||
"autoSetSystemDns": "オートセットシステムDNS"
|
"autoSetSystemDns": "オートセットシステムDNS",
|
||||||
|
"details": "{label}詳細",
|
||||||
|
"creationTime": "作成時間",
|
||||||
|
"progress": "進捗",
|
||||||
|
"host": "ホスト",
|
||||||
|
"destination": "宛先",
|
||||||
|
"destinationGeoIP": "宛先地理情報",
|
||||||
|
"destinationIPASN": "宛先IP ASN",
|
||||||
|
"specialProxy": "特殊プロキシ",
|
||||||
|
"specialRules": "特殊ルール",
|
||||||
|
"remoteDestination": "リモート宛先",
|
||||||
|
"networkType": "ネットワーク種別",
|
||||||
|
"proxyChains": "プロキシチェーン",
|
||||||
|
"log": "ログ",
|
||||||
|
"connection": "接続",
|
||||||
|
"request": "リクエスト"
|
||||||
}
|
}
|
||||||
@@ -407,5 +407,20 @@
|
|||||||
"import": "Импорт",
|
"import": "Импорт",
|
||||||
"importFile": "Импорт из файла",
|
"importFile": "Импорт из файла",
|
||||||
"importUrl": "Импорт по URL",
|
"importUrl": "Импорт по URL",
|
||||||
"autoSetSystemDns": "Автоматическая настройка системного DNS"
|
"autoSetSystemDns": "Автоматическая настройка системного DNS",
|
||||||
|
"details": "Детали {}",
|
||||||
|
"creationTime": "Время создания",
|
||||||
|
"progress": "Прогресс",
|
||||||
|
"host": "Хост",
|
||||||
|
"destination": "Назначение",
|
||||||
|
"destinationGeoIP": "Геолокация назначения",
|
||||||
|
"destinationIPASN": "ASN назначения",
|
||||||
|
"specialProxy": "Специальный прокси",
|
||||||
|
"specialRules": "Специальные правила",
|
||||||
|
"remoteDestination": "Удалённое назначение",
|
||||||
|
"networkType": "Тип сети",
|
||||||
|
"proxyChains": "Цепочки прокси",
|
||||||
|
"log": "Журнал",
|
||||||
|
"connection": "Соединение",
|
||||||
|
"request": "Запрос"
|
||||||
}
|
}
|
||||||
@@ -407,5 +407,20 @@
|
|||||||
"import": "导入",
|
"import": "导入",
|
||||||
"importFile": "通过文件导入",
|
"importFile": "通过文件导入",
|
||||||
"importUrl": "通过URL导入",
|
"importUrl": "通过URL导入",
|
||||||
"autoSetSystemDns": "自动设置系统DNS"
|
"autoSetSystemDns": "自动设置系统DNS",
|
||||||
|
"details": "{label}详情",
|
||||||
|
"creationTime": "创建时间",
|
||||||
|
"progress": "进度",
|
||||||
|
"host": "主机",
|
||||||
|
"destination": "目标地址",
|
||||||
|
"destinationGeoIP": "目标地理定位",
|
||||||
|
"destinationIPASN": "目标IP ASN",
|
||||||
|
"specialProxy": "特殊代理",
|
||||||
|
"specialRules": "特殊规则",
|
||||||
|
"remoteDestination": "远程目标",
|
||||||
|
"networkType": "网络类型",
|
||||||
|
"proxyChains": "代理链",
|
||||||
|
"log": "日志",
|
||||||
|
"connection": "连接",
|
||||||
|
"request": "请求"
|
||||||
}
|
}
|
||||||
|
|||||||
Submodule core/Clash.Meta updated: 413467ae6b...34ccd1202b
12
core/go.mod
12
core/go.mod
@@ -52,25 +52,25 @@ require (
|
|||||||
github.com/metacubex/amneziawg-go v0.0.0-20240922133038-fdf3a4d5a4ab // indirect
|
github.com/metacubex/amneziawg-go v0.0.0-20240922133038-fdf3a4d5a4ab // indirect
|
||||||
github.com/metacubex/bart v0.20.5 // indirect
|
github.com/metacubex/bart v0.20.5 // indirect
|
||||||
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399 // indirect
|
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399 // indirect
|
||||||
github.com/metacubex/chacha v0.1.2 // indirect
|
github.com/metacubex/chacha v0.1.5 // indirect
|
||||||
github.com/metacubex/fswatch v0.1.1 // indirect
|
github.com/metacubex/fswatch v0.1.1 // indirect
|
||||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
|
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
|
||||||
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b // indirect
|
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b // indirect
|
||||||
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect
|
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect
|
||||||
github.com/metacubex/quic-go v0.52.1-0.20250522021943-aef454b9e639 // indirect
|
github.com/metacubex/quic-go v0.52.1-0.20250522021943-aef454b9e639 // indirect
|
||||||
github.com/metacubex/randv2 v0.2.0 // indirect
|
github.com/metacubex/randv2 v0.2.0 // indirect
|
||||||
github.com/metacubex/sing v0.5.3 // indirect
|
github.com/metacubex/sing v0.5.4-0.20250605054047-54dc6097da29 // indirect
|
||||||
github.com/metacubex/sing-mux v0.3.2 // indirect
|
github.com/metacubex/sing-mux v0.3.2 // indirect
|
||||||
github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f // indirect
|
github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f // indirect
|
||||||
github.com/metacubex/sing-shadowsocks v0.2.10 // indirect
|
github.com/metacubex/sing-shadowsocks v0.2.11-0.20250621023810-0e9ef9dd0c92 // indirect
|
||||||
github.com/metacubex/sing-shadowsocks2 v0.2.4 // indirect
|
github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250621023950-93d605a2143d // indirect
|
||||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 // indirect
|
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 // indirect
|
||||||
github.com/metacubex/sing-tun v0.4.6-0.20250524142129-9d110c0af70c // indirect
|
github.com/metacubex/sing-tun v0.4.7-0.20250611091011-60774779fdd8 // indirect
|
||||||
github.com/metacubex/sing-vmess v0.2.2 // indirect
|
github.com/metacubex/sing-vmess v0.2.2 // indirect
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f // indirect
|
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f // indirect
|
||||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee // indirect
|
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee // indirect
|
||||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 // indirect
|
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 // indirect
|
||||||
github.com/metacubex/utls v1.7.3 // indirect
|
github.com/metacubex/utls v1.7.4-0.20250610022031-808d767c8c73 // indirect
|
||||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 // indirect
|
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 // indirect
|
||||||
github.com/miekg/dns v1.1.63 // indirect
|
github.com/miekg/dns v1.1.63 // indirect
|
||||||
github.com/mroth/weightedrand/v2 v2.1.0 // indirect
|
github.com/mroth/weightedrand/v2 v2.1.0 // indirect
|
||||||
|
|||||||
24
core/go.sum
24
core/go.sum
@@ -101,8 +101,8 @@ github.com/metacubex/bart v0.20.5 h1:XkgLZ17QxfxkqKdGsojoM2Zu01mmHyyQSFzt2/calTM
|
|||||||
github.com/metacubex/bart v0.20.5/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI=
|
github.com/metacubex/bart v0.20.5/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI=
|
||||||
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399 h1:oBowHVKZycNtAFbZ6avaCSZJYeme2Nrj+4RpV2cNJig=
|
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399 h1:oBowHVKZycNtAFbZ6avaCSZJYeme2Nrj+4RpV2cNJig=
|
||||||
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399/go.mod h1:4xcieuIK+M4bGQmQYZVqEaIYqjS1ahO4kXG7EmDgEro=
|
github.com/metacubex/bbolt v0.0.0-20240822011022-aed6d4850399/go.mod h1:4xcieuIK+M4bGQmQYZVqEaIYqjS1ahO4kXG7EmDgEro=
|
||||||
github.com/metacubex/chacha v0.1.2 h1:QulCq3eVm3TO6+4nVIWJtmSe7BT2GMrgVHuAoqRQnlc=
|
github.com/metacubex/chacha v0.1.5 h1:fKWMb/5c7ZrY8Uoqi79PPFxl+qwR7X/q0OrsAubyX2M=
|
||||||
github.com/metacubex/chacha v0.1.2/go.mod h1:Djn9bPZxLTXbJFSeyo0/qzEzQI+gUSSzttuzZM75GH8=
|
github.com/metacubex/chacha v0.1.5/go.mod h1:Djn9bPZxLTXbJFSeyo0/qzEzQI+gUSSzttuzZM75GH8=
|
||||||
github.com/metacubex/fswatch v0.1.1 h1:jqU7C/v+g0qc2RUFgmAOPoVvfl2BXXUXEumn6oQuxhU=
|
github.com/metacubex/fswatch v0.1.1 h1:jqU7C/v+g0qc2RUFgmAOPoVvfl2BXXUXEumn6oQuxhU=
|
||||||
github.com/metacubex/fswatch v0.1.1/go.mod h1:czrTT7Zlbz7vWft8RQu9Qqh+JoX+Nnb+UabuyN1YsgI=
|
github.com/metacubex/fswatch v0.1.1/go.mod h1:czrTT7Zlbz7vWft8RQu9Qqh+JoX+Nnb+UabuyN1YsgI=
|
||||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI=
|
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI=
|
||||||
@@ -116,20 +116,20 @@ github.com/metacubex/quic-go v0.52.1-0.20250522021943-aef454b9e639/go.mod h1:Kc6
|
|||||||
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
|
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
|
||||||
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
|
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
|
||||||
github.com/metacubex/sing v0.5.2/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
|
github.com/metacubex/sing v0.5.2/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
|
||||||
github.com/metacubex/sing v0.5.3 h1:QWdN16WFKMk06x4nzkc8SvZ7y2x+TLQrpkPoHs+WSVM=
|
github.com/metacubex/sing v0.5.4-0.20250605054047-54dc6097da29 h1:SD9q025FNTaepuFXFOKDhnGLVu6PQYChBvw2ZYPXeLo=
|
||||||
github.com/metacubex/sing v0.5.3/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
|
github.com/metacubex/sing v0.5.4-0.20250605054047-54dc6097da29/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
|
||||||
github.com/metacubex/sing-mux v0.3.2 h1:nJv52pyRivHcaZJKk2JgxpaVvj1GAXG81scSa9N7ncw=
|
github.com/metacubex/sing-mux v0.3.2 h1:nJv52pyRivHcaZJKk2JgxpaVvj1GAXG81scSa9N7ncw=
|
||||||
github.com/metacubex/sing-mux v0.3.2/go.mod h1:3rt1soewn0O6j89GCLmwAQFsq257u0jf2zQSPhTL3Bw=
|
github.com/metacubex/sing-mux v0.3.2/go.mod h1:3rt1soewn0O6j89GCLmwAQFsq257u0jf2zQSPhTL3Bw=
|
||||||
github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f h1:mP3vIm+9hRFI0C0Vl3pE0NESF/L85FDbuB0tGgUii6I=
|
github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f h1:mP3vIm+9hRFI0C0Vl3pE0NESF/L85FDbuB0tGgUii6I=
|
||||||
github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f/go.mod h1:JPTpf7fpnojsSuwRJExhSZSy63pVbp3VM39+zj+sAJM=
|
github.com/metacubex/sing-quic v0.0.0-20250523120938-f1a248e5ec7f/go.mod h1:JPTpf7fpnojsSuwRJExhSZSy63pVbp3VM39+zj+sAJM=
|
||||||
github.com/metacubex/sing-shadowsocks v0.2.10 h1:Pr7LDbjMANIQHl07zWgl1vDuhpsfDQUpZ8cX6DPabfg=
|
github.com/metacubex/sing-shadowsocks v0.2.11-0.20250621023810-0e9ef9dd0c92 h1:Y9ebcKya6ow7VHoESCN5+l4zZvg5eaL2IhI5LLCQxQA=
|
||||||
github.com/metacubex/sing-shadowsocks v0.2.10/go.mod h1:MtRM0ZZjR0kaDOzy9zWSt6/4/UlrnsNBq+1FNAF4vBk=
|
github.com/metacubex/sing-shadowsocks v0.2.11-0.20250621023810-0e9ef9dd0c92/go.mod h1:/squZ38pXrYjqtg8qn+joVvwbpGNYQNp8yxKsMVbCto=
|
||||||
github.com/metacubex/sing-shadowsocks2 v0.2.4 h1:Ec0x3hHR7xkld5Z09IGh16wtUUpBb2HgqZ9DExd8Q7s=
|
github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250621023950-93d605a2143d h1:Ey3A1tA8lVkRbK1FDmwuWj/57Nr8JMdpoVqe45mFzJg=
|
||||||
github.com/metacubex/sing-shadowsocks2 v0.2.4/go.mod h1:WP8+S0kqtnSbX1vlIpo5i8Irm/ijZITEPBcZ26B5unY=
|
github.com/metacubex/sing-shadowsocks2 v0.2.5-0.20250621023950-93d605a2143d/go.mod h1:+ukTd0OPFglT3bnKAYTJWYPbuox6HYNXE235r5tHdUk=
|
||||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
|
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
|
||||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
||||||
github.com/metacubex/sing-tun v0.4.6-0.20250524142129-9d110c0af70c h1:Y6jk7AH5BEg9Dsvczrf/KokYsvxeKSZZlCLHg+hC4ro=
|
github.com/metacubex/sing-tun v0.4.7-0.20250611091011-60774779fdd8 h1:4zWKqxTx75TbfW2EmlQ3hxM6RTRg2PYOAVMCnU4I61I=
|
||||||
github.com/metacubex/sing-tun v0.4.6-0.20250524142129-9d110c0af70c/go.mod h1:HDaHDL6onAX2ZGbAGUXKp++PohRdNb7Nzt6zxzhox+U=
|
github.com/metacubex/sing-tun v0.4.7-0.20250611091011-60774779fdd8/go.mod h1:2YywXPWW8Z97kTH7RffOeykKzU+l0aiKlglWV1PAS64=
|
||||||
github.com/metacubex/sing-vmess v0.2.2 h1:nG6GIKF1UOGmlzs+BIetdGHkFZ20YqFVIYp5Htqzp+4=
|
github.com/metacubex/sing-vmess v0.2.2 h1:nG6GIKF1UOGmlzs+BIetdGHkFZ20YqFVIYp5Htqzp+4=
|
||||||
github.com/metacubex/sing-vmess v0.2.2/go.mod h1:CVDNcdSLVYFgTHQlubr88d8CdqupAUDqLjROos+H9xk=
|
github.com/metacubex/sing-vmess v0.2.2/go.mod h1:CVDNcdSLVYFgTHQlubr88d8CdqupAUDqLjROos+H9xk=
|
||||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
|
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
|
||||||
@@ -138,8 +138,8 @@ github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113a
|
|||||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
|
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE=
|
||||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 h1:j1VRTiC9JLR4nUbSikx9OGdu/3AgFDqgcLj4GoqyQkc=
|
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 h1:j1VRTiC9JLR4nUbSikx9OGdu/3AgFDqgcLj4GoqyQkc=
|
||||||
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||||
github.com/metacubex/utls v1.7.3 h1:yDcMEWojFh+t8rU9X0HPcZDPAoFze/rIIyssqivzj8A=
|
github.com/metacubex/utls v1.7.4-0.20250610022031-808d767c8c73 h1:HWKsf92BqLYqugATFIJ3hYiEBZ7JF6AoqyvqF39afuI=
|
||||||
github.com/metacubex/utls v1.7.3/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
|
github.com/metacubex/utls v1.7.4-0.20250610022031-808d767c8c73/go.mod h1:oknYT0qTOwE4hjPmZOEpzVdefnW7bAdGLvZcqmk4TLU=
|
||||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
||||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
||||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class ApplicationState extends ConsumerState<Application> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_autoUpdateGroupTask() {
|
void _autoUpdateGroupTask() {
|
||||||
_autoUpdateGroupTaskTimer = Timer(const Duration(milliseconds: 20000), () {
|
_autoUpdateGroupTaskTimer = Timer(const Duration(milliseconds: 20000), () {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
globalState.appController.updateGroupsDebounce();
|
globalState.appController.updateGroupsDebounce();
|
||||||
@@ -71,14 +71,14 @@ class ApplicationState extends ConsumerState<Application> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_autoUpdateProfilesTask() {
|
void _autoUpdateProfilesTask() {
|
||||||
_autoUpdateProfilesTaskTimer = Timer(const Duration(minutes: 20), () async {
|
_autoUpdateProfilesTaskTimer = Timer(const Duration(minutes: 20), () async {
|
||||||
await globalState.appController.autoUpdateProfiles();
|
await globalState.appController.autoUpdateProfiles();
|
||||||
_autoUpdateProfilesTask();
|
_autoUpdateProfilesTask();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildPlatformState(Widget child) {
|
Widget _buildPlatformState(Widget child) {
|
||||||
if (system.isDesktop) {
|
if (system.isDesktop) {
|
||||||
return WindowManager(
|
return WindowManager(
|
||||||
child: TrayManager(
|
child: TrayManager(
|
||||||
@@ -97,13 +97,13 @@ class ApplicationState extends ConsumerState<Application> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildState(Widget child) {
|
Widget _buildState(Widget child) {
|
||||||
return AppStateManager(
|
return AppStateManager(
|
||||||
child: ClashManager(
|
child: ClashManager(
|
||||||
child: ConnectivityManager(
|
child: ConnectivityManager(
|
||||||
onConnectivityChanged: (results) async {
|
onConnectivityChanged: (results) async {
|
||||||
if (!results.contains(ConnectivityResult.vpn)) {
|
if (!results.contains(ConnectivityResult.vpn)) {
|
||||||
await clashCore.closeConnections();
|
clashCore.closeConnections();
|
||||||
}
|
}
|
||||||
globalState.appController.updateLocalIp();
|
globalState.appController.updateLocalIp();
|
||||||
globalState.appController.addCheckIpNumDebounce();
|
globalState.appController.addCheckIpNumDebounce();
|
||||||
@@ -114,7 +114,7 @@ class ApplicationState extends ConsumerState<Application> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildPlatformApp(Widget child) {
|
Widget _buildPlatformApp(Widget child) {
|
||||||
if (system.isDesktop) {
|
if (system.isDesktop) {
|
||||||
return WindowHeaderContainer(
|
return WindowHeaderContainer(
|
||||||
child: child,
|
child: child,
|
||||||
@@ -125,7 +125,7 @@ class ApplicationState extends ConsumerState<Application> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildApp(Widget child) {
|
Widget _buildApp(Widget child) {
|
||||||
return MessageManager(
|
return MessageManager(
|
||||||
child: ThemeManager(
|
child: ThemeManager(
|
||||||
child: child,
|
child: child,
|
||||||
@@ -153,8 +153,12 @@ class ApplicationState extends ConsumerState<Application> {
|
|||||||
],
|
],
|
||||||
builder: (_, child) {
|
builder: (_, child) {
|
||||||
return AppEnvManager(
|
return AppEnvManager(
|
||||||
child: _buildPlatformApp(
|
child: _buildApp(
|
||||||
_buildApp(child!),
|
AppSidebarContainer(
|
||||||
|
child: _buildPlatformApp(
|
||||||
|
child!,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -179,7 +183,7 @@ class ApplicationState extends ConsumerState<Application> {
|
|||||||
primaryColor: themeProps.primaryColor,
|
primaryColor: themeProps.primaryColor,
|
||||||
).toPureBlack(themeProps.pureBlack),
|
).toPureBlack(themeProps.pureBlack),
|
||||||
),
|
),
|
||||||
home: child,
|
home: child!,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: const HomePage(),
|
child: const HomePage(),
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class ClashCore {
|
|||||||
late ClashHandlerInterface clashInterface;
|
late ClashHandlerInterface clashInterface;
|
||||||
|
|
||||||
ClashCore._internal() {
|
ClashCore._internal() {
|
||||||
if (Platform.isAndroid) {
|
if (system.isAndroid) {
|
||||||
clashInterface = clashLib!;
|
clashInterface = clashLib!;
|
||||||
} else {
|
} else {
|
||||||
clashInterface = clashService!;
|
clashInterface = clashService!;
|
||||||
@@ -84,7 +84,7 @@ class ClashCore {
|
|||||||
return await clashInterface.setState(state);
|
return await clashInterface.setState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown() async {
|
Future<void> shutdown() async {
|
||||||
await clashInterface.shutdown();
|
await clashInterface.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,14 +107,14 @@ class ClashCore {
|
|||||||
if (proxies.isEmpty) return [];
|
if (proxies.isEmpty) return [];
|
||||||
final groupNames = [
|
final groupNames = [
|
||||||
UsedProxy.GLOBAL.name,
|
UsedProxy.GLOBAL.name,
|
||||||
...(proxies[UsedProxy.GLOBAL.name]["all"] as List).where((e) {
|
...(proxies[UsedProxy.GLOBAL.name]['all'] as List).where((e) {
|
||||||
final proxy = proxies[e] ?? {};
|
final proxy = proxies[e] ?? {};
|
||||||
return GroupTypeExtension.valueList.contains(proxy['type']);
|
return GroupTypeExtension.valueList.contains(proxy['type']);
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
final groupsRaw = groupNames.map((groupName) {
|
final groupsRaw = groupNames.map((groupName) {
|
||||||
final group = proxies[groupName];
|
final group = proxies[groupName];
|
||||||
group["all"] = ((group["all"] ?? []) as List)
|
group['all'] = ((group['all'] ?? []) as List)
|
||||||
.map(
|
.map(
|
||||||
(name) => proxies[name],
|
(name) => proxies[name],
|
||||||
)
|
)
|
||||||
@@ -133,22 +133,22 @@ class ClashCore {
|
|||||||
return await clashInterface.changeProxy(changeProxyParams);
|
return await clashInterface.changeProxy(changeProxyParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Connection>> getConnections() async {
|
Future<List<TrackerInfo>> getConnections() async {
|
||||||
final res = await clashInterface.getConnections();
|
final res = await clashInterface.getConnections();
|
||||||
final connectionsData = json.decode(res) as Map;
|
final connectionsData = json.decode(res) as Map;
|
||||||
final connectionsRaw = connectionsData['connections'] as List? ?? [];
|
final connectionsRaw = connectionsData['connections'] as List? ?? [];
|
||||||
return connectionsRaw.map((e) => Connection.fromJson(e)).toList();
|
return connectionsRaw.map((e) => TrackerInfo.fromJson(e)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
closeConnection(String id) {
|
void closeConnection(String id) {
|
||||||
clashInterface.closeConnection(id);
|
clashInterface.closeConnection(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
closeConnections() {
|
void closeConnections() {
|
||||||
clashInterface.closeConnections();
|
clashInterface.closeConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
resetConnections() {
|
void resetConnections() {
|
||||||
clashInterface.resetConnections();
|
clashInterface.resetConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,11 +202,11 @@ class ClashCore {
|
|||||||
return clashInterface.updateExternalProvider(providerName);
|
return clashInterface.updateExternalProvider(providerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
startListener() async {
|
Future<void> startListener() async {
|
||||||
await clashInterface.startListener();
|
await clashInterface.startListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
stopListener() async {
|
Future<void> stopListener() async {
|
||||||
await clashInterface.stopListener();
|
await clashInterface.stopListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,23 +260,23 @@ class ClashCore {
|
|||||||
return int.parse(value);
|
return int.parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
resetTraffic() {
|
void resetTraffic() {
|
||||||
clashInterface.resetTraffic();
|
clashInterface.resetTraffic();
|
||||||
}
|
}
|
||||||
|
|
||||||
startLog() {
|
void startLog() {
|
||||||
clashInterface.startLog();
|
clashInterface.startLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
stopLog() {
|
void stopLog() {
|
||||||
clashInterface.stopLog();
|
clashInterface.stopLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
requestGc() {
|
Future<void> requestGc() async {
|
||||||
clashInterface.forceGc();
|
await clashInterface.forceGc();
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() async {
|
Future<void> destroy() async {
|
||||||
await clashInterface.destroy();
|
await clashInterface.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,11 +57,11 @@ mixin ClashInterface {
|
|||||||
|
|
||||||
FutureOr<String> getMemory();
|
FutureOr<String> getMemory();
|
||||||
|
|
||||||
resetTraffic();
|
FutureOr<void> resetTraffic();
|
||||||
|
|
||||||
startLog();
|
FutureOr<void> startLog();
|
||||||
|
|
||||||
stopLog();
|
FutureOr<void> stopLog();
|
||||||
|
|
||||||
Future<bool> crash();
|
Future<bool> crash();
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ mixin AndroidClashInterface {
|
|||||||
abstract class ClashHandlerInterface with ClashInterface {
|
abstract class ClashHandlerInterface with ClashInterface {
|
||||||
Map<String, Completer> callbackCompleterMap = {};
|
Map<String, Completer> callbackCompleterMap = {};
|
||||||
|
|
||||||
handleResult(ActionResult result) async {
|
Future<void> handleResult(ActionResult result) async {
|
||||||
final completer = callbackCompleterMap[result.id];
|
final completer = callbackCompleterMap[result.id];
|
||||||
try {
|
try {
|
||||||
switch (result.method) {
|
switch (result.method) {
|
||||||
@@ -105,13 +105,13 @@ abstract class ClashHandlerInterface with ClashInterface {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
commonPrint.log("${result.id} error $e");
|
commonPrint.log('${result.id} error $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(String message);
|
void sendMessage(String message);
|
||||||
|
|
||||||
reStart();
|
FutureOr<void> reStart();
|
||||||
|
|
||||||
FutureOr<bool> destroy();
|
FutureOr<bool> destroy();
|
||||||
|
|
||||||
@@ -122,14 +122,14 @@ abstract class ClashHandlerInterface with ClashInterface {
|
|||||||
FutureOr<T> Function()? onTimeout,
|
FutureOr<T> Function()? onTimeout,
|
||||||
T? defaultValue,
|
T? defaultValue,
|
||||||
}) async {
|
}) async {
|
||||||
final id = "${method.name}#${utils.id}";
|
final id = '${method.name}#${utils.id}';
|
||||||
|
|
||||||
callbackCompleterMap[id] = Completer<T>();
|
callbackCompleterMap[id] = Completer<T>();
|
||||||
|
|
||||||
dynamic mDefaultValue = defaultValue;
|
dynamic mDefaultValue = defaultValue;
|
||||||
if (mDefaultValue == null) {
|
if (mDefaultValue == null) {
|
||||||
if (T == String) {
|
if (T == String) {
|
||||||
mDefaultValue = "";
|
mDefaultValue = '';
|
||||||
} else if (T == bool) {
|
} else if (T == bool) {
|
||||||
mDefaultValue = false;
|
mDefaultValue = false;
|
||||||
} else if (T == Map) {
|
} else if (T == Map) {
|
||||||
@@ -290,8 +290,8 @@ abstract class ClashHandlerInterface with ClashInterface {
|
|||||||
return invoke<String>(
|
return invoke<String>(
|
||||||
method: ActionMethod.sideLoadExternalProvider,
|
method: ActionMethod.sideLoadExternalProvider,
|
||||||
data: json.encode({
|
data: json.encode({
|
||||||
"providerName": providerName,
|
'providerName': providerName,
|
||||||
"data": data,
|
'data': data,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -382,9 +382,9 @@ abstract class ClashHandlerInterface with ClashInterface {
|
|||||||
@override
|
@override
|
||||||
Future<String> asyncTestDelay(String url, String proxyName) {
|
Future<String> asyncTestDelay(String url, String proxyName) {
|
||||||
final delayParams = {
|
final delayParams = {
|
||||||
"proxy-name": proxyName,
|
'proxy-name': proxyName,
|
||||||
"timeout": httpTimeoutDuration.inMilliseconds,
|
'timeout': httpTimeoutDuration.inMilliseconds,
|
||||||
"test-url": url,
|
'test-url': url,
|
||||||
};
|
};
|
||||||
return invoke<String>(
|
return invoke<String>(
|
||||||
method: ActionMethod.asyncTestDelay,
|
method: ActionMethod.asyncTestDelay,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
@@ -30,7 +29,7 @@ class ClashLib extends ClashHandlerInterface with AndroidClashInterface {
|
|||||||
return _canSendCompleter.future;
|
return _canSendCompleter.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
_initService() async {
|
Future<void> _initService() async {
|
||||||
await service?.destroy();
|
await service?.destroy();
|
||||||
_registerMainPort(receiverPort.sendPort);
|
_registerMainPort(receiverPort.sendPort);
|
||||||
receiverPort.listen((message) {
|
receiverPort.listen((message) {
|
||||||
@@ -52,7 +51,7 @@ class ClashLib extends ClashHandlerInterface with AndroidClashInterface {
|
|||||||
await service?.init();
|
await service?.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
_registerMainPort(SendPort sendPort) {
|
void _registerMainPort(SendPort sendPort) {
|
||||||
IsolateNameServer.removePortNameMapping(mainIsolate);
|
IsolateNameServer.removePortNameMapping(mainIsolate);
|
||||||
IsolateNameServer.registerPortWithName(sendPort, mainIsolate);
|
IsolateNameServer.registerPortWithName(sendPort, mainIsolate);
|
||||||
}
|
}
|
||||||
@@ -139,7 +138,7 @@ class ClashLibHandler {
|
|||||||
late final DynamicLibrary lib;
|
late final DynamicLibrary lib;
|
||||||
|
|
||||||
ClashLibHandler._internal() {
|
ClashLibHandler._internal() {
|
||||||
lib = DynamicLibrary.open("libclash.so");
|
lib = DynamicLibrary.open('libclash.so');
|
||||||
clashFFI = ClashFFI(lib);
|
clashFFI = ClashFFI(lib);
|
||||||
clashFFI.initNativeApiBridge(
|
clashFFI.initNativeApiBridge(
|
||||||
NativeApi.initializeApiDLData,
|
NativeApi.initializeApiDLData,
|
||||||
@@ -169,19 +168,19 @@ class ClashLibHandler {
|
|||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
attachMessagePort(int messagePort) {
|
void attachMessagePort(int messagePort) {
|
||||||
clashFFI.attachMessagePort(
|
clashFFI.attachMessagePort(
|
||||||
messagePort,
|
messagePort,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDns(String dns) {
|
void updateDns(String dns) {
|
||||||
final dnsChar = dns.toNativeUtf8().cast<Char>();
|
final dnsChar = dns.toNativeUtf8().cast<Char>();
|
||||||
clashFFI.updateDns(dnsChar);
|
clashFFI.updateDns(dnsChar);
|
||||||
malloc.free(dnsChar);
|
malloc.free(dnsChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(CoreState state) {
|
void setState(CoreState state) {
|
||||||
final stateChar = json.encode(state).toNativeUtf8().cast<Char>();
|
final stateChar = json.encode(state).toNativeUtf8().cast<Char>();
|
||||||
clashFFI.setState(stateChar);
|
clashFFI.setState(stateChar);
|
||||||
malloc.free(stateChar);
|
malloc.free(stateChar);
|
||||||
@@ -221,12 +220,12 @@ class ClashLibHandler {
|
|||||||
return Traffic.fromMap(json.decode(trafficString));
|
return Traffic.fromMap(json.decode(trafficString));
|
||||||
}
|
}
|
||||||
|
|
||||||
startListener() async {
|
Future<bool> startListener() async {
|
||||||
clashFFI.startListener();
|
clashFFI.startListener();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
stopListener() async {
|
Future<bool> stopListener() async {
|
||||||
clashFFI.stopListener();
|
clashFFI.stopListener();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -287,7 +286,7 @@ class ClashLibHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClashLib? get clashLib =>
|
ClashLib? get clashLib =>
|
||||||
Platform.isAndroid && !globalState.isService ? ClashLib() : null;
|
system.isAndroid && !globalState.isService ? ClashLib() : null;
|
||||||
|
|
||||||
ClashLibHandler? get clashLibHandler =>
|
ClashLibHandler? get clashLibHandler =>
|
||||||
Platform.isAndroid && globalState.isService ? ClashLibHandler() : null;
|
system.isAndroid && globalState.isService ? ClashLibHandler() : null;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class ClashMessage {
|
|||||||
listener.onDelay(Delay.fromJson(m.data));
|
listener.onDelay(Delay.fromJson(m.data));
|
||||||
break;
|
break;
|
||||||
case AppMessageType.request:
|
case AppMessageType.request:
|
||||||
listener.onRequest(Connection.fromJson(m.data));
|
listener.onRequest(TrackerInfo.fromJson(m.data));
|
||||||
break;
|
break;
|
||||||
case AppMessageType.loaded:
|
case AppMessageType.loaded:
|
||||||
listener.onLoaded(m.data);
|
listener.onLoaded(m.data);
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ class ClashService extends ClashHandlerInterface {
|
|||||||
reStart();
|
reStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
_initServer() async {
|
Future<void> _initServer() async {
|
||||||
runZonedGuarded(() async {
|
runZonedGuarded(() async {
|
||||||
final address = !Platform.isWindows
|
final address = !system.isWindows
|
||||||
? InternetAddress(
|
? InternetAddress(
|
||||||
unixSocketPath,
|
unixSocketPath,
|
||||||
type: InternetAddressType.unix,
|
type: InternetAddressType.unix,
|
||||||
@@ -83,10 +83,10 @@ class ClashService extends ClashHandlerInterface {
|
|||||||
await shutdown();
|
await shutdown();
|
||||||
}
|
}
|
||||||
final serverSocket = await serverCompleter.future;
|
final serverSocket = await serverCompleter.future;
|
||||||
final arg = Platform.isWindows
|
final arg = system.isWindows
|
||||||
? "${serverSocket.port}"
|
? '${serverSocket.port}'
|
||||||
: serverSocket.address.address;
|
: serverSocket.address.address;
|
||||||
if (Platform.isWindows && await system.checkIsAdmin()) {
|
if (system.isWindows && await system.checkIsAdmin()) {
|
||||||
final isSuccess = await request.startCoreByHelper(arg);
|
final isSuccess = await request.startCoreByHelper(arg);
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
return;
|
return;
|
||||||
@@ -122,8 +122,8 @@ class ClashService extends ClashHandlerInterface {
|
|||||||
socket.writeln(message);
|
socket.writeln(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
_deleteSocketFile() async {
|
Future<void> _deleteSocketFile() async {
|
||||||
if (!Platform.isWindows) {
|
if (!system.isWindows) {
|
||||||
final file = File(unixSocketPath);
|
final file = File(unixSocketPath);
|
||||||
if (await file.exists()) {
|
if (await file.exists()) {
|
||||||
await file.delete();
|
await file.delete();
|
||||||
@@ -131,7 +131,7 @@ class ClashService extends ClashHandlerInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_destroySocket() async {
|
Future<void> _destroySocket() async {
|
||||||
if (socketCompleter.isCompleted) {
|
if (socketCompleter.isCompleted) {
|
||||||
final lastSocket = await socketCompleter.future;
|
final lastSocket = await socketCompleter.future;
|
||||||
await lastSocket.close();
|
await lastSocket.close();
|
||||||
@@ -141,7 +141,7 @@ class ClashService extends ClashHandlerInterface {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
shutdown() async {
|
shutdown() async {
|
||||||
if (Platform.isWindows) {
|
if (system.isWindows) {
|
||||||
await request.stopCoreByHelper();
|
await request.stopCoreByHelper();
|
||||||
}
|
}
|
||||||
await _destroySocket();
|
await _destroySocket();
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:fl_clash/plugins/app.dart';
|
import 'package:fl_clash/plugins/app.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
|
|
||||||
|
import 'system.dart';
|
||||||
|
|
||||||
class Android {
|
class Android {
|
||||||
init() async {
|
Future<void> init() async {
|
||||||
app?.onExit = () async {
|
app?.onExit = () async {
|
||||||
await globalState.appController.savePreferences();
|
await globalState.appController.savePreferences();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final android = Platform.isAndroid ? Android() : null;
|
final android = system.isAndroid ? Android() : null;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:archive/archive_io.dart';
|
import 'package:archive/archive_io.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
extension ArchiveExt on Archive {
|
extension ArchiveExt on Archive {
|
||||||
addDirectoryToArchive(String dirPath, String parentPath) {
|
void addDirectoryToArchive(String dirPath, String parentPath) {
|
||||||
final dir = Directory(dirPath);
|
final dir = Directory(dirPath);
|
||||||
final entities = dir.listSync(recursive: false);
|
final entities = dir.listSync(recursive: false);
|
||||||
for (final entity in entities) {
|
for (final entity in entities) {
|
||||||
@@ -19,7 +20,7 @@ extension ArchiveExt on Archive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add<T>(String name, T raw) {
|
void add<T>(String name, T raw) {
|
||||||
final data = json.encode(raw);
|
final data = json.encode(raw);
|
||||||
addFile(
|
addFile(
|
||||||
ArchiveFile(name, data.length, data),
|
ArchiveFile(name, data.length, data),
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ extension ColorExtension on Color {
|
|||||||
return withAlpha(77);
|
return withAlpha(77);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color get opacity12 {
|
||||||
|
return withAlpha(31);
|
||||||
|
}
|
||||||
|
|
||||||
Color get opacity15 {
|
Color get opacity15 {
|
||||||
return withAlpha(38);
|
return withAlpha(38);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,4 +37,3 @@ export 'text.dart';
|
|||||||
export 'tray.dart';
|
export 'tray.dart';
|
||||||
export 'utils.dart';
|
export 'utils.dart';
|
||||||
export 'window.dart';
|
export 'window.dart';
|
||||||
export 'windows.dart';
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
@@ -8,13 +7,13 @@ import 'package:fl_clash/enum/enum.dart';
|
|||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
const appName = "FlClash";
|
const appName = 'FlClash';
|
||||||
const appHelperService = "FlClashHelperService";
|
const appHelperService = 'FlClashHelperService';
|
||||||
const coreName = "clash.meta";
|
const coreName = 'clash.meta';
|
||||||
const browserUa =
|
const browserUa =
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
||||||
const packageName = "com.follow.clash";
|
const packageName = 'com.follow.clash';
|
||||||
final unixSocketPath = "/tmp/FlClashSocket_${Random().nextInt(10000)}.sock";
|
final unixSocketPath = '/tmp/FlClashSocket_${Random().nextInt(10000)}.sock';
|
||||||
const helperPort = 47890;
|
const helperPort = 47890;
|
||||||
const maxTextScale = 1.4;
|
const maxTextScale = 1.4;
|
||||||
const minTextScale = 0.8;
|
const minTextScale = 0.8;
|
||||||
@@ -31,25 +30,25 @@ const animateDuration = Duration(milliseconds: 100);
|
|||||||
const midDuration = Duration(milliseconds: 200);
|
const midDuration = Duration(milliseconds: 200);
|
||||||
const commonDuration = Duration(milliseconds: 300);
|
const commonDuration = Duration(milliseconds: 300);
|
||||||
const defaultUpdateDuration = Duration(days: 1);
|
const defaultUpdateDuration = Duration(days: 1);
|
||||||
const mmdbFileName = "geoip.metadb";
|
const mmdbFileName = 'geoip.metadb';
|
||||||
const asnFileName = "ASN.mmdb";
|
const asnFileName = 'ASN.mmdb';
|
||||||
const geoIpFileName = "GeoIP.dat";
|
const geoIpFileName = 'GeoIP.dat';
|
||||||
const geoSiteFileName = "GeoSite.dat";
|
const geoSiteFileName = 'GeoSite.dat';
|
||||||
final double kHeaderHeight = system.isDesktop
|
final double kHeaderHeight = system.isDesktop
|
||||||
? !Platform.isMacOS
|
? !system.isMacOS
|
||||||
? 40
|
? 40
|
||||||
: 28
|
: 28
|
||||||
: 0;
|
: 0;
|
||||||
const profilesDirectoryName = "profiles";
|
const profilesDirectoryName = 'profiles';
|
||||||
const localhost = "127.0.0.1";
|
const localhost = '127.0.0.1';
|
||||||
const clashConfigKey = "clash_config";
|
const clashConfigKey = 'clash_config';
|
||||||
const configKey = "config";
|
const configKey = 'config';
|
||||||
const double dialogCommonWidth = 300;
|
const double dialogCommonWidth = 300;
|
||||||
const repository = "chen08209/FlClash";
|
const repository = 'chen08209/FlClash';
|
||||||
const defaultExternalController = "127.0.0.1:9090";
|
const defaultExternalController = '127.0.0.1:9090';
|
||||||
const maxMobileWidth = 600;
|
const maxMobileWidth = 600;
|
||||||
const maxLaptopWidth = 840;
|
const maxLaptopWidth = 840;
|
||||||
const defaultTestUrl = "https://www.gstatic.com/generate_204";
|
const defaultTestUrl = 'https://www.gstatic.com/generate_204';
|
||||||
final commonFilter = ImageFilter.blur(
|
final commonFilter = ImageFilter.blur(
|
||||||
sigmaX: 5,
|
sigmaX: 5,
|
||||||
sigmaY: 5,
|
sigmaY: 5,
|
||||||
@@ -57,7 +56,7 @@ final commonFilter = ImageFilter.blur(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const navigationItemListEquality = ListEquality<NavigationItem>();
|
const navigationItemListEquality = ListEquality<NavigationItem>();
|
||||||
const connectionListEquality = ListEquality<Connection>();
|
const trackerInfoListEquality = ListEquality<TrackerInfo>();
|
||||||
const stringListEquality = ListEquality<String>();
|
const stringListEquality = ListEquality<String>();
|
||||||
const intListEquality = ListEquality<int>();
|
const intListEquality = ListEquality<int>();
|
||||||
const logListEquality = ListEquality<Log>();
|
const logListEquality = ListEquality<Log>();
|
||||||
@@ -78,9 +77,9 @@ const viewModeColumnsMap = {
|
|||||||
ViewMode.desktop: [4, 3],
|
ViewMode.desktop: [4, 3],
|
||||||
};
|
};
|
||||||
|
|
||||||
// const proxiesStoreKey = PageStorageKey<String>('proxies');
|
const proxiesListStoreKey = PageStorageKey<String>('proxies_list');
|
||||||
// const toolsStoreKey = PageStorageKey<String>('tools');
|
const toolsStoreKey = PageStorageKey<String>('tools');
|
||||||
// const profilesStoreKey = PageStorageKey<String>('profiles');
|
const profilesStoreKey = PageStorageKey<String>('profiles');
|
||||||
|
|
||||||
const defaultPrimaryColor = 0XFFD8C0C3;
|
const defaultPrimaryColor = 0XFFD8C0C3;
|
||||||
|
|
||||||
@@ -88,11 +87,11 @@ double getWidgetHeight(num lines) {
|
|||||||
return max(lines * 84 + (lines - 1) * 16, 0).ap;
|
return max(lines * 84 + (lines - 1) * 16, 0).ap;
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxLength = 150;
|
const maxLength = 1000;
|
||||||
|
|
||||||
final mainIsolate = "FlClashMainIsolate";
|
final mainIsolate = 'FlClashMainIsolate';
|
||||||
|
|
||||||
final serviceIsolate = "FlClashServiceIsolate";
|
final serviceIsolate = 'FlClashServiceIsolate';
|
||||||
|
|
||||||
const defaultPrimaryColors = [
|
const defaultPrimaryColors = [
|
||||||
0xFF795548,
|
0xFF795548,
|
||||||
@@ -104,7 +103,7 @@ const defaultPrimaryColors = [
|
|||||||
0XFF665390,
|
0XFF665390,
|
||||||
];
|
];
|
||||||
|
|
||||||
const scriptTemplate = """
|
const scriptTemplate = '''
|
||||||
const main = (config) => {
|
const main = (config) => {
|
||||||
return config;
|
return config;
|
||||||
}""";
|
}''';
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ extension BuildContextExtension on BuildContext {
|
|||||||
return findAncestorStateOfType<CommonScaffoldState>();
|
return findAncestorStateOfType<CommonScaffoldState>();
|
||||||
}
|
}
|
||||||
|
|
||||||
showNotifier(String text) {
|
Future<void>? showNotifier(String text) {
|
||||||
return findAncestorStateOfType<MessageManagerState>()?.message(text);
|
return findAncestorStateOfType<MessageManagerState>()?.message(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
showSnackBar(
|
void showSnackBar(
|
||||||
String message, {
|
String message, {
|
||||||
SnackBarAction? action,
|
SnackBarAction? action,
|
||||||
}) {
|
}) {
|
||||||
@@ -72,3 +72,18 @@ extension BuildContextExtension on BuildContext {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BackHandleInherited extends InheritedWidget {
|
||||||
|
final Function handleBack;
|
||||||
|
|
||||||
|
const BackHandleInherited(
|
||||||
|
{super.key, required this.handleBack, required super.child});
|
||||||
|
|
||||||
|
static BackHandleInherited? of(BuildContext context) =>
|
||||||
|
context.dependOnInheritedWidgetOfExactType<BackHandleInherited>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool updateShouldNotify(BackHandleInherited oldWidget) {
|
||||||
|
return handleBack != oldWidget.handleBack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,26 +17,34 @@ extension DateTimeExtension on DateTime {
|
|||||||
final difference = currentDateTime.difference(this);
|
final difference = currentDateTime.difference(this);
|
||||||
final days = difference.inDays;
|
final days = difference.inDays;
|
||||||
if (days >= 365) {
|
if (days >= 365) {
|
||||||
return "${(days / 365).floor()} ${appLocalizations.years}${appLocalizations.ago}";
|
return '${(days / 365).floor()} ${appLocalizations.years}${appLocalizations.ago}';
|
||||||
}
|
}
|
||||||
if (days >= 30) {
|
if (days >= 30) {
|
||||||
return "${(days / 30).floor()} ${appLocalizations.months}${appLocalizations.ago}";
|
return '${(days / 30).floor()} ${appLocalizations.months}${appLocalizations.ago}';
|
||||||
}
|
}
|
||||||
if (days >= 1) {
|
if (days >= 1) {
|
||||||
return "$days ${appLocalizations.days}${appLocalizations.ago}";
|
return '$days ${appLocalizations.days}${appLocalizations.ago}';
|
||||||
}
|
}
|
||||||
final hours = difference.inHours;
|
final hours = difference.inHours;
|
||||||
if (hours >= 1) {
|
if (hours >= 1) {
|
||||||
return "$hours ${appLocalizations.hours}${appLocalizations.ago}";
|
return '$hours ${appLocalizations.hours}${appLocalizations.ago}';
|
||||||
}
|
}
|
||||||
final minutes = difference.inMinutes;
|
final minutes = difference.inMinutes;
|
||||||
if (minutes >= 1) {
|
if (minutes >= 1) {
|
||||||
return "$minutes ${appLocalizations.minutes}${appLocalizations.ago}";
|
return '$minutes ${appLocalizations.minutes}${appLocalizations.ago}';
|
||||||
}
|
}
|
||||||
return appLocalizations.just;
|
return appLocalizations.just;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get show {
|
String get show {
|
||||||
return toIso8601String().substring(0, 10);
|
return toString().substring(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get showFull {
|
||||||
|
return toString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get showTime {
|
||||||
|
return toString().substring(10, 19);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,18 +38,18 @@ class DAVClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get root => "/$appName";
|
String get root => '/$appName';
|
||||||
|
|
||||||
get backupFile => "$root/$fileName";
|
String get backupFile => '$root/$fileName';
|
||||||
|
|
||||||
backup(Uint8List data) async {
|
Future<bool> backup(Uint8List data) async {
|
||||||
await client.mkdir("$root");
|
await client.mkdir(root);
|
||||||
await client.write("$backupFile", data);
|
await client.write(backupFile, data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<int>> recovery() async {
|
Future<List<int>> recovery() async {
|
||||||
await client.mkdir("$root");
|
await client.mkdir(root);
|
||||||
final data = await client.read(backupFile);
|
final data = await client.read(backupFile);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import 'iterable.dart';
|
import 'iterable.dart';
|
||||||
|
|
||||||
|
typedef ValueCallback<T> = T Function();
|
||||||
|
|
||||||
class FixedList<T> {
|
class FixedList<T> {
|
||||||
final int maxLength;
|
final int maxLength;
|
||||||
final List<T> _list;
|
final List<T> _list;
|
||||||
@@ -7,12 +9,12 @@ class FixedList<T> {
|
|||||||
FixedList(this.maxLength, {List<T>? list})
|
FixedList(this.maxLength, {List<T>? list})
|
||||||
: _list = (list ?? [])..truncate(maxLength);
|
: _list = (list ?? [])..truncate(maxLength);
|
||||||
|
|
||||||
add(T item) {
|
void add(T item) {
|
||||||
_list.add(item);
|
_list.add(item);
|
||||||
_list.truncate(maxLength);
|
_list.truncate(maxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
void clear() {
|
||||||
_list.clear();
|
_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +40,7 @@ class FixedMap<K, V> {
|
|||||||
_map = map ?? {};
|
_map = map ?? {};
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCacheValue(K key, V Function() callback) {
|
V updateCacheValue(K key, ValueCallback<V> callback) {
|
||||||
final realValue = _map.updateCacheValue(
|
final realValue = _map.updateCacheValue(
|
||||||
key,
|
key,
|
||||||
callback,
|
callback,
|
||||||
@@ -47,21 +49,21 @@ class FixedMap<K, V> {
|
|||||||
return realValue;
|
return realValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
void clear() {
|
||||||
_map.clear();
|
_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMaxLength(int size) {
|
void updateMaxLength(int size) {
|
||||||
maxLength = size;
|
maxLength = size;
|
||||||
_adjustMap();
|
_adjustMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMap(Map<K, V> map) {
|
void updateMap(Map<K, V> map) {
|
||||||
_map = map;
|
_map = map;
|
||||||
_adjustMap();
|
_adjustMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
_adjustMap() {
|
void _adjustMap() {
|
||||||
if (_map.length > maxLength) {
|
if (_map.length > maxLength) {
|
||||||
_map = Map.fromEntries(
|
_map = Map.fromEntries(
|
||||||
map.entries.toList()..truncate(maxLength),
|
map.entries.toList()..truncate(maxLength),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:fl_clash/enum/enum.dart';
|
|||||||
class Debouncer {
|
class Debouncer {
|
||||||
final Map<FunctionTag, Timer?> _operations = {};
|
final Map<FunctionTag, Timer?> _operations = {};
|
||||||
|
|
||||||
call(
|
void call(
|
||||||
FunctionTag tag,
|
FunctionTag tag,
|
||||||
Function func, {
|
Function func, {
|
||||||
List<dynamic>? args,
|
List<dynamic>? args,
|
||||||
@@ -28,7 +28,7 @@ class Debouncer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel(dynamic tag) {
|
void cancel(dynamic tag) {
|
||||||
_operations[tag]?.cancel();
|
_operations[tag]?.cancel();
|
||||||
_operations[tag] = null;
|
_operations[tag] = null;
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ class Debouncer {
|
|||||||
class Throttler {
|
class Throttler {
|
||||||
final Map<FunctionTag, Timer?> _operations = {};
|
final Map<FunctionTag, Timer?> _operations = {};
|
||||||
|
|
||||||
call(
|
bool call(
|
||||||
FunctionTag tag,
|
FunctionTag tag,
|
||||||
Function func, {
|
Function func, {
|
||||||
List<dynamic>? args,
|
List<dynamic>? args,
|
||||||
@@ -61,7 +61,7 @@ class Throttler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel(dynamic tag) {
|
void cancel(dynamic tag) {
|
||||||
_operations[tag]?.cancel();
|
_operations[tag]?.cancel();
|
||||||
_operations[tag] = null;
|
_operations[tag] = null;
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ Future<T> retry<T>({
|
|||||||
}
|
}
|
||||||
attempts++;
|
attempts++;
|
||||||
}
|
}
|
||||||
throw "unknown error";
|
throw 'unknown error';
|
||||||
}
|
}
|
||||||
|
|
||||||
final debouncer = Debouncer();
|
final debouncer = Debouncer();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'dart:ui';
|
|||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
|
|
||||||
extension CompleterExt<T> on Completer<T> {
|
extension CompleterExt<T> on Completer<T> {
|
||||||
safeFuture({
|
Future<T> safeFuture({
|
||||||
Duration? timeout,
|
Duration? timeout,
|
||||||
VoidCallback? onLast,
|
VoidCallback? onLast,
|
||||||
FutureOr<T> Function()? onTimeout,
|
FutureOr<T> Function()? onTimeout,
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import 'package:fl_clash/state.dart';
|
|||||||
class FlClashHttpOverrides extends HttpOverrides {
|
class FlClashHttpOverrides extends HttpOverrides {
|
||||||
static String handleFindProxy(Uri url) {
|
static String handleFindProxy(Uri url) {
|
||||||
if ([localhost].contains(url.host)) {
|
if ([localhost].contains(url.host)) {
|
||||||
return "DIRECT";
|
return 'DIRECT';
|
||||||
}
|
}
|
||||||
final port = globalState.config.patchClashConfig.mixedPort;
|
final port = globalState.config.patchClashConfig.mixedPort;
|
||||||
final isStart = globalState.appState.runTime != null;
|
final isStart = globalState.appState.runTime != null;
|
||||||
commonPrint.log("find $url proxy:$isStart");
|
commonPrint.log('find $url proxy:$isStart');
|
||||||
if (!isStart) return "DIRECT";
|
if (!isStart) return 'DIRECT';
|
||||||
return "PROXY localhost:$port";
|
return 'PROXY localhost:$port';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class IconsExt{
|
class IconsExt {
|
||||||
static const IconData target =
|
static const IconData target = IconData(0xe900, fontFamily: 'Icons');
|
||||||
IconData(0xe900, fontFamily: "Icons");
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ extension IterableExt<T> on Iterable<T> {
|
|||||||
|
|
||||||
extension ListExt<T> on List<T> {
|
extension ListExt<T> on List<T> {
|
||||||
void truncate(int maxLength) {
|
void truncate(int maxLength) {
|
||||||
assert(maxLength > 0);
|
if (maxLength == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (length > maxLength) {
|
if (length > maxLength) {
|
||||||
removeRange(0, length - maxLength);
|
removeRange(0, length - maxLength);
|
||||||
}
|
}
|
||||||
@@ -70,11 +72,19 @@ extension ListExt<T> on List<T> {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<T> safeSublist(int start) {
|
List<T> safeSublist(int start, [int? end]) {
|
||||||
if (start <= 0) return this;
|
if (start <= 0) return this;
|
||||||
if (start > length) return [];
|
if (start > length) return [];
|
||||||
|
if (end != null) {
|
||||||
|
return sublist(start, end.clamp(start, length));
|
||||||
|
}
|
||||||
return sublist(start);
|
return sublist(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T safeGet(int index) {
|
||||||
|
if (length > index) return this[index];
|
||||||
|
return last;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DoubleListExt on List<double> {
|
extension DoubleListExt on List<double> {
|
||||||
@@ -104,10 +114,10 @@ extension DoubleListExt on List<double> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension MapExt<K, V> on Map<K, V> {
|
extension MapExt<K, V> on Map<K, V> {
|
||||||
updateCacheValue(K key, V Function() callback) {
|
V updateCacheValue(K key, V Function() callback) {
|
||||||
if (this[key] == null) {
|
if (this[key] == null) {
|
||||||
this[key] = callback();
|
this[key] = callback();
|
||||||
}
|
}
|
||||||
return this[key];
|
return this[key]!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:uni_platform/uni_platform.dart';
|
import 'package:uni_platform/uni_platform.dart';
|
||||||
|
|
||||||
|
import 'system.dart';
|
||||||
|
|
||||||
final Map<PhysicalKeyboardKey, String> _knownKeyLabels =
|
final Map<PhysicalKeyboardKey, String> _knownKeyLabels =
|
||||||
<PhysicalKeyboardKey, String>{
|
<PhysicalKeyboardKey, String>{
|
||||||
PhysicalKeyboardKey.keyA: 'A',
|
PhysicalKeyboardKey.keyA: 'A',
|
||||||
@@ -79,14 +79,14 @@ final Map<PhysicalKeyboardKey, String> _knownKeyLabels =
|
|||||||
PhysicalKeyboardKey.arrowLeft: '←',
|
PhysicalKeyboardKey.arrowLeft: '←',
|
||||||
PhysicalKeyboardKey.arrowDown: '↓',
|
PhysicalKeyboardKey.arrowDown: '↓',
|
||||||
PhysicalKeyboardKey.arrowUp: '↑',
|
PhysicalKeyboardKey.arrowUp: '↑',
|
||||||
PhysicalKeyboardKey.controlLeft: "CTRL",
|
PhysicalKeyboardKey.controlLeft: 'CTRL',
|
||||||
PhysicalKeyboardKey.shiftLeft: 'SHIFT',
|
PhysicalKeyboardKey.shiftLeft: 'SHIFT',
|
||||||
PhysicalKeyboardKey.altLeft: "ALT",
|
PhysicalKeyboardKey.altLeft: 'ALT',
|
||||||
PhysicalKeyboardKey.metaLeft: Platform.isMacOS ? '⌘' : 'WIN',
|
PhysicalKeyboardKey.metaLeft: system.isMacOS ? '⌘' : 'WIN',
|
||||||
PhysicalKeyboardKey.controlRight: "CTRL",
|
PhysicalKeyboardKey.controlRight: 'CTRL',
|
||||||
PhysicalKeyboardKey.shiftRight: 'SHIFT',
|
PhysicalKeyboardKey.shiftRight: 'SHIFT',
|
||||||
PhysicalKeyboardKey.altRight: "ALT",
|
PhysicalKeyboardKey.altRight: 'ALT',
|
||||||
PhysicalKeyboardKey.metaRight: Platform.isMacOS ? '⌘' : 'WIN',
|
PhysicalKeyboardKey.metaRight: system.isMacOS ? '⌘' : 'WIN',
|
||||||
PhysicalKeyboardKey.fn: 'FN',
|
PhysicalKeyboardKey.fn: 'FN',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,6 +101,3 @@ extension KeyboardKeyExt on KeyboardKey {
|
|||||||
return _knownKeyLabels[physicalKey] ?? physicalKey?.debugName ?? 'Unknown';
|
return _knownKeyLabels[physicalKey] ?? physicalKey?.debugName ?? 'Unknown';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ class AutoLaunch {
|
|||||||
return await launchAtStartup.disable();
|
return await launchAtStartup.disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus(bool isAutoLaunch) async {
|
Future<void> updateStatus(bool isAutoLaunch) async {
|
||||||
if(kDebugMode){
|
if (kDebugMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (await isEnable == isAutoLaunch) return;
|
if (await isEnable == isAutoLaunch) return;
|
||||||
|
|||||||
@@ -15,8 +15,9 @@ class LinkManager {
|
|||||||
_appLinks = AppLinks();
|
_appLinks = AppLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
initAppLinksListen(installConfigCallBack) async {
|
Future<void> initAppLinksListen(
|
||||||
commonPrint.log("initAppLinksListen");
|
Function(String url) installConfigCallBack) async {
|
||||||
|
commonPrint.log('initAppLinksListen');
|
||||||
destroy();
|
destroy();
|
||||||
subscription = _appLinks.uriLinkStream.listen(
|
subscription = _appLinks.uriLinkStream.listen(
|
||||||
(uri) {
|
(uri) {
|
||||||
@@ -32,7 +33,7 @@ class LinkManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
void destroy() {
|
||||||
if (subscription != null) {
|
if (subscription != null) {
|
||||||
subscription?.cancel();
|
subscription?.cancel();
|
||||||
subscription = null;
|
subscription = null;
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ class Measure {
|
|||||||
|
|
||||||
double get bodyMediumHeight {
|
double get bodyMediumHeight {
|
||||||
return _measureMap.updateCacheValue(
|
return _measureMap.updateCacheValue(
|
||||||
"bodyMediumHeight",
|
'bodyMediumHeight',
|
||||||
() => computeTextSize(
|
() => computeTextSize(
|
||||||
Text(
|
Text(
|
||||||
"X",
|
'X',
|
||||||
style: context.textTheme.bodyMedium,
|
style: context.textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
).height,
|
).height,
|
||||||
@@ -45,10 +45,10 @@ class Measure {
|
|||||||
|
|
||||||
double get bodyLargeHeight {
|
double get bodyLargeHeight {
|
||||||
return _measureMap.updateCacheValue(
|
return _measureMap.updateCacheValue(
|
||||||
"bodyLargeHeight",
|
'bodyLargeHeight',
|
||||||
() => computeTextSize(
|
() => computeTextSize(
|
||||||
Text(
|
Text(
|
||||||
"X",
|
'X',
|
||||||
style: context.textTheme.bodyLarge,
|
style: context.textTheme.bodyLarge,
|
||||||
),
|
),
|
||||||
).height,
|
).height,
|
||||||
@@ -57,10 +57,10 @@ class Measure {
|
|||||||
|
|
||||||
double get bodySmallHeight {
|
double get bodySmallHeight {
|
||||||
return _measureMap.updateCacheValue(
|
return _measureMap.updateCacheValue(
|
||||||
"bodySmallHeight",
|
'bodySmallHeight',
|
||||||
() => computeTextSize(
|
() => computeTextSize(
|
||||||
Text(
|
Text(
|
||||||
"X",
|
'X',
|
||||||
style: context.textTheme.bodySmall,
|
style: context.textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
).height,
|
).height,
|
||||||
@@ -69,10 +69,10 @@ class Measure {
|
|||||||
|
|
||||||
double get labelSmallHeight {
|
double get labelSmallHeight {
|
||||||
return _measureMap.updateCacheValue(
|
return _measureMap.updateCacheValue(
|
||||||
"labelSmallHeight",
|
'labelSmallHeight',
|
||||||
() => computeTextSize(
|
() => computeTextSize(
|
||||||
Text(
|
Text(
|
||||||
"X",
|
'X',
|
||||||
style: context.textTheme.labelSmall,
|
style: context.textTheme.labelSmall,
|
||||||
),
|
),
|
||||||
).height,
|
).height,
|
||||||
@@ -81,10 +81,10 @@ class Measure {
|
|||||||
|
|
||||||
double get labelMediumHeight {
|
double get labelMediumHeight {
|
||||||
return _measureMap.updateCacheValue(
|
return _measureMap.updateCacheValue(
|
||||||
"labelMediumHeight",
|
'labelMediumHeight',
|
||||||
() => computeTextSize(
|
() => computeTextSize(
|
||||||
Text(
|
Text(
|
||||||
"X",
|
'X',
|
||||||
style: context.textTheme.labelMedium,
|
style: context.textTheme.labelMedium,
|
||||||
),
|
),
|
||||||
).height,
|
).height,
|
||||||
@@ -93,10 +93,10 @@ class Measure {
|
|||||||
|
|
||||||
double get titleLargeHeight {
|
double get titleLargeHeight {
|
||||||
return _measureMap.updateCacheValue(
|
return _measureMap.updateCacheValue(
|
||||||
"titleLargeHeight",
|
'titleLargeHeight',
|
||||||
() => computeTextSize(
|
() => computeTextSize(
|
||||||
Text(
|
Text(
|
||||||
"X",
|
'X',
|
||||||
style: context.textTheme.titleLarge,
|
style: context.textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
).height,
|
).height,
|
||||||
@@ -105,10 +105,10 @@ class Measure {
|
|||||||
|
|
||||||
double get titleMediumHeight {
|
double get titleMediumHeight {
|
||||||
return _measureMap.updateCacheValue(
|
return _measureMap.updateCacheValue(
|
||||||
"titleMediumHeight",
|
'titleMediumHeight',
|
||||||
() => computeTextSize(
|
() => computeTextSize(
|
||||||
Text(
|
Text(
|
||||||
"X",
|
'X',
|
||||||
style: context.textTheme.titleMedium,
|
style: context.textTheme.titleMedium,
|
||||||
),
|
),
|
||||||
).height,
|
).height,
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import 'package:fl_clash/models/models.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:riverpod/riverpod.dart';
|
import 'package:riverpod/riverpod.dart';
|
||||||
import 'context.dart';
|
|
||||||
|
|
||||||
mixin AutoDisposeNotifierMixin<T> on AutoDisposeNotifier<T> {
|
mixin AutoDisposeNotifierMixin<T> on AutoDisposeNotifier<T> {
|
||||||
set value(T value) {
|
set value(T value) {
|
||||||
@@ -17,37 +14,31 @@ mixin AutoDisposeNotifierMixin<T> on AutoDisposeNotifier<T> {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdate(T value) {}
|
void onUpdate(T value) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin PageMixin<T extends StatefulWidget> on State<T> {
|
// mixin PageMixin<T extends StatefulWidget> on State<T> {
|
||||||
void onPageShow() {
|
// initPageState() {
|
||||||
initPageState();
|
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
}
|
// final commonScaffoldState = context.commonScaffoldState;
|
||||||
|
// commonScaffoldState?.actions = actions;
|
||||||
initPageState() {
|
// commonScaffoldState?.floatingActionButton = floatingActionButton;
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
// commonScaffoldState?.onKeywordsUpdate = onKeywordsUpdate;
|
||||||
final commonScaffoldState = context.commonScaffoldState;
|
// commonScaffoldState?.updateSearchState(
|
||||||
commonScaffoldState?.actions = actions;
|
// (_) => onSearch != null
|
||||||
commonScaffoldState?.floatingActionButton = floatingActionButton;
|
// ? AppBarSearchState(
|
||||||
commonScaffoldState?.onKeywordsUpdate = onKeywordsUpdate;
|
// onSearch: onSearch!,
|
||||||
commonScaffoldState?.updateSearchState(
|
// )
|
||||||
(_) => onSearch != null
|
// : null,
|
||||||
? AppBarSearchState(
|
// );
|
||||||
onSearch: onSearch!,
|
// });
|
||||||
)
|
// }
|
||||||
: null,
|
//
|
||||||
);
|
// List<Widget> get actions => [];
|
||||||
});
|
//
|
||||||
}
|
// Widget? get floatingActionButton => null;
|
||||||
|
//
|
||||||
void onPageHidden() {}
|
// Function(String)? get onSearch => null;
|
||||||
|
//
|
||||||
List<Widget> get actions => [];
|
// Function(List<String>)? get onKeywordsUpdate => null;
|
||||||
|
// }
|
||||||
Widget? get floatingActionButton => null;
|
|
||||||
|
|
||||||
Function(String)? get onSearch => null;
|
|
||||||
|
|
||||||
Function(List<String>)? get onKeywordsUpdate => null;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
|
import 'package:fl_clash/providers/providers.dart';
|
||||||
import 'package:fl_clash/views/views.dart';
|
import 'package:fl_clash/views/views.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
class Navigation {
|
class Navigation {
|
||||||
static Navigation? _instance;
|
static Navigation? _instance;
|
||||||
@@ -11,62 +13,69 @@ class Navigation {
|
|||||||
bool hasProxies = false,
|
bool hasProxies = false,
|
||||||
}) {
|
}) {
|
||||||
return [
|
return [
|
||||||
const NavigationItem(
|
NavigationItem(
|
||||||
keep: false,
|
keep: false,
|
||||||
icon: Icon(Icons.space_dashboard),
|
icon: Icon(Icons.space_dashboard),
|
||||||
label: PageLabel.dashboard,
|
label: PageLabel.dashboard,
|
||||||
view: DashboardView(
|
builder: (_) => const DashboardView(
|
||||||
key: GlobalObjectKey(PageLabel.dashboard),
|
key: GlobalObjectKey(PageLabel.dashboard),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
NavigationItem(
|
NavigationItem(
|
||||||
icon: const Icon(Icons.article),
|
icon: const Icon(Icons.article),
|
||||||
label: PageLabel.proxies,
|
label: PageLabel.proxies,
|
||||||
view: const ProxiesView(
|
builder: (_) => ProviderScope(
|
||||||
key: GlobalObjectKey(
|
overrides: [
|
||||||
PageLabel.proxies,
|
queryProvider.overrideWith(
|
||||||
|
() => Query(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: const ProxiesView(
|
||||||
|
key: GlobalObjectKey(
|
||||||
|
PageLabel.proxies,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
modes: hasProxies
|
modes: hasProxies
|
||||||
? [NavigationItemMode.mobile, NavigationItemMode.desktop]
|
? [NavigationItemMode.mobile, NavigationItemMode.desktop]
|
||||||
: [],
|
: [],
|
||||||
),
|
),
|
||||||
const NavigationItem(
|
NavigationItem(
|
||||||
icon: Icon(Icons.folder),
|
icon: Icon(Icons.folder),
|
||||||
label: PageLabel.profiles,
|
label: PageLabel.profiles,
|
||||||
view: ProfilesView(
|
builder: (_) => const ProfilesView(
|
||||||
key: GlobalObjectKey(
|
key: GlobalObjectKey(
|
||||||
PageLabel.profiles,
|
PageLabel.profiles,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const NavigationItem(
|
NavigationItem(
|
||||||
icon: Icon(Icons.view_timeline),
|
icon: Icon(Icons.view_timeline),
|
||||||
label: PageLabel.requests,
|
label: PageLabel.requests,
|
||||||
view: RequestsView(
|
builder: (_) => const RequestsView(
|
||||||
key: GlobalObjectKey(
|
key: GlobalObjectKey(
|
||||||
PageLabel.requests,
|
PageLabel.requests,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
description: "requestsDesc",
|
description: 'requestsDesc',
|
||||||
modes: [NavigationItemMode.desktop, NavigationItemMode.more],
|
modes: [NavigationItemMode.desktop, NavigationItemMode.more],
|
||||||
),
|
),
|
||||||
const NavigationItem(
|
NavigationItem(
|
||||||
icon: Icon(Icons.ballot),
|
icon: Icon(Icons.ballot),
|
||||||
label: PageLabel.connections,
|
label: PageLabel.connections,
|
||||||
view: ConnectionsView(
|
builder: (_) => const ConnectionsView(
|
||||||
key: GlobalObjectKey(
|
key: GlobalObjectKey(
|
||||||
PageLabel.connections,
|
PageLabel.connections,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
description: "connectionsDesc",
|
description: 'connectionsDesc',
|
||||||
modes: [NavigationItemMode.desktop, NavigationItemMode.more],
|
modes: [NavigationItemMode.desktop, NavigationItemMode.more],
|
||||||
),
|
),
|
||||||
const NavigationItem(
|
NavigationItem(
|
||||||
icon: Icon(Icons.storage),
|
icon: Icon(Icons.storage),
|
||||||
label: PageLabel.resources,
|
label: PageLabel.resources,
|
||||||
description: "resourcesDesc",
|
description: 'resourcesDesc',
|
||||||
view: ResourcesView(
|
builder: (_) => const ResourcesView(
|
||||||
key: GlobalObjectKey(
|
key: GlobalObjectKey(
|
||||||
PageLabel.resources,
|
PageLabel.resources,
|
||||||
),
|
),
|
||||||
@@ -76,20 +85,20 @@ class Navigation {
|
|||||||
NavigationItem(
|
NavigationItem(
|
||||||
icon: const Icon(Icons.adb),
|
icon: const Icon(Icons.adb),
|
||||||
label: PageLabel.logs,
|
label: PageLabel.logs,
|
||||||
view: const LogsView(
|
builder: (_) => const LogsView(
|
||||||
key: GlobalObjectKey(
|
key: GlobalObjectKey(
|
||||||
PageLabel.logs,
|
PageLabel.logs,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
description: "logsDesc",
|
description: 'logsDesc',
|
||||||
modes: openLogs
|
modes: openLogs
|
||||||
? [NavigationItemMode.desktop, NavigationItemMode.more]
|
? [NavigationItemMode.desktop, NavigationItemMode.more]
|
||||||
: [],
|
: [],
|
||||||
),
|
),
|
||||||
const NavigationItem(
|
NavigationItem(
|
||||||
icon: Icon(Icons.construction),
|
icon: Icon(Icons.construction),
|
||||||
label: PageLabel.tools,
|
label: PageLabel.tools,
|
||||||
view: ToolsView(
|
builder: (_) => const ToolsView(
|
||||||
key: GlobalObjectKey(
|
key: GlobalObjectKey(
|
||||||
PageLabel.tools,
|
PageLabel.tools,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:fl_clash/common/common.dart';
|
|||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:fl_clash/widgets/dialog.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class BaseNavigator {
|
class BaseNavigator {
|
||||||
@@ -21,20 +20,20 @@ class BaseNavigator {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<T?> modal<T>(BuildContext context, Widget child) async {
|
// static Future<T?> modal<T>(BuildContext context, Widget child) async {
|
||||||
if (globalState.appState.viewMode != ViewMode.mobile) {
|
// if (globalState.appState.viewMode != ViewMode.mobile) {
|
||||||
return await globalState.showCommonDialog<T>(
|
// return await globalState.showCommonDialog<T>(
|
||||||
child: CommonModal(
|
// child: CommonModal(
|
||||||
child: child,
|
// child: child,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
return await Navigator.of(context).push<T>(
|
// return await Navigator.of(context).push<T>(
|
||||||
CommonRoute(
|
// CommonRoute(
|
||||||
builder: (context) => child,
|
// builder: (context) => child,
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
class CommonDesktopRoute<T> extends PageRoute<T> {
|
class CommonDesktopRoute<T> extends PageRoute<T> {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
extension NumExt on num {
|
extension NumExt on num {
|
||||||
String fixed({decimals = 2}) {
|
String fixed({int decimals = 2}) {
|
||||||
String formatted = toStringAsFixed(decimals);
|
String formatted = toStringAsFixed(decimals);
|
||||||
if (formatted.contains('.')) {
|
if (formatted.contains('.')) {
|
||||||
formatted = formatted.replaceAll(RegExp(r'0*$'), '');
|
formatted = formatted.replaceAll(RegExp(r'0*$'), '');
|
||||||
@@ -20,7 +20,7 @@ extension NumExt on num {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension DoubleExt on double {
|
extension DoubleExt on double {
|
||||||
moreOrEqual(double value) {
|
bool moreOrEqual(double value) {
|
||||||
return this > value || (value - this).abs() < precisionErrorTolerance + 1;
|
return this > value || (value - this).abs() < precisionErrorTolerance + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ extension OffsetExt on Offset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension RectExt on Rect {
|
extension RectExt on Rect {
|
||||||
doRectIntersect(Rect rect) {
|
bool doRectIntersect(Rect rect) {
|
||||||
return left < rect.right &&
|
return left < rect.right &&
|
||||||
right > rect.left &&
|
right > rect.left &&
|
||||||
top < rect.bottom &&
|
top < rect.bottom &&
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import 'common.dart';
|
|||||||
|
|
||||||
extension PackageInfoExtension on PackageInfo {
|
extension PackageInfoExtension on PackageInfo {
|
||||||
String get ua => [
|
String get ua => [
|
||||||
"$appName/v$version",
|
'$appName/v$version',
|
||||||
"clash-verge",
|
'clash-verge',
|
||||||
"Platform/${Platform.operatingSystem}",
|
'Platform/${Platform.operatingSystem}',
|
||||||
].join(" ");
|
].join(' ');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class AppPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String get executableExtension {
|
String get executableExtension {
|
||||||
return Platform.isWindows ? ".exe" : "";
|
return system.isWindows ? '.exe' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
String get executableDirPath {
|
String get executableDirPath {
|
||||||
@@ -40,11 +40,11 @@ class AppPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String get corePath {
|
String get corePath {
|
||||||
return join(executableDirPath, "FlClashCore$executableExtension");
|
return join(executableDirPath, 'FlClashCore$executableExtension');
|
||||||
}
|
}
|
||||||
|
|
||||||
String get helperPath {
|
String get helperPath {
|
||||||
return join(executableDirPath, "$appHelperService$executableExtension");
|
return join(executableDirPath, '$appHelperService$executableExtension');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> get downloadDirPath async {
|
Future<String> get downloadDirPath async {
|
||||||
@@ -59,12 +59,12 @@ class AppPath {
|
|||||||
|
|
||||||
Future<String> get lockFilePath async {
|
Future<String> get lockFilePath async {
|
||||||
final directory = await dataDir.future;
|
final directory = await dataDir.future;
|
||||||
return join(directory.path, "FlClash.lock");
|
return join(directory.path, 'FlClash.lock');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> get sharedPreferencesPath async {
|
Future<String> get sharedPreferencesPath async {
|
||||||
final directory = await dataDir.future;
|
final directory = await dataDir.future;
|
||||||
return join(directory.path, "shared_preferences.json");
|
return join(directory.path, 'shared_preferences.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> get profilesPath async {
|
Future<String> get profilesPath async {
|
||||||
@@ -74,14 +74,14 @@ class AppPath {
|
|||||||
|
|
||||||
Future<String> getProfilePath(String id) async {
|
Future<String> getProfilePath(String id) async {
|
||||||
final directory = await profilesPath;
|
final directory = await profilesPath;
|
||||||
return join(directory, "$id.yaml");
|
return join(directory, '$id.yaml');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getProvidersDirPath(String id) async {
|
Future<String> getProvidersDirPath(String id) async {
|
||||||
final directory = await profilesPath;
|
final directory = await profilesPath;
|
||||||
return join(
|
return join(
|
||||||
directory,
|
directory,
|
||||||
"providers",
|
'providers',
|
||||||
id,
|
id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ class AppPath {
|
|||||||
final directory = await profilesPath;
|
final directory = await profilesPath;
|
||||||
return join(
|
return join(
|
||||||
directory,
|
directory,
|
||||||
"providers",
|
'providers',
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
url.toMd5(),
|
url.toMd5(),
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ class Picker {
|
|||||||
final path = await FilePicker.platform.saveFile(
|
final path = await FilePicker.platform.saveFile(
|
||||||
fileName: fileName,
|
fileName: fileName,
|
||||||
initialDirectory: await appPath.downloadDirPath,
|
initialDirectory: await appPath.downloadDirPath,
|
||||||
bytes: Platform.isAndroid ? bytes : null,
|
bytes: system.isAndroid ? bytes : null,
|
||||||
);
|
);
|
||||||
if (!Platform.isAndroid && path != null) {
|
if (!system.isAndroid && path != null) {
|
||||||
final file = await File(path).create(recursive: true);
|
final file = await File(path).create(recursive: true);
|
||||||
await file.writeAsBytes(bytes);
|
await file.writeAsBytes(bytes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,12 +49,12 @@ class Preferences {
|
|||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearClashConfig() async {
|
Future<void> clearClashConfig() async {
|
||||||
final preferences = await sharedPreferencesCompleter.future;
|
final preferences = await sharedPreferencesCompleter.future;
|
||||||
preferences?.remove(clashConfigKey);
|
preferences?.remove(clashConfigKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearPreferences() async {
|
Future<void> clearPreferences() async {
|
||||||
final sharedPreferencesIns = await sharedPreferencesCompleter.future;
|
final sharedPreferencesIns = await sharedPreferencesCompleter.future;
|
||||||
sharedPreferencesIns?.clear();
|
sharedPreferencesIns?.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ class CommonPrint {
|
|||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(String? text) {
|
void log(String? text) {
|
||||||
final payload = "[FlClash] $text";
|
final payload = '[APP] $text';
|
||||||
debugPrint(payload);
|
debugPrint(payload);
|
||||||
if (!globalState.isInit) {
|
if (!globalState.isInit) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ class Render {
|
|||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
active() {
|
void active() {
|
||||||
resume();
|
resume();
|
||||||
pause();
|
pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
pause() {
|
void pause() {
|
||||||
throttler.call(
|
throttler.call(
|
||||||
FunctionTag.renderPause,
|
FunctionTag.renderPause,
|
||||||
_pause,
|
_pause,
|
||||||
@@ -29,7 +29,7 @@ class Render {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
resume() {
|
void resume() {
|
||||||
throttler.cancel(FunctionTag.renderPause);
|
throttler.cancel(FunctionTag.renderPause);
|
||||||
_resume();
|
_resume();
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ class Render {
|
|||||||
_drawFrame = _dispatcher.onDrawFrame;
|
_drawFrame = _dispatcher.onDrawFrame;
|
||||||
_dispatcher.onBeginFrame = null;
|
_dispatcher.onBeginFrame = null;
|
||||||
_dispatcher.onDrawFrame = null;
|
_dispatcher.onDrawFrame = null;
|
||||||
commonPrint.log("pause");
|
commonPrint.log('pause');
|
||||||
}
|
}
|
||||||
|
|
||||||
void _resume() {
|
void _resume() {
|
||||||
@@ -50,7 +50,7 @@ class Render {
|
|||||||
_dispatcher.onBeginFrame = _beginFrame;
|
_dispatcher.onBeginFrame = _beginFrame;
|
||||||
_dispatcher.onDrawFrame = _drawFrame;
|
_dispatcher.onDrawFrame = _drawFrame;
|
||||||
_dispatcher.scheduleFrame();
|
_dispatcher.scheduleFrame();
|
||||||
commonPrint.log("resume");
|
commonPrint.log('resume');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Request {
|
|||||||
_dio = Dio(
|
_dio = Dio(
|
||||||
BaseOptions(
|
BaseOptions(
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": browserUa,
|
'User-Agent': browserUa,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -69,7 +69,7 @@ class Request {
|
|||||||
|
|
||||||
Future<Map<String, dynamic>?> checkForUpdate() async {
|
Future<Map<String, dynamic>?> checkForUpdate() async {
|
||||||
final response = await _dio.get(
|
final response = await _dio.get(
|
||||||
"https://api.github.com/repos/$repository/releases/latest",
|
'https://api.github.com/repos/$repository/releases/latest',
|
||||||
options: Options(
|
options: Options(
|
||||||
responseType: ResponseType.json,
|
responseType: ResponseType.json,
|
||||||
),
|
),
|
||||||
@@ -85,16 +85,22 @@ class Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Map<String, IpInfo Function(Map<String, dynamic>)> _ipInfoSources = {
|
final Map<String, IpInfo Function(Map<String, dynamic>)> _ipInfoSources = {
|
||||||
"https://ipwho.is/": IpInfo.fromIpwhoIsJson,
|
'https://ipwho.is/': IpInfo.fromIpwhoIsJson,
|
||||||
"https://api.ip.sb/geoip/": IpInfo.fromIpSbJson,
|
'https://api.ip.sb/geoip/': IpInfo.fromIpSbJson,
|
||||||
"https://ipapi.co/json/": IpInfo.fromIpApiCoJson,
|
'https://ipapi.co/json/': IpInfo.fromIpApiCoJson,
|
||||||
"https://ipinfo.io/json/": IpInfo.fromIpInfoIoJson,
|
'https://ipinfo.io/json/': IpInfo.fromIpInfoIoJson,
|
||||||
};
|
};
|
||||||
|
|
||||||
Future<Result<IpInfo?>> checkIp({CancelToken? cancelToken}) async {
|
Future<Result<IpInfo?>> checkIp({CancelToken? cancelToken}) async {
|
||||||
var failureCount = 0;
|
var failureCount = 0;
|
||||||
final futures = _ipInfoSources.entries.map((source) async {
|
final futures = _ipInfoSources.entries.map((source) async {
|
||||||
final Completer<Result<IpInfo?>> completer = Completer();
|
final Completer<Result<IpInfo?>> completer = Completer();
|
||||||
|
handleFailRes() {
|
||||||
|
if (!completer.isCompleted && failureCount == _ipInfoSources.length) {
|
||||||
|
completer.complete(Result.success(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final future = Dio().get<Map<String, dynamic>>(
|
final future = Dio().get<Map<String, dynamic>>(
|
||||||
source.key,
|
source.key,
|
||||||
cancelToken: cancelToken,
|
cancelToken: cancelToken,
|
||||||
@@ -107,15 +113,14 @@ class Request {
|
|||||||
completer.complete(Result.success(source.value(res.data!)));
|
completer.complete(Result.success(source.value(res.data!)));
|
||||||
} else {
|
} else {
|
||||||
failureCount++;
|
failureCount++;
|
||||||
if (failureCount == _ipInfoSources.length) {
|
handleFailRes();
|
||||||
completer.complete(Result.success(null));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
failureCount++;
|
failureCount++;
|
||||||
if (e == DioExceptionType.cancel) {
|
if (e == DioExceptionType.cancel) {
|
||||||
completer.complete(Result.error("cancelled"));
|
completer.complete(Result.error('cancelled'));
|
||||||
}
|
}
|
||||||
|
handleFailRes();
|
||||||
});
|
});
|
||||||
return completer.future;
|
return completer.future;
|
||||||
});
|
});
|
||||||
@@ -128,7 +133,7 @@ class Request {
|
|||||||
try {
|
try {
|
||||||
final response = await _dio
|
final response = await _dio
|
||||||
.get(
|
.get(
|
||||||
"http://$localhost:$helperPort/ping",
|
'http://$localhost:$helperPort/ping',
|
||||||
options: Options(
|
options: Options(
|
||||||
responseType: ResponseType.plain,
|
responseType: ResponseType.plain,
|
||||||
),
|
),
|
||||||
@@ -151,10 +156,10 @@ class Request {
|
|||||||
try {
|
try {
|
||||||
final response = await _dio
|
final response = await _dio
|
||||||
.post(
|
.post(
|
||||||
"http://$localhost:$helperPort/start",
|
'http://$localhost:$helperPort/start',
|
||||||
data: json.encode({
|
data: json.encode({
|
||||||
"path": appPath.corePath,
|
'path': appPath.corePath,
|
||||||
"arg": arg,
|
'arg': arg,
|
||||||
}),
|
}),
|
||||||
options: Options(
|
options: Options(
|
||||||
responseType: ResponseType.plain,
|
responseType: ResponseType.plain,
|
||||||
@@ -179,7 +184,7 @@ class Request {
|
|||||||
try {
|
try {
|
||||||
final response = await _dio
|
final response = await _dio
|
||||||
.post(
|
.post(
|
||||||
"http://$localhost:$helperPort/stop",
|
'http://$localhost:$helperPort/stop',
|
||||||
options: Options(
|
options: Options(
|
||||||
responseType: ResponseType.plain,
|
responseType: ResponseType.plain,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class ShowBarScrollBehavior extends BaseScrollBehavior {
|
|||||||
Widget child,
|
Widget child,
|
||||||
ScrollableDetails details,
|
ScrollableDetails details,
|
||||||
) {
|
) {
|
||||||
return CommonAutoHiddenScrollBar(
|
return CommonScrollBar(
|
||||||
controller: details.controller,
|
controller: details.controller,
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
@@ -88,6 +88,54 @@ class NextClampingScrollPhysics extends ClampingScrollPhysics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// class CacheScrollPositionController extends ScrollController {
|
||||||
|
// final String key;
|
||||||
|
//
|
||||||
|
// CacheScrollPositionController({
|
||||||
|
// required this.key,
|
||||||
|
// double initialScrollOffset = 0.0,
|
||||||
|
// super.keepScrollOffset = true,
|
||||||
|
// super.debugLabel,
|
||||||
|
// super.onAttach,
|
||||||
|
// super.onDetach,
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// ScrollPosition createScrollPosition(
|
||||||
|
// ScrollPhysics physics,
|
||||||
|
// ScrollContext context,
|
||||||
|
// ScrollPosition? oldPosition,
|
||||||
|
// ) {
|
||||||
|
// return ScrollPositionWithSingleContext(
|
||||||
|
// physics: physics,
|
||||||
|
// context: context,
|
||||||
|
// initialPixels:
|
||||||
|
// globalState.scrollPositionCache[key] ?? initialScrollOffset,
|
||||||
|
// keepScrollOffset: keepScrollOffset,
|
||||||
|
// oldPosition: oldPosition,
|
||||||
|
// debugLabel: debugLabel,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// double? get cacheOffset => globalState.scrollPositionCache[key];
|
||||||
|
//
|
||||||
|
// _handleScroll() {
|
||||||
|
// globalState.scrollPositionCache[key] = position.pixels;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void attach(ScrollPosition position) {
|
||||||
|
// super.attach(position);
|
||||||
|
// addListener(_handleScroll);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void detach(ScrollPosition position) {
|
||||||
|
// removeListener(_handleScroll);
|
||||||
|
// super.detach(position);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
class ReverseScrollController extends ScrollController {
|
class ReverseScrollController extends ScrollController {
|
||||||
ReverseScrollController({
|
ReverseScrollController({
|
||||||
super.initialScrollOffset,
|
super.initialScrollOffset,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ extension StringExtension on String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool get isSvg {
|
bool get isSvg {
|
||||||
return endsWith(".svg");
|
return endsWith('.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isRegex {
|
bool get isRegex {
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/plugins/app.dart';
|
import 'package:fl_clash/plugins/app.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:fl_clash/widgets/input.dart';
|
import 'package:fl_clash/widgets/input.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
class System {
|
class System {
|
||||||
static System? _instance;
|
static System? _instance;
|
||||||
List<String>? originDns;
|
|
||||||
|
|
||||||
System._internal();
|
System._internal();
|
||||||
|
|
||||||
@@ -19,25 +21,32 @@ class System {
|
|||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isDesktop =>
|
bool get isDesktop => isWindows || isMacOS || isLinux;
|
||||||
Platform.isWindows || Platform.isMacOS || Platform.isLinux;
|
|
||||||
|
bool get isWindows => Platform.isWindows;
|
||||||
|
|
||||||
|
bool get isMacOS => Platform.isMacOS;
|
||||||
|
|
||||||
|
bool get isAndroid => Platform.isAndroid;
|
||||||
|
|
||||||
|
bool get isLinux => Platform.isLinux;
|
||||||
|
|
||||||
Future<int> get version async {
|
Future<int> get version async {
|
||||||
final deviceInfo = await DeviceInfoPlugin().deviceInfo;
|
final deviceInfo = await DeviceInfoPlugin().deviceInfo;
|
||||||
return switch (Platform.operatingSystem) {
|
return switch (Platform.operatingSystem) {
|
||||||
"macos" => (deviceInfo as MacOsDeviceInfo).majorVersion,
|
'macos' => (deviceInfo as MacOsDeviceInfo).majorVersion,
|
||||||
"android" => (deviceInfo as AndroidDeviceInfo).version.sdkInt,
|
'android' => (deviceInfo as AndroidDeviceInfo).version.sdkInt,
|
||||||
"windows" => (deviceInfo as WindowsDeviceInfo).majorVersion,
|
'windows' => (deviceInfo as WindowsDeviceInfo).majorVersion,
|
||||||
String() => 0
|
String() => 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> checkIsAdmin() async {
|
Future<bool> checkIsAdmin() async {
|
||||||
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
|
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
|
||||||
if (Platform.isWindows) {
|
if (system.isWindows) {
|
||||||
final result = await windows?.checkService();
|
final result = await windows?.checkService();
|
||||||
return result == WindowsHelperServiceStatus.running;
|
return result == WindowsHelperServiceStatus.running;
|
||||||
} else if (Platform.isMacOS) {
|
} else if (system.isMacOS) {
|
||||||
final result = await Process.run('stat', ['-f', '%Su:%Sg %Sp', corePath]);
|
final result = await Process.run('stat', ['-f', '%Su:%Sg %Sp', corePath]);
|
||||||
final output = result.stdout.trim();
|
final output = result.stdout.trim();
|
||||||
if (output.startsWith('root:admin') && output.contains('rws')) {
|
if (output.startsWith('root:admin') && output.contains('rws')) {
|
||||||
@@ -56,7 +65,7 @@ class System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<AuthorizeCode> authorizeCore() async {
|
Future<AuthorizeCode> authorizeCore() async {
|
||||||
if (Platform.isAndroid) {
|
if (system.isAndroid) {
|
||||||
return AuthorizeCode.error;
|
return AuthorizeCode.error;
|
||||||
}
|
}
|
||||||
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
|
final corePath = appPath.corePath.replaceAll(' ', '\\\\ ');
|
||||||
@@ -65,7 +74,7 @@ class System {
|
|||||||
return AuthorizeCode.none;
|
return AuthorizeCode.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.isWindows) {
|
if (system.isWindows) {
|
||||||
final result = await windows?.registerService();
|
final result = await windows?.registerService();
|
||||||
if (result == true) {
|
if (result == true) {
|
||||||
return AuthorizeCode.success;
|
return AuthorizeCode.success;
|
||||||
@@ -73,13 +82,13 @@ class System {
|
|||||||
return AuthorizeCode.error;
|
return AuthorizeCode.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.isMacOS) {
|
if (system.isMacOS) {
|
||||||
final shell = 'chown root:admin $corePath; chmod +sx $corePath';
|
final shell = 'chown root:admin $corePath; chmod +sx $corePath';
|
||||||
final arguments = [
|
final arguments = [
|
||||||
"-e",
|
'-e',
|
||||||
'do shell script "$shell" with administrator privileges',
|
'do shell script "$shell" with administrator privileges',
|
||||||
];
|
];
|
||||||
final result = await Process.run("osascript", arguments);
|
final result = await Process.run('osascript', arguments);
|
||||||
if (result.exitCode != 0) {
|
if (result.exitCode != 0) {
|
||||||
return AuthorizeCode.error;
|
return AuthorizeCode.error;
|
||||||
}
|
}
|
||||||
@@ -93,7 +102,7 @@ class System {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
final arguments = [
|
final arguments = [
|
||||||
"-c",
|
'-c',
|
||||||
'echo "$password" | sudo -S chown root:root "$corePath" && echo "$password" | sudo -S chmod +sx "$corePath"'
|
'echo "$password" | sudo -S chown root:root "$corePath" && echo "$password" | sudo -S chmod +sx "$corePath"'
|
||||||
];
|
];
|
||||||
final result = await Process.run(shell, arguments);
|
final result = await Process.run(shell, arguments);
|
||||||
@@ -105,15 +114,223 @@ class System {
|
|||||||
return AuthorizeCode.error;
|
return AuthorizeCode.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getMacOSDefaultServiceName() async {
|
Future<void> back() async {
|
||||||
if (!Platform.isMacOS) {
|
await app?.moveTaskToBack();
|
||||||
return null;
|
await window?.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> exit() async {
|
||||||
|
if (system.isAndroid) {
|
||||||
|
await SystemNavigator.pop();
|
||||||
}
|
}
|
||||||
|
await window?.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final system = System();
|
||||||
|
|
||||||
|
class Windows {
|
||||||
|
static Windows? _instance;
|
||||||
|
late DynamicLibrary _shell32;
|
||||||
|
|
||||||
|
Windows._internal() {
|
||||||
|
_shell32 = DynamicLibrary.open('shell32.dll');
|
||||||
|
}
|
||||||
|
|
||||||
|
factory Windows() {
|
||||||
|
_instance ??= Windows._internal();
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runas(String command, String arguments) {
|
||||||
|
final commandPtr = command.toNativeUtf16();
|
||||||
|
final argumentsPtr = arguments.toNativeUtf16();
|
||||||
|
final operationPtr = 'runas'.toNativeUtf16();
|
||||||
|
|
||||||
|
final shellExecute = _shell32.lookupFunction<
|
||||||
|
Int32 Function(
|
||||||
|
Pointer<Utf16> hwnd,
|
||||||
|
Pointer<Utf16> lpOperation,
|
||||||
|
Pointer<Utf16> lpFile,
|
||||||
|
Pointer<Utf16> lpParameters,
|
||||||
|
Pointer<Utf16> lpDirectory,
|
||||||
|
Int32 nShowCmd),
|
||||||
|
int Function(
|
||||||
|
Pointer<Utf16> hwnd,
|
||||||
|
Pointer<Utf16> lpOperation,
|
||||||
|
Pointer<Utf16> lpFile,
|
||||||
|
Pointer<Utf16> lpParameters,
|
||||||
|
Pointer<Utf16> lpDirectory,
|
||||||
|
int nShowCmd)>('ShellExecuteW');
|
||||||
|
|
||||||
|
final result = shellExecute(
|
||||||
|
nullptr,
|
||||||
|
operationPtr,
|
||||||
|
commandPtr,
|
||||||
|
argumentsPtr,
|
||||||
|
nullptr,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
calloc.free(commandPtr);
|
||||||
|
calloc.free(argumentsPtr);
|
||||||
|
calloc.free(operationPtr);
|
||||||
|
|
||||||
|
commonPrint.log('windows runas: $command $arguments resultCode:$result');
|
||||||
|
|
||||||
|
if (result < 42) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _killProcess(int port) async {
|
||||||
|
final result = await Process.run('netstat', ['-ano']);
|
||||||
|
final lines = result.stdout.toString().trim().split('\n');
|
||||||
|
for (final line in lines) {
|
||||||
|
if (!line.contains(':$port') || !line.contains('LISTENING')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final parts = line.trim().split(RegExp(r'\s+'));
|
||||||
|
final pid = int.tryParse(parts.last);
|
||||||
|
if (pid != null) {
|
||||||
|
await Process.run('taskkill', ['/PID', pid.toString(), '/F']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<WindowsHelperServiceStatus> checkService() async {
|
||||||
|
// final qcResult = await Process.run('sc', ['qc', appHelperService]);
|
||||||
|
// final qcOutput = qcResult.stdout.toString();
|
||||||
|
// if (qcResult.exitCode != 0 || !qcOutput.contains(appPath.helperPath)) {
|
||||||
|
// return WindowsHelperServiceStatus.none;
|
||||||
|
// }
|
||||||
|
final result = await Process.run('sc', ['query', appHelperService]);
|
||||||
|
if (result.exitCode != 0) {
|
||||||
|
return WindowsHelperServiceStatus.none;
|
||||||
|
}
|
||||||
|
final output = result.stdout.toString();
|
||||||
|
if (output.contains('RUNNING') && await request.pingHelper()) {
|
||||||
|
return WindowsHelperServiceStatus.running;
|
||||||
|
}
|
||||||
|
return WindowsHelperServiceStatus.presence;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> registerService() async {
|
||||||
|
final status = await checkService();
|
||||||
|
|
||||||
|
if (status == WindowsHelperServiceStatus.running) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _killProcess(helperPort);
|
||||||
|
|
||||||
|
final command = [
|
||||||
|
'/c',
|
||||||
|
if (status == WindowsHelperServiceStatus.presence) ...[
|
||||||
|
'sc',
|
||||||
|
'delete',
|
||||||
|
appHelperService,
|
||||||
|
'/force',
|
||||||
|
'&&',
|
||||||
|
],
|
||||||
|
'sc',
|
||||||
|
'create',
|
||||||
|
appHelperService,
|
||||||
|
'binPath= "${appPath.helperPath}"',
|
||||||
|
'start= auto',
|
||||||
|
'&&',
|
||||||
|
'sc',
|
||||||
|
'start',
|
||||||
|
appHelperService,
|
||||||
|
].join(' ');
|
||||||
|
|
||||||
|
final res = runas('cmd.exe', command);
|
||||||
|
|
||||||
|
await Future.delayed(
|
||||||
|
Duration(milliseconds: 300),
|
||||||
|
);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> registerTask(String appName) async {
|
||||||
|
final taskXml = '''
|
||||||
|
<?xml version="1.0" encoding="UTF-16"?>
|
||||||
|
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
||||||
|
<Principals>
|
||||||
|
<Principal id="Author">
|
||||||
|
<LogonType>InteractiveToken</LogonType>
|
||||||
|
<RunLevel>HighestAvailable</RunLevel>
|
||||||
|
</Principal>
|
||||||
|
</Principals>
|
||||||
|
<Triggers>
|
||||||
|
<LogonTrigger/>
|
||||||
|
</Triggers>
|
||||||
|
<Settings>
|
||||||
|
<MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
|
||||||
|
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
||||||
|
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
||||||
|
<AllowHardTerminate>false</AllowHardTerminate>
|
||||||
|
<StartWhenAvailable>false</StartWhenAvailable>
|
||||||
|
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
||||||
|
<IdleSettings>
|
||||||
|
<StopOnIdleEnd>false</StopOnIdleEnd>
|
||||||
|
<RestartOnIdle>false</RestartOnIdle>
|
||||||
|
</IdleSettings>
|
||||||
|
<AllowStartOnDemand>true</AllowStartOnDemand>
|
||||||
|
<Enabled>true</Enabled>
|
||||||
|
<Hidden>false</Hidden>
|
||||||
|
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
||||||
|
<WakeToRun>false</WakeToRun>
|
||||||
|
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
|
||||||
|
<Priority>7</Priority>
|
||||||
|
</Settings>
|
||||||
|
<Actions Context="Author">
|
||||||
|
<Exec>
|
||||||
|
<Command>"${Platform.resolvedExecutable}"</Command>
|
||||||
|
</Exec>
|
||||||
|
</Actions>
|
||||||
|
</Task>''';
|
||||||
|
final taskPath = join(await appPath.tempPath, 'task.xml');
|
||||||
|
await File(taskPath).create(recursive: true);
|
||||||
|
await File(taskPath)
|
||||||
|
.writeAsBytes(taskXml.encodeUtf16LeWithBom, flush: true);
|
||||||
|
final commandLine = [
|
||||||
|
'/Create',
|
||||||
|
'/TN',
|
||||||
|
appName,
|
||||||
|
'/XML',
|
||||||
|
'%s',
|
||||||
|
'/F',
|
||||||
|
].join(' ');
|
||||||
|
return runas(
|
||||||
|
'schtasks',
|
||||||
|
commandLine.replaceFirst('%s', taskPath),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final windows = system.isWindows ? Windows() : null;
|
||||||
|
|
||||||
|
class MacOS {
|
||||||
|
static MacOS? _instance;
|
||||||
|
|
||||||
|
List<String>? originDns;
|
||||||
|
|
||||||
|
MacOS._internal();
|
||||||
|
|
||||||
|
factory MacOS() {
|
||||||
|
_instance ??= MacOS._internal();
|
||||||
|
return _instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String?> get defaultServiceName async {
|
||||||
final result = await Process.run('route', ['-n', 'get', 'default']);
|
final result = await Process.run('route', ['-n', 'get', 'default']);
|
||||||
final output = result.stdout.toString();
|
final output = result.stdout.toString();
|
||||||
final deviceLine = output
|
final deviceLine = output
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.firstWhere((s) => s.contains('interface:'), orElse: () => "");
|
.firstWhere((s) => s.contains('interface:'), orElse: () => '');
|
||||||
final lineSplits = deviceLine.trim().split(' ');
|
final lineSplits = deviceLine.trim().split(' ');
|
||||||
if (lineSplits.length != 2) {
|
if (lineSplits.length != 2) {
|
||||||
return null;
|
return null;
|
||||||
@@ -125,15 +342,15 @@ class System {
|
|||||||
);
|
);
|
||||||
final serviceResultOutput = serviceResult.stdout.toString();
|
final serviceResultOutput = serviceResult.stdout.toString();
|
||||||
final currentService = serviceResultOutput.split('\n\n').firstWhere(
|
final currentService = serviceResultOutput.split('\n\n').firstWhere(
|
||||||
(s) => s.contains("Device: $device"),
|
(s) => s.contains('Device: $device'),
|
||||||
orElse: () => "",
|
orElse: () => '',
|
||||||
);
|
);
|
||||||
if (currentService.isEmpty) {
|
if (currentService.isEmpty) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final currentServiceNameLine = currentService.split("\n").firstWhere(
|
final currentServiceNameLine = currentService.split('\n').firstWhere(
|
||||||
(line) => RegExp(r'^\(\d+\).*').hasMatch(line),
|
(line) => RegExp(r'^\(\d+\).*').hasMatch(line),
|
||||||
orElse: () => "");
|
orElse: () => '');
|
||||||
final currentServiceNameLineSplits =
|
final currentServiceNameLineSplits =
|
||||||
currentServiceNameLine.trim().split(' ');
|
currentServiceNameLine.trim().split(' ');
|
||||||
if (currentServiceNameLineSplits.length < 2) {
|
if (currentServiceNameLineSplits.length < 2) {
|
||||||
@@ -142,11 +359,8 @@ class System {
|
|||||||
return currentServiceNameLineSplits[1];
|
return currentServiceNameLineSplits[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<String>?> getMacOSOriginDns() async {
|
Future<List<String>?> get systemDns async {
|
||||||
if (!Platform.isMacOS) {
|
final deviceServiceName = await defaultServiceName;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final deviceServiceName = await getMacOSDefaultServiceName();
|
|
||||||
if (deviceServiceName == null) {
|
if (deviceServiceName == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -158,16 +372,13 @@ class System {
|
|||||||
if (output.startsWith("There aren't any DNS Servers set on")) {
|
if (output.startsWith("There aren't any DNS Servers set on")) {
|
||||||
originDns = [];
|
originDns = [];
|
||||||
} else {
|
} else {
|
||||||
originDns = output.split("\n");
|
originDns = output.split('\n');
|
||||||
}
|
}
|
||||||
return originDns;
|
return originDns;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMacOSDns(bool restore) async {
|
Future<void> updateDns(bool restore) async {
|
||||||
if (!Platform.isMacOS) {
|
final serviceName = await defaultServiceName;
|
||||||
return;
|
|
||||||
}
|
|
||||||
final serviceName = await getMacOSDefaultServiceName();
|
|
||||||
if (serviceName == null) {
|
if (serviceName == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -175,11 +386,11 @@ class System {
|
|||||||
if (restore) {
|
if (restore) {
|
||||||
nextDns = originDns;
|
nextDns = originDns;
|
||||||
} else {
|
} else {
|
||||||
final originDns = await system.getMacOSOriginDns();
|
final originDns = await systemDns;
|
||||||
if (originDns == null) {
|
if (originDns == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final needAddDns = "223.5.5.5";
|
final needAddDns = '223.5.5.5';
|
||||||
if (originDns.contains(needAddDns)) {
|
if (originDns.contains(needAddDns)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -194,22 +405,10 @@ class System {
|
|||||||
'-setdnsservers',
|
'-setdnsservers',
|
||||||
serviceName,
|
serviceName,
|
||||||
if (nextDns.isNotEmpty) ...nextDns,
|
if (nextDns.isNotEmpty) ...nextDns,
|
||||||
if (nextDns.isEmpty) "Empty",
|
if (nextDns.isEmpty) 'Empty',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
back() async {
|
|
||||||
await app?.moveTaskToBack();
|
|
||||||
await window?.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
exit() async {
|
|
||||||
if (Platform.isAndroid) {
|
|
||||||
await SystemNavigator.pop();
|
|
||||||
}
|
|
||||||
await window?.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final system = System();
|
final macOS = system.isMacOS ? MacOS() : null;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class CommonTheme {
|
|||||||
|
|
||||||
Color get darkenSecondaryContainer {
|
Color get darkenSecondaryContainer {
|
||||||
return _colorMap.updateCacheValue(
|
return _colorMap.updateCacheValue(
|
||||||
"darkenSecondaryContainer",
|
'darkenSecondaryContainer',
|
||||||
() => context.colorScheme.secondaryContainer
|
() => context.colorScheme.secondaryContainer
|
||||||
.blendDarken(context, factor: 0.1),
|
.blendDarken(context, factor: 0.1),
|
||||||
);
|
);
|
||||||
@@ -21,7 +21,7 @@ class CommonTheme {
|
|||||||
|
|
||||||
Color get darkenSecondaryContainerLighter {
|
Color get darkenSecondaryContainerLighter {
|
||||||
return _colorMap.updateCacheValue(
|
return _colorMap.updateCacheValue(
|
||||||
"darkenSecondaryContainerLighter",
|
'darkenSecondaryContainerLighter',
|
||||||
() => context.colorScheme.secondaryContainer
|
() => context.colorScheme.secondaryContainer
|
||||||
.blendDarken(context, factor: 0.1)
|
.blendDarken(context, factor: 0.1)
|
||||||
.opacity60,
|
.opacity60,
|
||||||
@@ -30,7 +30,7 @@ class CommonTheme {
|
|||||||
|
|
||||||
Color get darken2SecondaryContainer {
|
Color get darken2SecondaryContainer {
|
||||||
return _colorMap.updateCacheValue(
|
return _colorMap.updateCacheValue(
|
||||||
"darken2SecondaryContainer",
|
'darken2SecondaryContainer',
|
||||||
() => context.colorScheme.secondaryContainer
|
() => context.colorScheme.secondaryContainer
|
||||||
.blendDarken(context, factor: 0.2),
|
.blendDarken(context, factor: 0.2),
|
||||||
);
|
);
|
||||||
@@ -38,7 +38,7 @@ class CommonTheme {
|
|||||||
|
|
||||||
Color get darken3PrimaryContainer {
|
Color get darken3PrimaryContainer {
|
||||||
return _colorMap.updateCacheValue(
|
return _colorMap.updateCacheValue(
|
||||||
"darken3PrimaryContainer",
|
'darken3PrimaryContainer',
|
||||||
() => context.colorScheme.primaryContainer
|
() => context.colorScheme.primaryContainer
|
||||||
.blendDarken(context, factor: 0.3),
|
.blendDarken(context, factor: 0.3),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:tray_manager/tray_manager.dart';
|
|||||||
|
|
||||||
import 'app_localizations.dart';
|
import 'app_localizations.dart';
|
||||||
import 'constant.dart';
|
import 'constant.dart';
|
||||||
|
import 'system.dart';
|
||||||
import 'window.dart';
|
import 'window.dart';
|
||||||
|
|
||||||
class Tray {
|
class Tray {
|
||||||
@@ -18,7 +19,7 @@ class Tray {
|
|||||||
required Brightness? brightness,
|
required Brightness? brightness,
|
||||||
bool force = false,
|
bool force = false,
|
||||||
}) async {
|
}) async {
|
||||||
if (Platform.isAndroid) {
|
if (system.isAndroid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Platform.isLinux || force) {
|
if (Platform.isLinux || force) {
|
||||||
@@ -38,11 +39,11 @@ class Tray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update({
|
Future<void> update({
|
||||||
required TrayState trayState,
|
required TrayState trayState,
|
||||||
bool focus = false,
|
bool focus = false,
|
||||||
}) async {
|
}) async {
|
||||||
if (Platform.isAndroid) {
|
if (system.isAndroid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
@@ -80,7 +81,7 @@ class Tray {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
menuItems.add(MenuItem.separator());
|
menuItems.add(MenuItem.separator());
|
||||||
if (Platform.isMacOS) {
|
if (system.isMacOS) {
|
||||||
for (final group in trayState.groups) {
|
for (final group in trayState.groups) {
|
||||||
List<MenuItem> subMenuItems = [];
|
List<MenuItem> subMenuItems = [];
|
||||||
for (final proxy in group.all) {
|
for (final proxy in group.all) {
|
||||||
@@ -169,8 +170,8 @@ class Tray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTrayTitle([Traffic? traffic]) async {
|
Future<void> updateTrayTitle([Traffic? traffic]) async {
|
||||||
// if (!Platform.isMacOS) {
|
// if (!system.isMacOS) {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
// if (traffic == null) {
|
// if (traffic == null) {
|
||||||
@@ -183,11 +184,10 @@ class Tray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _copyEnv(int port) async {
|
Future<void> _copyEnv(int port) async {
|
||||||
final url = "http://127.0.0.1:$port";
|
final url = 'http://127.0.0.1:$port';
|
||||||
|
|
||||||
final cmdline = Platform.isWindows
|
final cmdline =
|
||||||
? "set \$env:all_proxy=$url"
|
system.isWindows ? 'set \$env:all_proxy=$url' : 'export all_proxy=$url';
|
||||||
: "export all_proxy=$url";
|
|
||||||
|
|
||||||
await Clipboard.setData(
|
await Clipboard.setData(
|
||||||
ClipboardData(
|
ClipboardData(
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ class Utils {
|
|||||||
final random = Random();
|
final random = Random();
|
||||||
final randomStr =
|
final randomStr =
|
||||||
String.fromCharCodes(List.generate(8, (_) => random.nextInt(26) + 97));
|
String.fromCharCodes(List.generate(8, (_) => random.nextInt(26) + 97));
|
||||||
return "$timestamp$randomStr";
|
return '$timestamp$randomStr';
|
||||||
}
|
}
|
||||||
|
|
||||||
String getDateStringLast2(int value) {
|
String getDateStringLast2(int value) {
|
||||||
var valueRaw = "0$value";
|
var valueRaw = '0$value';
|
||||||
return valueRaw.substring(
|
return valueRaw.substring(
|
||||||
valueRaw.length - 2,
|
valueRaw.length - 2,
|
||||||
);
|
);
|
||||||
@@ -73,7 +73,7 @@ class Utils {
|
|||||||
var inMinutes = difference.inMinutes;
|
var inMinutes = difference.inMinutes;
|
||||||
var inSeconds = difference.inSeconds;
|
var inSeconds = difference.inSeconds;
|
||||||
|
|
||||||
return "${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}";
|
return '${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}';
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTimeText(int? timeStamp) {
|
String getTimeText(int? timeStamp) {
|
||||||
@@ -83,17 +83,17 @@ class Utils {
|
|||||||
final diff = timeStamp / 1000;
|
final diff = timeStamp / 1000;
|
||||||
final inHours = (diff / 3600).floor();
|
final inHours = (diff / 3600).floor();
|
||||||
if (inHours > 99) {
|
if (inHours > 99) {
|
||||||
return "99:59:59";
|
return '99:59:59';
|
||||||
}
|
}
|
||||||
final inMinutes = (diff / 60 % 60).floor();
|
final inMinutes = (diff / 60 % 60).floor();
|
||||||
final inSeconds = (diff % 60).floor();
|
final inSeconds = (diff % 60).floor();
|
||||||
|
|
||||||
return "${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}";
|
return '${getDateStringLast2(inHours)}:${getDateStringLast2(inMinutes)}:${getDateStringLast2(inSeconds)}';
|
||||||
}
|
}
|
||||||
|
|
||||||
Locale? getLocaleForString(String? localString) {
|
Locale? getLocaleForString(String? localString) {
|
||||||
if (localString == null) return null;
|
if (localString == null) return null;
|
||||||
var localSplit = localString.split("_");
|
var localSplit = localString.split('_');
|
||||||
if (localSplit.length == 1) {
|
if (localSplit.length == 1) {
|
||||||
return Locale(localSplit[0]);
|
return Locale(localSplit[0]);
|
||||||
}
|
}
|
||||||
@@ -137,18 +137,18 @@ class Utils {
|
|||||||
final number = int.parse(match[1] ?? '0') + 1;
|
final number = int.parse(match[1] ?? '0') + 1;
|
||||||
return label.replaceFirst(reg, '($number)', label.length - 3 - 1);
|
return label.replaceFirst(reg, '($number)', label.length - 3 - 1);
|
||||||
} else {
|
} else {
|
||||||
return "$label(1)";
|
return '$label(1)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTrayIconPath({
|
String getTrayIconPath({
|
||||||
required Brightness brightness,
|
required Brightness brightness,
|
||||||
}) {
|
}) {
|
||||||
if (Platform.isMacOS) {
|
if (system.isMacOS) {
|
||||||
return "assets/images/icon_white.png";
|
return 'assets/images/icon_white.png';
|
||||||
}
|
}
|
||||||
final suffix = Platform.isWindows ? "ico" : "png";
|
final suffix = system.isWindows ? 'ico' : 'png';
|
||||||
return "assets/images/icon.$suffix";
|
return 'assets/images/icon.$suffix';
|
||||||
// return switch (brightness) {
|
// return switch (brightness) {
|
||||||
// Brightness.dark => "assets/images/icon_white.$suffix",
|
// Brightness.dark => "assets/images/icon_white.$suffix",
|
||||||
// Brightness.light => "assets/images/icon_black.$suffix",
|
// Brightness.light => "assets/images/icon_black.$suffix",
|
||||||
@@ -181,7 +181,7 @@ class Utils {
|
|||||||
String getPinyin(String value) {
|
String getPinyin(String value) {
|
||||||
return value.isNotEmpty
|
return value.isNotEmpty
|
||||||
? PinyinHelper.getFirstWordPinyin(value.substring(0, 1))
|
? PinyinHelper.getFirstWordPinyin(value.substring(0, 1))
|
||||||
: "";
|
: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getFileNameForDisposition(String? disposition) {
|
String? getFileNameForDisposition(String? disposition) {
|
||||||
@@ -189,7 +189,7 @@ class Utils {
|
|||||||
final parseValue = HeaderValue.parse(disposition);
|
final parseValue = HeaderValue.parse(disposition);
|
||||||
final parameters = parseValue.parameters;
|
final parameters = parseValue.parameters;
|
||||||
final fileNamePointKey = parameters.keys
|
final fileNamePointKey = parameters.keys
|
||||||
.firstWhere((key) => key == "filename*", orElse: () => "");
|
.firstWhere((key) => key == 'filename*', orElse: () => '');
|
||||||
if (fileNamePointKey.isNotEmpty) {
|
if (fileNamePointKey.isNotEmpty) {
|
||||||
final res = parameters[fileNamePointKey]?.split("''") ?? [];
|
final res = parameters[fileNamePointKey]?.split("''") ?? [];
|
||||||
if (res.length >= 2) {
|
if (res.length >= 2) {
|
||||||
@@ -197,7 +197,7 @@ class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final fileNameKey = parameters.keys
|
final fileNameKey = parameters.keys
|
||||||
.firstWhere((key) => key == "filename", orElse: () => "");
|
.firstWhere((key) => key == 'filename', orElse: () => '');
|
||||||
if (fileNameKey.isEmpty) return null;
|
if (fileNameKey.isEmpty) return null;
|
||||||
return parameters[fileNameKey];
|
return parameters[fileNameKey];
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ class Utils {
|
|||||||
900,
|
900,
|
||||||
];
|
];
|
||||||
|
|
||||||
_createPrimarySwatch(Color color) {
|
MaterialColor _createPrimarySwatch(Color color) {
|
||||||
final Map<int, Color> swatch = <int, Color>{};
|
final Map<int, Color> swatch = <int, Color>{};
|
||||||
final int a = color.alpha8bit;
|
final int a = color.alpha8bit;
|
||||||
final int r = color.red8bit;
|
final int r = color.red8bit;
|
||||||
@@ -294,11 +294,11 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getBackupFileName() {
|
String getBackupFileName() {
|
||||||
return "${appName}_backup_${DateTime.now().show}.zip";
|
return '${appName}_backup_${DateTime.now().show}.zip';
|
||||||
}
|
}
|
||||||
|
|
||||||
String get logFile {
|
String get logFile {
|
||||||
return "${appName}_${DateTime.now().show}.log";
|
return '${appName}_${DateTime.now().show}.log';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLocalIpAddress() async {
|
Future<String?> getLocalIpAddress() async {
|
||||||
@@ -324,11 +324,11 @@ class Utils {
|
|||||||
});
|
});
|
||||||
return addresses.first.address;
|
return addresses.first.address;
|
||||||
}
|
}
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleActivator controlSingleActivator(LogicalKeyboardKey trigger) {
|
SingleActivator controlSingleActivator(LogicalKeyboardKey trigger) {
|
||||||
final control = Platform.isMacOS ? false : true;
|
final control = system.isMacOS ? false : true;
|
||||||
return SingleActivator(
|
return SingleActivator(
|
||||||
trigger,
|
trigger,
|
||||||
control: control,
|
control: control,
|
||||||
|
|||||||
@@ -3,30 +3,34 @@ import 'dart:io';
|
|||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_acrylic/flutter_acrylic.dart' as acrylic;
|
||||||
import 'package:screen_retriever/screen_retriever.dart';
|
import 'package:screen_retriever/screen_retriever.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
class Window {
|
class Window {
|
||||||
init(int version) async {
|
Future<void> init(int version) async {
|
||||||
final props = globalState.config.windowProps;
|
final props = globalState.config.windowProps;
|
||||||
final acquire = await singleInstanceLock.acquire();
|
final acquire = await singleInstanceLock.acquire();
|
||||||
if (!acquire) {
|
if (!acquire) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if (Platform.isWindows) {
|
if (system.isWindows) {
|
||||||
protocol.register("clash");
|
protocol.register('clash');
|
||||||
protocol.register("clashmeta");
|
protocol.register('clashmeta');
|
||||||
protocol.register("flclash");
|
protocol.register('flclash');
|
||||||
|
}
|
||||||
|
if ((version > 10 && system.isMacOS)) {
|
||||||
|
await acrylic.Window.initialize();
|
||||||
}
|
}
|
||||||
await windowManager.ensureInitialized();
|
await windowManager.ensureInitialized();
|
||||||
WindowOptions windowOptions = WindowOptions(
|
WindowOptions windowOptions = WindowOptions(
|
||||||
size: Size(props.width, props.height),
|
size: Size(props.width, props.height),
|
||||||
minimumSize: const Size(380, 400),
|
minimumSize: const Size(380, 400),
|
||||||
);
|
);
|
||||||
if (!Platform.isMacOS || version > 10) {
|
if (!system.isMacOS || version > 10) {
|
||||||
await windowManager.setTitleBarStyle(TitleBarStyle.hidden);
|
await windowManager.setTitleBarStyle(TitleBarStyle.hidden);
|
||||||
}
|
}
|
||||||
if (!Platform.isMacOS) {
|
if (!system.isMacOS) {
|
||||||
final left = props.left ?? 0;
|
final left = props.left ?? 0;
|
||||||
final top = props.top ?? 0;
|
final top = props.top ?? 0;
|
||||||
final right = left + props.width;
|
final right = left + props.width;
|
||||||
@@ -62,7 +66,14 @@ class Window {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
show() async {
|
void updateMacOSBrightness(Brightness brightness) {
|
||||||
|
if (!system.isMacOS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
acrylic.Window.overrideMacOSBrightness(dark: brightness == Brightness.dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> show() async {
|
||||||
render?.resume();
|
render?.resume();
|
||||||
await windowManager.show();
|
await windowManager.show();
|
||||||
await windowManager.focus();
|
await windowManager.focus();
|
||||||
@@ -71,15 +82,15 @@ class Window {
|
|||||||
|
|
||||||
Future<bool> get isVisible async {
|
Future<bool> get isVisible async {
|
||||||
final value = await windowManager.isVisible();
|
final value = await windowManager.isVisible();
|
||||||
commonPrint.log("window visible check: $value");
|
commonPrint.log('window visible check: $value');
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
close() async {
|
Future<void> close() async {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() async {
|
Future<void> hide() async {
|
||||||
render?.pause();
|
render?.pause();
|
||||||
await windowManager.hide();
|
await windowManager.hide();
|
||||||
await windowManager.setSkipTaskbar(true);
|
await windowManager.setSkipTaskbar(true);
|
||||||
|
|||||||
@@ -1,191 +0,0 @@
|
|||||||
import 'dart:ffi';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:ffi/ffi.dart';
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
|
||||||
import 'package:fl_clash/enum/enum.dart';
|
|
||||||
import 'package:path/path.dart';
|
|
||||||
|
|
||||||
class Windows {
|
|
||||||
static Windows? _instance;
|
|
||||||
late DynamicLibrary _shell32;
|
|
||||||
|
|
||||||
Windows._internal() {
|
|
||||||
_shell32 = DynamicLibrary.open('shell32.dll');
|
|
||||||
}
|
|
||||||
|
|
||||||
factory Windows() {
|
|
||||||
_instance ??= Windows._internal();
|
|
||||||
return _instance!;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool runas(String command, String arguments) {
|
|
||||||
final commandPtr = command.toNativeUtf16();
|
|
||||||
final argumentsPtr = arguments.toNativeUtf16();
|
|
||||||
final operationPtr = 'runas'.toNativeUtf16();
|
|
||||||
|
|
||||||
final shellExecute = _shell32.lookupFunction<
|
|
||||||
Int32 Function(
|
|
||||||
Pointer<Utf16> hwnd,
|
|
||||||
Pointer<Utf16> lpOperation,
|
|
||||||
Pointer<Utf16> lpFile,
|
|
||||||
Pointer<Utf16> lpParameters,
|
|
||||||
Pointer<Utf16> lpDirectory,
|
|
||||||
Int32 nShowCmd),
|
|
||||||
int Function(
|
|
||||||
Pointer<Utf16> hwnd,
|
|
||||||
Pointer<Utf16> lpOperation,
|
|
||||||
Pointer<Utf16> lpFile,
|
|
||||||
Pointer<Utf16> lpParameters,
|
|
||||||
Pointer<Utf16> lpDirectory,
|
|
||||||
int nShowCmd)>('ShellExecuteW');
|
|
||||||
|
|
||||||
final result = shellExecute(
|
|
||||||
nullptr,
|
|
||||||
operationPtr,
|
|
||||||
commandPtr,
|
|
||||||
argumentsPtr,
|
|
||||||
nullptr,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
|
|
||||||
calloc.free(commandPtr);
|
|
||||||
calloc.free(argumentsPtr);
|
|
||||||
calloc.free(operationPtr);
|
|
||||||
|
|
||||||
commonPrint.log("windows runas: $command $arguments resultCode:$result");
|
|
||||||
|
|
||||||
if (result < 42) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_killProcess(int port) async {
|
|
||||||
final result = await Process.run('netstat', ['-ano']);
|
|
||||||
final lines = result.stdout.toString().trim().split('\n');
|
|
||||||
for (final line in lines) {
|
|
||||||
if (!line.contains(":$port") || !line.contains("LISTENING")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final parts = line.trim().split(RegExp(r'\s+'));
|
|
||||||
final pid = int.tryParse(parts.last);
|
|
||||||
if (pid != null) {
|
|
||||||
await Process.run('taskkill', ['/PID', pid.toString(), '/F']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<WindowsHelperServiceStatus> checkService() async {
|
|
||||||
// final qcResult = await Process.run('sc', ['qc', appHelperService]);
|
|
||||||
// final qcOutput = qcResult.stdout.toString();
|
|
||||||
// if (qcResult.exitCode != 0 || !qcOutput.contains(appPath.helperPath)) {
|
|
||||||
// return WindowsHelperServiceStatus.none;
|
|
||||||
// }
|
|
||||||
final result = await Process.run('sc', ['query', appHelperService]);
|
|
||||||
if(result.exitCode != 0){
|
|
||||||
return WindowsHelperServiceStatus.none;
|
|
||||||
}
|
|
||||||
final output = result.stdout.toString();
|
|
||||||
if (output.contains("RUNNING") && await request.pingHelper()) {
|
|
||||||
return WindowsHelperServiceStatus.running;
|
|
||||||
}
|
|
||||||
return WindowsHelperServiceStatus.presence;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> registerService() async {
|
|
||||||
final status = await checkService();
|
|
||||||
|
|
||||||
if (status == WindowsHelperServiceStatus.running) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
await _killProcess(helperPort);
|
|
||||||
|
|
||||||
final command = [
|
|
||||||
"/c",
|
|
||||||
if (status == WindowsHelperServiceStatus.presence) ...[
|
|
||||||
"sc",
|
|
||||||
"delete",
|
|
||||||
appHelperService,
|
|
||||||
"/force",
|
|
||||||
"&&",
|
|
||||||
],
|
|
||||||
"sc",
|
|
||||||
"create",
|
|
||||||
appHelperService,
|
|
||||||
'binPath= "${appPath.helperPath}"',
|
|
||||||
'start= auto',
|
|
||||||
"&&",
|
|
||||||
"sc",
|
|
||||||
"start",
|
|
||||||
appHelperService,
|
|
||||||
].join(" ");
|
|
||||||
|
|
||||||
final res = runas("cmd.exe", command);
|
|
||||||
|
|
||||||
await Future.delayed(
|
|
||||||
Duration(milliseconds: 300),
|
|
||||||
);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> registerTask(String appName) async {
|
|
||||||
final taskXml = '''
|
|
||||||
<?xml version="1.0" encoding="UTF-16"?>
|
|
||||||
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
||||||
<Principals>
|
|
||||||
<Principal id="Author">
|
|
||||||
<LogonType>InteractiveToken</LogonType>
|
|
||||||
<RunLevel>HighestAvailable</RunLevel>
|
|
||||||
</Principal>
|
|
||||||
</Principals>
|
|
||||||
<Triggers>
|
|
||||||
<LogonTrigger/>
|
|
||||||
</Triggers>
|
|
||||||
<Settings>
|
|
||||||
<MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
|
|
||||||
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
|
||||||
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
|
||||||
<AllowHardTerminate>false</AllowHardTerminate>
|
|
||||||
<StartWhenAvailable>false</StartWhenAvailable>
|
|
||||||
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
|
||||||
<IdleSettings>
|
|
||||||
<StopOnIdleEnd>false</StopOnIdleEnd>
|
|
||||||
<RestartOnIdle>false</RestartOnIdle>
|
|
||||||
</IdleSettings>
|
|
||||||
<AllowStartOnDemand>true</AllowStartOnDemand>
|
|
||||||
<Enabled>true</Enabled>
|
|
||||||
<Hidden>false</Hidden>
|
|
||||||
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
|
||||||
<WakeToRun>false</WakeToRun>
|
|
||||||
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
|
|
||||||
<Priority>7</Priority>
|
|
||||||
</Settings>
|
|
||||||
<Actions Context="Author">
|
|
||||||
<Exec>
|
|
||||||
<Command>"${Platform.resolvedExecutable}"</Command>
|
|
||||||
</Exec>
|
|
||||||
</Actions>
|
|
||||||
</Task>''';
|
|
||||||
final taskPath = join(await appPath.tempPath, "task.xml");
|
|
||||||
await File(taskPath).create(recursive: true);
|
|
||||||
await File(taskPath)
|
|
||||||
.writeAsBytes(taskXml.encodeUtf16LeWithBom, flush: true);
|
|
||||||
final commandLine = [
|
|
||||||
'/Create',
|
|
||||||
'/TN',
|
|
||||||
appName,
|
|
||||||
'/XML',
|
|
||||||
"%s",
|
|
||||||
'/F',
|
|
||||||
].join(" ");
|
|
||||||
return runas(
|
|
||||||
'schtasks',
|
|
||||||
commandLine.replaceFirst("%s", taskPath),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final windows = Platform.isWindows ? Windows() : null;
|
|
||||||
@@ -2,7 +2,6 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:archive/archive.dart';
|
import 'package:archive/archive.dart';
|
||||||
import 'package:fl_clash/clash/clash.dart';
|
import 'package:fl_clash/clash/clash.dart';
|
||||||
@@ -12,7 +11,9 @@ import 'package:fl_clash/plugins/app.dart';
|
|||||||
import 'package:fl_clash/providers/providers.dart';
|
import 'package:fl_clash/providers/providers.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:fl_clash/widgets/dialog.dart';
|
import 'package:fl_clash/widgets/dialog.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
@@ -29,29 +30,29 @@ class AppController {
|
|||||||
|
|
||||||
AppController(this.context, WidgetRef ref) : _ref = ref;
|
AppController(this.context, WidgetRef ref) : _ref = ref;
|
||||||
|
|
||||||
setupClashConfigDebounce() {
|
void setupClashConfigDebounce() {
|
||||||
debouncer.call(FunctionTag.setupClashConfig, () async {
|
debouncer.call(FunctionTag.setupClashConfig, () async {
|
||||||
await setupClashConfig();
|
await setupClashConfig();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateClashConfigDebounce() {
|
Future<void> updateClashConfigDebounce() async {
|
||||||
debouncer.call(FunctionTag.updateClashConfig, () async {
|
debouncer.call(FunctionTag.updateClashConfig, () async {
|
||||||
await updateClashConfig();
|
await updateClashConfig();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGroupsDebounce() {
|
void updateGroupsDebounce() {
|
||||||
debouncer.call(FunctionTag.updateGroups, updateGroups);
|
debouncer.call(FunctionTag.updateGroups, updateGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
addCheckIpNumDebounce() {
|
void addCheckIpNumDebounce() {
|
||||||
debouncer.call(FunctionTag.addCheckIpNum, () {
|
debouncer.call(FunctionTag.addCheckIpNum, () {
|
||||||
_ref.read(checkIpNumProvider.notifier).add();
|
_ref.read(checkIpNumProvider.notifier).add();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
applyProfileDebounce({
|
void applyProfileDebounce({
|
||||||
bool silence = false,
|
bool silence = false,
|
||||||
}) {
|
}) {
|
||||||
debouncer.call(FunctionTag.applyProfile, (silence) {
|
debouncer.call(FunctionTag.applyProfile, (silence) {
|
||||||
@@ -59,11 +60,11 @@ class AppController {
|
|||||||
}, args: [silence]);
|
}, args: [silence]);
|
||||||
}
|
}
|
||||||
|
|
||||||
savePreferencesDebounce() {
|
void savePreferencesDebounce() {
|
||||||
debouncer.call(FunctionTag.savePreferences, savePreferences);
|
debouncer.call(FunctionTag.savePreferences, savePreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeProxyDebounce(String groupName, String proxyName) {
|
void changeProxyDebounce(String groupName, String proxyName) {
|
||||||
debouncer.call(FunctionTag.changeProxy,
|
debouncer.call(FunctionTag.changeProxy,
|
||||||
(String groupName, String proxyName) async {
|
(String groupName, String proxyName) async {
|
||||||
await changeProxy(
|
await changeProxy(
|
||||||
@@ -74,8 +75,8 @@ class AppController {
|
|||||||
}, args: [groupName, proxyName]);
|
}, args: [groupName, proxyName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
restartCore() async {
|
Future<void> restartCore() async {
|
||||||
commonPrint.log("restart core");
|
commonPrint.log('restart core');
|
||||||
await clashService?.reStart();
|
await clashService?.reStart();
|
||||||
await _initCore();
|
await _initCore();
|
||||||
if (_ref.read(runTimeProvider.notifier).isStart) {
|
if (_ref.read(runTimeProvider.notifier).isStart) {
|
||||||
@@ -83,7 +84,7 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus(bool isStart) async {
|
Future<void> updateStatus(bool isStart) async {
|
||||||
if (isStart) {
|
if (isStart) {
|
||||||
await globalState.handleStart([
|
await globalState.handleStart([
|
||||||
updateRunTime,
|
updateRunTime,
|
||||||
@@ -102,7 +103,7 @@ class AppController {
|
|||||||
applyProfileDebounce();
|
applyProfileDebounce();
|
||||||
} else {
|
} else {
|
||||||
await globalState.handleStop();
|
await globalState.handleStop();
|
||||||
await clashCore.resetTraffic();
|
clashCore.resetTraffic();
|
||||||
_ref.read(trafficsProvider.notifier).clear();
|
_ref.read(trafficsProvider.notifier).clear();
|
||||||
_ref.read(totalTrafficProvider.notifier).value = Traffic();
|
_ref.read(totalTrafficProvider.notifier).value = Traffic();
|
||||||
_ref.read(runTimeProvider.notifier).value = null;
|
_ref.read(runTimeProvider.notifier).value = null;
|
||||||
@@ -110,7 +111,7 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRunTime() {
|
void updateRunTime() {
|
||||||
final startTime = globalState.startTime;
|
final startTime = globalState.startTime;
|
||||||
if (startTime != null) {
|
if (startTime != null) {
|
||||||
final startTimeStamp = startTime.millisecondsSinceEpoch;
|
final startTimeStamp = startTime.millisecondsSinceEpoch;
|
||||||
@@ -121,20 +122,20 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTraffic() async {
|
Future<void> updateTraffic() async {
|
||||||
final traffic = await clashCore.getTraffic();
|
final traffic = await clashCore.getTraffic();
|
||||||
_ref.read(trafficsProvider.notifier).addTraffic(traffic);
|
_ref.read(trafficsProvider.notifier).addTraffic(traffic);
|
||||||
_ref.read(totalTrafficProvider.notifier).value =
|
_ref.read(totalTrafficProvider.notifier).value =
|
||||||
await clashCore.getTotalTraffic();
|
await clashCore.getTotalTraffic();
|
||||||
}
|
}
|
||||||
|
|
||||||
addProfile(Profile profile) async {
|
Future<void> addProfile(Profile profile) async {
|
||||||
_ref.read(profilesProvider.notifier).setProfile(profile);
|
_ref.read(profilesProvider.notifier).setProfile(profile);
|
||||||
if (_ref.read(currentProfileIdProvider) != null) return;
|
if (_ref.read(currentProfileIdProvider) != null) return;
|
||||||
_ref.read(currentProfileIdProvider.notifier).value = profile.id;
|
_ref.read(currentProfileIdProvider.notifier).value = profile.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteProfile(String id) async {
|
Future<void> deleteProfile(String id) async {
|
||||||
_ref.read(profilesProvider.notifier).deleteProfileById(id);
|
_ref.read(profilesProvider.notifier).deleteProfileById(id);
|
||||||
clearEffect(id);
|
clearEffect(id);
|
||||||
if (globalState.config.currentProfileId == id) {
|
if (globalState.config.currentProfileId == id) {
|
||||||
@@ -150,12 +151,12 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProviders() async {
|
Future<void> updateProviders() async {
|
||||||
_ref.read(providersProvider.notifier).value =
|
_ref.read(providersProvider.notifier).value =
|
||||||
await clashCore.getExternalProviders();
|
await clashCore.getExternalProviders();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLocalIp() async {
|
Future<void> updateLocalIp() async {
|
||||||
_ref.read(localIpProvider.notifier).value = null;
|
_ref.read(localIpProvider.notifier).value = null;
|
||||||
await Future.delayed(commonDuration);
|
await Future.delayed(commonDuration);
|
||||||
_ref.read(localIpProvider.notifier).value = await utils.getLocalIpAddress();
|
_ref.read(localIpProvider.notifier).value = await utils.getLocalIpAddress();
|
||||||
@@ -171,26 +172,26 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setProfile(Profile profile) {
|
void setProfile(Profile profile) {
|
||||||
_ref.read(profilesProvider.notifier).setProfile(profile);
|
_ref.read(profilesProvider.notifier).setProfile(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
setProfileAndAutoApply(Profile profile) {
|
void setProfileAndAutoApply(Profile profile) {
|
||||||
_ref.read(profilesProvider.notifier).setProfile(profile);
|
_ref.read(profilesProvider.notifier).setProfile(profile);
|
||||||
if (profile.id == _ref.read(currentProfileIdProvider)) {
|
if (profile.id == _ref.read(currentProfileIdProvider)) {
|
||||||
applyProfileDebounce(silence: true);
|
applyProfileDebounce(silence: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setProfiles(List<Profile> profiles) {
|
void setProfiles(List<Profile> profiles) {
|
||||||
_ref.read(profilesProvider.notifier).value = profiles;
|
_ref.read(profilesProvider.notifier).value = profiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
addLog(Log log) {
|
void addLog(Log log) {
|
||||||
_ref.read(logsProvider).add(log);
|
_ref.read(logsProvider).add(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOrAddHotKeyAction(HotKeyAction hotKeyAction) {
|
void updateOrAddHotKeyAction(HotKeyAction hotKeyAction) {
|
||||||
final hotKeyActions = _ref.read(hotKeyActionsProvider);
|
final hotKeyActions = _ref.read(hotKeyActionsProvider);
|
||||||
final index =
|
final index =
|
||||||
hotKeyActions.indexWhere((item) => item.action == hotKeyAction.action);
|
hotKeyActions.indexWhere((item) => item.action == hotKeyAction.action);
|
||||||
@@ -219,26 +220,26 @@ class AppController {
|
|||||||
return _ref.read(getProxiesColumnsProvider);
|
return _ref.read(getProxiesColumnsProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
addSortNum() {
|
dynamic addSortNum() {
|
||||||
return _ref.read(sortNumProvider.notifier).add();
|
return _ref.read(sortNumProvider.notifier).add();
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentGroupName() {
|
String? getCurrentGroupName() {
|
||||||
final currentGroupName = _ref.read(currentProfileProvider.select(
|
final currentGroupName = _ref.read(currentProfileProvider.select(
|
||||||
(state) => state?.currentGroupName,
|
(state) => state?.currentGroupName,
|
||||||
));
|
));
|
||||||
return currentGroupName;
|
return currentGroupName;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyCardState getProxyCardState(proxyName) {
|
ProxyCardState getProxyCardState(String proxyName) {
|
||||||
return _ref.read(getProxyCardStateProvider(proxyName));
|
return _ref.read(getProxyCardStateProvider(proxyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectedProxyName(groupName) {
|
String? getSelectedProxyName(String groupName) {
|
||||||
return _ref.read(getSelectedProxyNameProvider(groupName));
|
return _ref.read(getSelectedProxyNameProvider(groupName));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCurrentGroupName(String groupName) {
|
void updateCurrentGroupName(String groupName) {
|
||||||
final profile = _ref.read(currentProfileProvider);
|
final profile = _ref.read(currentProfileProvider);
|
||||||
if (profile == null || profile.currentGroupName == groupName) {
|
if (profile == null || profile.currentGroupName == groupName) {
|
||||||
return;
|
return;
|
||||||
@@ -249,11 +250,12 @@ class AppController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateClashConfig() async {
|
Future<void> updateClashConfig() async {
|
||||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
await safeRun(
|
||||||
if (commonScaffoldState?.mounted != true) return;
|
() async {
|
||||||
await commonScaffoldState?.loadingRun(() async {
|
await _updateClashConfig();
|
||||||
await _updateClashConfig();
|
},
|
||||||
});
|
needLoading: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateClashConfig() async {
|
Future<void> _updateClashConfig() async {
|
||||||
@@ -272,13 +274,16 @@ class AppController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Result<bool>> _requestAdmin(bool enableTun) async {
|
Future<Result<bool>> _requestAdmin(bool enableTun) async {
|
||||||
|
if(system.isWindows && kDebugMode){
|
||||||
|
return Result.success(false);
|
||||||
|
}
|
||||||
final realTunEnable = _ref.read(realTunEnableProvider);
|
final realTunEnable = _ref.read(realTunEnableProvider);
|
||||||
if (enableTun != realTunEnable && realTunEnable == false) {
|
if (enableTun != realTunEnable && realTunEnable == false) {
|
||||||
final code = await system.authorizeCore();
|
final code = await system.authorizeCore();
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case AuthorizeCode.success:
|
case AuthorizeCode.success:
|
||||||
await restartCore();
|
await restartCore();
|
||||||
return Result.error("");
|
return Result.error('');
|
||||||
case AuthorizeCode.none:
|
case AuthorizeCode.none:
|
||||||
break;
|
break;
|
||||||
case AuthorizeCode.error:
|
case AuthorizeCode.error:
|
||||||
@@ -291,14 +296,15 @@ class AppController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setupClashConfig() async {
|
Future<void> setupClashConfig() async {
|
||||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
await safeRun(
|
||||||
if (commonScaffoldState?.mounted != true) return;
|
() async {
|
||||||
await commonScaffoldState?.loadingRun(() async {
|
await _setupClashConfig();
|
||||||
await _setupClashConfig();
|
},
|
||||||
});
|
needLoading: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setupClashConfig() async {
|
Future<void> _setupClashConfig() async {
|
||||||
await _ref.read(currentProfileProvider)?.checkAndUpdate();
|
await _ref.read(currentProfileProvider)?.checkAndUpdate();
|
||||||
final patchConfig = _ref.read(patchClashConfigProvider);
|
final patchConfig = _ref.read(patchClashConfigProvider);
|
||||||
final res = await _requestAdmin(patchConfig.tun.enable);
|
final res = await _requestAdmin(patchConfig.tun.enable);
|
||||||
@@ -332,29 +338,32 @@ class AppController {
|
|||||||
if (silence) {
|
if (silence) {
|
||||||
await _applyProfile();
|
await _applyProfile();
|
||||||
} else {
|
} else {
|
||||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
await safeRun(
|
||||||
if (commonScaffoldState?.mounted != true) return;
|
() async {
|
||||||
await commonScaffoldState?.loadingRun(() async {
|
await _applyProfile();
|
||||||
await _applyProfile();
|
},
|
||||||
});
|
needLoading: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
addCheckIpNumDebounce();
|
addCheckIpNumDebounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeProfile() {
|
void handleChangeProfile() {
|
||||||
_ref.read(delayDataSourceProvider.notifier).value = {};
|
_ref.read(delayDataSourceProvider.notifier).value = {};
|
||||||
applyProfile();
|
applyProfile();
|
||||||
_ref.read(logsProvider.notifier).value = FixedList(500);
|
_ref.read(logsProvider.notifier).value = FixedList(500);
|
||||||
_ref.read(requestsProvider.notifier).value = FixedList(500);
|
_ref.read(requestsProvider.notifier).value = FixedList(500);
|
||||||
globalState.cacheHeightMap = {};
|
globalState.computeHeightMapCache = {};
|
||||||
globalState.cacheScrollPosition = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBrightness(Brightness brightness) {
|
void updateBrightness() {
|
||||||
_ref.read(appBrightnessProvider.notifier).value = brightness;
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_ref.read(systemBrightnessProvider.notifier).value =
|
||||||
|
WidgetsBinding.instance.platformDispatcher.platformBrightness;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
autoUpdateProfiles() async {
|
Future<void> autoUpdateProfiles() async {
|
||||||
for (final profile in _ref.read(profilesProvider)) {
|
for (final profile in _ref.read(profilesProvider)) {
|
||||||
if (!profile.autoUpdate) continue;
|
if (!profile.autoUpdate) continue;
|
||||||
final isNotNeedUpdate = profile.lastUpdateDate
|
final isNotNeedUpdate = profile.lastUpdateDate
|
||||||
@@ -386,7 +395,7 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProfiles() async {
|
Future<void> updateProfiles() async {
|
||||||
for (final profile in _ref.read(profilesProvider)) {
|
for (final profile in _ref.read(profilesProvider)) {
|
||||||
if (profile.type == ProfileType.file) {
|
if (profile.type == ProfileType.file) {
|
||||||
continue;
|
continue;
|
||||||
@@ -395,12 +404,12 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
savePreferences() async {
|
Future<void> savePreferences() async {
|
||||||
commonPrint.log("save preferences");
|
commonPrint.log('save preferences');
|
||||||
await preferences.saveConfig(globalState.config);
|
await preferences.saveConfig(globalState.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeProxy({
|
Future<void> changeProxy({
|
||||||
required String groupName,
|
required String groupName,
|
||||||
required String proxyName,
|
required String proxyName,
|
||||||
}) async {
|
}) async {
|
||||||
@@ -416,13 +425,13 @@ class AppController {
|
|||||||
addCheckIpNumDebounce();
|
addCheckIpNumDebounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBackOrExit() async {
|
Future<void> handleBackOrExit() async {
|
||||||
if (_ref.read(backBlockProvider)) {
|
if (_ref.read(backBlockProvider)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_ref.read(appSettingProvider).minimizeOnExit) {
|
if (_ref.read(appSettingProvider).minimizeOnExit) {
|
||||||
if (system.isDesktop) {
|
if (system.isDesktop) {
|
||||||
await savePreferencesDebounce();
|
await savePreferences();
|
||||||
}
|
}
|
||||||
await system.back();
|
await system.back();
|
||||||
} else {
|
} else {
|
||||||
@@ -430,21 +439,21 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backBlock() {
|
void backBlock() {
|
||||||
_ref.read(backBlockProvider.notifier).value = true;
|
_ref.read(backBlockProvider.notifier).value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unBackBlock() {
|
void unBackBlock() {
|
||||||
_ref.read(backBlockProvider.notifier).value = false;
|
_ref.read(backBlockProvider.notifier).value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleExit() async {
|
Future<void> handleExit() async {
|
||||||
Future.delayed(commonDuration, () {
|
Future.delayed(commonDuration, () {
|
||||||
system.exit();
|
system.exit();
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await savePreferences();
|
await savePreferences();
|
||||||
await system.setMacOSDns(true);
|
await macOS?.updateDns(true);
|
||||||
await proxy?.stopProxy();
|
await proxy?.stopProxy();
|
||||||
await clashCore.shutdown();
|
await clashCore.shutdown();
|
||||||
await clashService?.destroy();
|
await clashService?.destroy();
|
||||||
@@ -455,19 +464,19 @@ class AppController {
|
|||||||
|
|
||||||
Future handleClear() async {
|
Future handleClear() async {
|
||||||
await preferences.clearPreferences();
|
await preferences.clearPreferences();
|
||||||
commonPrint.log("clear preferences");
|
commonPrint.log('clear preferences');
|
||||||
globalState.config = Config(
|
globalState.config = Config(
|
||||||
themeProps: defaultThemeProps,
|
themeProps: defaultThemeProps,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
autoCheckUpdate() async {
|
Future<void> autoCheckUpdate() async {
|
||||||
if (!_ref.read(appSettingProvider).autoCheckUpdate) return;
|
if (!_ref.read(appSettingProvider).autoCheckUpdate) return;
|
||||||
final res = await request.checkForUpdate();
|
final res = await request.checkForUpdate();
|
||||||
checkUpdateResultHandle(data: res);
|
checkUpdateResultHandle(data: res);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkUpdateResultHandle({
|
Future<void> checkUpdateResultHandle({
|
||||||
Map<String, dynamic>? data,
|
Map<String, dynamic>? data,
|
||||||
bool handleError = false,
|
bool handleError = false,
|
||||||
}) async {
|
}) async {
|
||||||
@@ -482,16 +491,16 @@ class AppController {
|
|||||||
final res = await globalState.showMessage(
|
final res = await globalState.showMessage(
|
||||||
title: appLocalizations.discoverNewVersion,
|
title: appLocalizations.discoverNewVersion,
|
||||||
message: TextSpan(
|
message: TextSpan(
|
||||||
text: "$tagName \n",
|
text: '$tagName \n',
|
||||||
style: textTheme.headlineSmall,
|
style: textTheme.headlineSmall,
|
||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: "\n",
|
text: '\n',
|
||||||
style: textTheme.bodyMedium,
|
style: textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
for (final submit in submits)
|
for (final submit in submits)
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: "- $submit \n",
|
text: '- $submit \n',
|
||||||
style: textTheme.bodyMedium,
|
style: textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -502,7 +511,7 @@ class AppController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
launchUrl(
|
launchUrl(
|
||||||
Uri.parse("https://github.com/$repository/releases/latest"),
|
Uri.parse('https://github.com/$repository/releases/latest'),
|
||||||
);
|
);
|
||||||
} else if (handleError) {
|
} else if (handleError) {
|
||||||
globalState.showMessage(
|
globalState.showMessage(
|
||||||
@@ -514,7 +523,7 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_handlePreference() async {
|
Future<void> _handlePreference() async {
|
||||||
if (await preferences.isInit) {
|
if (await preferences.isInit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -543,9 +552,11 @@ class AppController {
|
|||||||
await applyProfile();
|
await applyProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
init() async {
|
Future<void> init() async {
|
||||||
FlutterError.onError = (details) {
|
FlutterError.onError = (details) {
|
||||||
commonPrint.log(details.stack.toString());
|
if (kDebugMode) {
|
||||||
|
commonPrint.log(details.stack.toString());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
updateTray(true);
|
updateTray(true);
|
||||||
await _initCore();
|
await _initCore();
|
||||||
@@ -565,8 +576,8 @@ class AppController {
|
|||||||
_ref.read(initProvider.notifier).value = true;
|
_ref.read(initProvider.notifier).value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_initStatus() async {
|
Future<void> _initStatus() async {
|
||||||
if (Platform.isAndroid) {
|
if (system.isAndroid) {
|
||||||
await globalState.updateStartTime();
|
await globalState.updateStartTime();
|
||||||
}
|
}
|
||||||
final status = globalState.isStart == true
|
final status = globalState.isStart == true
|
||||||
@@ -579,28 +590,28 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDelay(Delay delay) {
|
void setDelay(Delay delay) {
|
||||||
_ref.read(delayDataSourceProvider.notifier).setDelay(delay);
|
_ref.read(delayDataSourceProvider.notifier).setDelay(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
toPage(PageLabel pageLabel) {
|
void toPage(PageLabel pageLabel) {
|
||||||
_ref.read(currentPageLabelProvider.notifier).value = pageLabel;
|
_ref.read(currentPageLabelProvider.notifier).value = pageLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
toProfiles() {
|
void toProfiles() {
|
||||||
toPage(PageLabel.profiles);
|
toPage(PageLabel.profiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
initLink() {
|
void initLink() {
|
||||||
linkManager.initAppLinksListen(
|
linkManager.initAppLinksListen(
|
||||||
(url) async {
|
(url) async {
|
||||||
final res = await globalState.showMessage(
|
final res = await globalState.showMessage(
|
||||||
title: "${appLocalizations.add}${appLocalizations.profile}",
|
title: '${appLocalizations.add}${appLocalizations.profile}',
|
||||||
message: TextSpan(
|
message: TextSpan(
|
||||||
children: [
|
children: [
|
||||||
TextSpan(text: appLocalizations.doYouWantToPass),
|
TextSpan(text: appLocalizations.doYouWantToPass),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: " $url ",
|
text: ' $url ',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
@@ -609,7 +620,7 @@ class AppController {
|
|||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text:
|
text:
|
||||||
"${appLocalizations.create}${appLocalizations.profile}"),
|
'${appLocalizations.create}${appLocalizations.profile}'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -652,7 +663,7 @@ class AppController {
|
|||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_handlerDisclaimer() async {
|
Future<void> _handlerDisclaimer() async {
|
||||||
if (_ref.read(appSettingProvider).disclaimerAccepted) {
|
if (_ref.read(appSettingProvider).disclaimerAccepted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -663,62 +674,64 @@ class AppController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addProfileFormURL(String url) async {
|
Future<void> addProfileFormURL(String url) async {
|
||||||
if (globalState.navigatorKey.currentState?.canPop() ?? false) {
|
if (globalState.navigatorKey.currentState?.canPop() ?? false) {
|
||||||
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
||||||
}
|
}
|
||||||
toProfiles();
|
toProfiles();
|
||||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
|
||||||
if (commonScaffoldState?.mounted != true) return;
|
final profile = await safeRun(
|
||||||
final profile = await commonScaffoldState?.loadingRun<Profile>(
|
|
||||||
() async {
|
() async {
|
||||||
return await Profile.normal(
|
return await Profile.normal(
|
||||||
url: url,
|
url: url,
|
||||||
).update();
|
).update();
|
||||||
},
|
},
|
||||||
title: "${appLocalizations.add}${appLocalizations.profile}",
|
needLoading: true,
|
||||||
|
title: '${appLocalizations.add}${appLocalizations.profile}',
|
||||||
);
|
);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
await addProfile(profile);
|
await addProfile(profile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addProfileFormFile() async {
|
Future<void> addProfileFormFile() async {
|
||||||
final platformFile = await globalState.safeRun(picker.pickerFile);
|
final platformFile = await safeRun(picker.pickerFile);
|
||||||
final bytes = platformFile?.bytes;
|
final bytes = platformFile?.bytes;
|
||||||
if (bytes == null) {
|
if (bytes == null) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
globalState.navigatorKey.currentState?.popUntil((route) => route.isFirst);
|
||||||
toProfiles();
|
toProfiles();
|
||||||
final commonScaffoldState = globalState.homeScaffoldKey.currentState;
|
|
||||||
if (commonScaffoldState?.mounted != true) return;
|
final profile = await safeRun(
|
||||||
final profile = await commonScaffoldState?.loadingRun<Profile?>(
|
|
||||||
() async {
|
() async {
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
return await Profile.normal(label: platformFile?.name).saveFile(bytes);
|
return await Profile.normal(label: platformFile?.name).saveFile(bytes);
|
||||||
},
|
},
|
||||||
title: "${appLocalizations.add}${appLocalizations.profile}",
|
needLoading: true,
|
||||||
|
title: '${appLocalizations.add}${appLocalizations.profile}',
|
||||||
);
|
);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
await addProfile(profile);
|
await addProfile(profile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addProfileFormQrCode() async {
|
Future<void> addProfileFormQrCode() async {
|
||||||
final url = await globalState.safeRun(picker.pickerConfigQRCode);
|
final url = await safeRun(
|
||||||
|
picker.pickerConfigQRCode,
|
||||||
|
);
|
||||||
if (url == null) return;
|
if (url == null) return;
|
||||||
addProfileFormURL(url);
|
addProfileFormURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateViewSize(Size size) {
|
void updateViewSize(Size size) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
_ref.read(viewSizeProvider.notifier).value = size;
|
_ref.read(viewSizeProvider.notifier).value = size;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setProvider(ExternalProvider? provider) {
|
void setProvider(ExternalProvider? provider) {
|
||||||
_ref.read(providersProvider.notifier).setProvider(provider);
|
_ref.read(providersProvider.notifier).setProvider(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,18 +776,22 @@ class AppController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Proxy> getSortProxies(List<Proxy> proxies, [String? url]) {
|
List<Proxy> getSortProxies({
|
||||||
return switch (_ref.read(proxiesStyleSettingProvider).sortType) {
|
required List<Proxy> proxies,
|
||||||
|
required ProxiesSortType sortType,
|
||||||
|
String? testUrl,
|
||||||
|
}) {
|
||||||
|
return switch (sortType) {
|
||||||
ProxiesSortType.none => proxies,
|
ProxiesSortType.none => proxies,
|
||||||
ProxiesSortType.delay => _sortOfDelay(
|
ProxiesSortType.delay => _sortOfDelay(
|
||||||
proxies: proxies,
|
proxies: proxies,
|
||||||
testUrl: url,
|
testUrl: testUrl,
|
||||||
),
|
),
|
||||||
ProxiesSortType.name => _sortOfName(proxies),
|
ProxiesSortType.name => _sortOfName(proxies),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
clearEffect(String profileId) async {
|
Future<Null> clearEffect(String profileId) async {
|
||||||
final profilePath = await appPath.getProfilePath(profileId);
|
final profilePath = await appPath.getProfilePath(profileId);
|
||||||
final providersDirPath = await appPath.getProvidersDirPath(profileId);
|
final providersDirPath = await appPath.getProvidersDirPath(profileId);
|
||||||
return await Isolate.run(() async {
|
return await Isolate.run(() async {
|
||||||
@@ -791,13 +808,13 @@ class AppController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTun() {
|
void updateTun() {
|
||||||
_ref.read(patchClashConfigProvider.notifier).updateState(
|
_ref.read(patchClashConfigProvider.notifier).updateState(
|
||||||
(state) => state.copyWith.tun(enable: !state.tun.enable),
|
(state) => state.copyWith.tun(enable: !state.tun.enable),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSystemProxy() {
|
void updateSystemProxy() {
|
||||||
_ref.read(networkSettingProvider.notifier).updateState(
|
_ref.read(networkSettingProvider.notifier).updateState(
|
||||||
(state) => state.copyWith(
|
(state) => state.copyWith(
|
||||||
systemProxy: !state.systemProxy,
|
systemProxy: !state.systemProxy,
|
||||||
@@ -816,11 +833,11 @@ class AppController {
|
|||||||
return _ref.read(packagesProvider);
|
return _ref.read(packagesProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStart() {
|
void updateStart() {
|
||||||
updateStatus(!_ref.read(runTimeProvider.notifier).isStart);
|
updateStatus(!_ref.read(runTimeProvider.notifier).isStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCurrentSelectedMap(String groupName, String proxyName) {
|
void updateCurrentSelectedMap(String groupName, String proxyName) {
|
||||||
final currentProfile = _ref.read(currentProfileProvider);
|
final currentProfile = _ref.read(currentProfileProvider);
|
||||||
if (currentProfile != null &&
|
if (currentProfile != null &&
|
||||||
currentProfile.selectedMap[groupName] != proxyName) {
|
currentProfile.selectedMap[groupName] != proxyName) {
|
||||||
@@ -835,7 +852,7 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCurrentUnfoldSet(Set<String> value) {
|
void updateCurrentUnfoldSet(Set<String> value) {
|
||||||
final currentProfile = _ref.read(currentProfileProvider);
|
final currentProfile = _ref.read(currentProfileProvider);
|
||||||
if (currentProfile == null) {
|
if (currentProfile == null) {
|
||||||
return;
|
return;
|
||||||
@@ -847,7 +864,7 @@ class AppController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeMode(Mode mode) {
|
void changeMode(Mode mode) {
|
||||||
_ref.read(patchClashConfigProvider.notifier).updateState(
|
_ref.read(patchClashConfigProvider.notifier).updateState(
|
||||||
(state) => state.copyWith(mode: mode),
|
(state) => state.copyWith(mode: mode),
|
||||||
);
|
);
|
||||||
@@ -857,7 +874,7 @@ class AppController {
|
|||||||
addCheckIpNumDebounce();
|
addCheckIpNumDebounce();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAutoLaunch() {
|
void updateAutoLaunch() {
|
||||||
_ref.read(appSettingProvider.notifier).updateState(
|
_ref.read(appSettingProvider.notifier).updateState(
|
||||||
(state) => state.copyWith(
|
(state) => state.copyWith(
|
||||||
autoLaunch: !state.autoLaunch,
|
autoLaunch: !state.autoLaunch,
|
||||||
@@ -865,7 +882,7 @@ class AppController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateVisible() async {
|
Future<void> updateVisible() async {
|
||||||
final visible = await window?.isVisible;
|
final visible = await window?.isVisible;
|
||||||
if (visible != null && !visible) {
|
if (visible != null && !visible) {
|
||||||
window?.show();
|
window?.show();
|
||||||
@@ -874,7 +891,7 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMode() {
|
void updateMode() {
|
||||||
_ref.read(patchClashConfigProvider.notifier).updateState(
|
_ref.read(patchClashConfigProvider.notifier).updateState(
|
||||||
(state) {
|
(state) {
|
||||||
final index = Mode.values.indexWhere((item) => item == state.mode);
|
final index = Mode.values.indexWhere((item) => item == state.mode);
|
||||||
@@ -889,7 +906,7 @@ class AppController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAddOrUpdate(WidgetRef ref, [Rule? rule]) async {
|
Future<void> handleAddOrUpdate(WidgetRef ref, [Rule? rule]) async {
|
||||||
final res = await globalState.showCommonDialog<Rule>(
|
final res = await globalState.showCommonDialog<Rule>(
|
||||||
child: AddRuleDialog(
|
child: AddRuleDialog(
|
||||||
rule: rule,
|
rule: rule,
|
||||||
@@ -926,7 +943,7 @@ class AppController {
|
|||||||
(item) => item.toString(),
|
(item) => item.toString(),
|
||||||
);
|
);
|
||||||
final data = await Isolate.run<List<int>>(() async {
|
final data = await Isolate.run<List<int>>(() async {
|
||||||
final logsRawString = logsRaw.join("\n");
|
final logsRawString = logsRaw.join('\n');
|
||||||
return utf8.encode(logsRawString);
|
return utf8.encode(logsRawString);
|
||||||
});
|
});
|
||||||
return await picker.saveFile(
|
return await picker.saveFile(
|
||||||
@@ -942,20 +959,20 @@ class AppController {
|
|||||||
final configJson = globalState.config.toJson();
|
final configJson = globalState.config.toJson();
|
||||||
return Isolate.run<List<int>>(() async {
|
return Isolate.run<List<int>>(() async {
|
||||||
final archive = Archive();
|
final archive = Archive();
|
||||||
archive.add("config.json", configJson);
|
archive.add('config.json', configJson);
|
||||||
await archive.addDirectoryToArchive(profilesPath, homeDirPath);
|
archive.addDirectoryToArchive(profilesPath, homeDirPath);
|
||||||
final zipEncoder = ZipEncoder();
|
final zipEncoder = ZipEncoder();
|
||||||
return zipEncoder.encode(archive) ?? [];
|
return zipEncoder.encode(archive) ?? [];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTray([bool focus = false]) async {
|
Future<void> updateTray([bool focus = false]) async {
|
||||||
tray.update(
|
tray.update(
|
||||||
trayState: _ref.read(trayStateProvider),
|
trayState: _ref.read(trayStateProvider),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
recoveryData(
|
Future<void> recoveryData(
|
||||||
List<int> data,
|
List<int> data,
|
||||||
RecoveryOption recoveryOption,
|
RecoveryOption recoveryOption,
|
||||||
) async {
|
) async {
|
||||||
@@ -965,12 +982,12 @@ class AppController {
|
|||||||
});
|
});
|
||||||
final homeDirPath = await appPath.homeDirPath;
|
final homeDirPath = await appPath.homeDirPath;
|
||||||
final configs =
|
final configs =
|
||||||
archive.files.where((item) => item.name.endsWith(".json")).toList();
|
archive.files.where((item) => item.name.endsWith('.json')).toList();
|
||||||
final profiles =
|
final profiles =
|
||||||
archive.files.where((item) => !item.name.endsWith(".json"));
|
archive.files.where((item) => !item.name.endsWith('.json'));
|
||||||
final configIndex =
|
final configIndex =
|
||||||
configs.indexWhere((config) => config.name == "config.json");
|
configs.indexWhere((config) => config.name == 'config.json');
|
||||||
if (configIndex == -1) throw "invalid backup file";
|
if (configIndex == -1) throw 'invalid backup file';
|
||||||
final configFile = configs[configIndex];
|
final configFile = configs[configIndex];
|
||||||
var tempConfig = Config.compatibleFromJson(
|
var tempConfig = Config.compatibleFromJson(
|
||||||
json.decode(
|
json.decode(
|
||||||
@@ -984,7 +1001,7 @@ class AppController {
|
|||||||
await file.writeAsBytes(profile.content);
|
await file.writeAsBytes(profile.content);
|
||||||
}
|
}
|
||||||
final clashConfigIndex =
|
final clashConfigIndex =
|
||||||
configs.indexWhere((config) => config.name == "clashConfig.json");
|
configs.indexWhere((config) => config.name == 'clashConfig.json');
|
||||||
if (clashConfigIndex != -1) {
|
if (clashConfigIndex != -1) {
|
||||||
final clashConfigFile = configs[clashConfigIndex];
|
final clashConfigFile = configs[clashConfigIndex];
|
||||||
tempConfig = tempConfig.copyWith(
|
tempConfig = tempConfig.copyWith(
|
||||||
@@ -1003,7 +1020,7 @@ class AppController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_recovery(Config config, RecoveryOption recoveryOption) {
|
void _recovery(Config config, RecoveryOption recoveryOption) {
|
||||||
final recoveryStrategy = _ref.read(appSettingProvider.select(
|
final recoveryStrategy = _ref.read(appSettingProvider.select(
|
||||||
(state) => state.recoveryStrategy,
|
(state) => state.recoveryStrategy,
|
||||||
));
|
));
|
||||||
@@ -1040,4 +1057,35 @@ class AppController {
|
|||||||
_ref.read(currentProfileIdProvider.notifier).value = profiles.first.id;
|
_ref.read(currentProfileIdProvider.notifier).value = profiles.first.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<T?> safeRun<T>(
|
||||||
|
FutureOr<T> Function() futureFunction, {
|
||||||
|
String? title,
|
||||||
|
bool needLoading = false,
|
||||||
|
bool silence = true,
|
||||||
|
}) async {
|
||||||
|
final realSilence = needLoading == true ? true : silence;
|
||||||
|
try {
|
||||||
|
if (needLoading) {
|
||||||
|
_ref.read(loadingProvider.notifier).value = true;
|
||||||
|
}
|
||||||
|
final res = await futureFunction();
|
||||||
|
return res;
|
||||||
|
} catch (e) {
|
||||||
|
commonPrint.log('$e');
|
||||||
|
if (realSilence) {
|
||||||
|
globalState.showNotifier(e.toString());
|
||||||
|
} else {
|
||||||
|
globalState.showMessage(
|
||||||
|
title: title ?? appLocalizations.tip,
|
||||||
|
message: TextSpan(
|
||||||
|
text: e.toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
_ref.read(loadingProvider.notifier).value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:fl_clash/common/system.dart';
|
||||||
import 'package:fl_clash/views/dashboard/widgets/widgets.dart';
|
import 'package:fl_clash/views/dashboard/widgets/widgets.dart';
|
||||||
import 'package:fl_clash/widgets/widgets.dart';
|
import 'package:fl_clash/widgets/widgets.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||||
@@ -15,16 +17,16 @@ enum SupportPlatform {
|
|||||||
Android;
|
Android;
|
||||||
|
|
||||||
static SupportPlatform get currentPlatform {
|
static SupportPlatform get currentPlatform {
|
||||||
if (Platform.isWindows) {
|
if (system.isWindows) {
|
||||||
return SupportPlatform.Windows;
|
return SupportPlatform.Windows;
|
||||||
} else if (Platform.isMacOS) {
|
} else if (system.isMacOS) {
|
||||||
return SupportPlatform.MacOS;
|
return SupportPlatform.MacOS;
|
||||||
} else if (Platform.isLinux) {
|
} else if (Platform.isLinux) {
|
||||||
return SupportPlatform.Linux;
|
return SupportPlatform.Linux;
|
||||||
} else if (Platform.isAndroid) {
|
} else if (system.isAndroid) {
|
||||||
return SupportPlatform.Android;
|
return SupportPlatform.Android;
|
||||||
}
|
}
|
||||||
throw "invalid platform";
|
throw 'invalid platform';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,11 +45,11 @@ enum GroupType {
|
|||||||
|
|
||||||
static GroupType parseProfileType(String type) {
|
static GroupType parseProfileType(String type) {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
"url-test" => URLTest,
|
'url-test' => URLTest,
|
||||||
"select" => Selector,
|
'select' => Selector,
|
||||||
"fallback" => Fallback,
|
'fallback' => Fallback,
|
||||||
"load-balance" => LoadBalance,
|
'load-balance' => LoadBalance,
|
||||||
"relay" => Relay,
|
'relay' => Relay,
|
||||||
String() => throw UnimplementedError(),
|
String() => throw UnimplementedError(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -58,7 +60,7 @@ enum GroupName { GLOBAL, Proxy, Auto, Fallback }
|
|||||||
extension GroupTypeExtension on GroupType {
|
extension GroupTypeExtension on GroupType {
|
||||||
static List<String> get valueList => GroupType.values
|
static List<String> get valueList => GroupType.values
|
||||||
.map(
|
.map(
|
||||||
(e) => e.toString().split(".").last,
|
(e) => e.toString().split('.').last,
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -80,7 +82,7 @@ enum UsedProxy { GLOBAL, DIRECT, REJECT }
|
|||||||
extension UsedProxyExtension on UsedProxy {
|
extension UsedProxyExtension on UsedProxy {
|
||||||
static List<String> get valueList => UsedProxy.values
|
static List<String> get valueList => UsedProxy.values
|
||||||
.map(
|
.map(
|
||||||
(e) => e.toString().split(".").last,
|
(e) => e.toString().split('.').last,
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -97,7 +99,18 @@ enum LogLevel {
|
|||||||
warning,
|
warning,
|
||||||
error,
|
error,
|
||||||
silent,
|
silent,
|
||||||
app,
|
}
|
||||||
|
|
||||||
|
extension LogLevelExt on LogLevel {
|
||||||
|
Color? get color {
|
||||||
|
return switch (this) {
|
||||||
|
LogLevel.silent => Colors.grey.shade700,
|
||||||
|
LogLevel.debug => Colors.grey.shade400,
|
||||||
|
LogLevel.info => null,
|
||||||
|
LogLevel.warning => Colors.yellowAccent,
|
||||||
|
LogLevel.error => Colors.redAccent,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TransportProtocol { udp, tcp }
|
enum TransportProtocol { udp, tcp }
|
||||||
@@ -160,18 +173,18 @@ enum ProxyCardType { expand, shrink, min }
|
|||||||
|
|
||||||
enum DnsMode {
|
enum DnsMode {
|
||||||
normal,
|
normal,
|
||||||
@JsonValue("fake-ip")
|
@JsonValue('fake-ip')
|
||||||
fakeIp,
|
fakeIp,
|
||||||
@JsonValue("redir-host")
|
@JsonValue('redir-host')
|
||||||
redirHost,
|
redirHost,
|
||||||
hosts
|
hosts
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ExternalControllerStatus {
|
enum ExternalControllerStatus {
|
||||||
@JsonValue("")
|
@JsonValue('')
|
||||||
close(""),
|
close(''),
|
||||||
@JsonValue("127.0.0.1:9090")
|
@JsonValue('127.0.0.1:9090')
|
||||||
open("127.0.0.1:9090");
|
open('127.0.0.1:9090');
|
||||||
|
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
@@ -235,9 +248,9 @@ enum ProxiesIconStyle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum FontFamily {
|
enum FontFamily {
|
||||||
twEmoji("Twemoji"),
|
twEmoji('Twemoji'),
|
||||||
jetBrainsMono("JetBrainsMono"),
|
jetBrainsMono('JetBrainsMono'),
|
||||||
icon("Icons");
|
icon('Icons');
|
||||||
|
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
@@ -320,6 +333,7 @@ enum FunctionTag {
|
|||||||
proxiesTabChange,
|
proxiesTabChange,
|
||||||
logs,
|
logs,
|
||||||
requests,
|
requests,
|
||||||
|
autoScrollToEnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DashboardWidget {
|
enum DashboardWidget {
|
||||||
@@ -423,39 +437,39 @@ enum PageLabel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum RuleAction {
|
enum RuleAction {
|
||||||
DOMAIN("DOMAIN"),
|
DOMAIN('DOMAIN'),
|
||||||
DOMAIN_SUFFIX("DOMAIN-SUFFIX"),
|
DOMAIN_SUFFIX('DOMAIN-SUFFIX'),
|
||||||
DOMAIN_KEYWORD("DOMAIN-KEYWORD"),
|
DOMAIN_KEYWORD('DOMAIN-KEYWORD'),
|
||||||
DOMAIN_REGEX("DOMAIN-REGEX"),
|
DOMAIN_REGEX('DOMAIN-REGEX'),
|
||||||
GEOSITE("GEOSITE"),
|
GEOSITE('GEOSITE'),
|
||||||
IP_CIDR("IP-CIDR"),
|
IP_CIDR('IP-CIDR'),
|
||||||
IP_CIDR6("IP-CIDR6"),
|
IP_CIDR6('IP-CIDR6'),
|
||||||
IP_SUFFIX("IP-SUFFIX"),
|
IP_SUFFIX('IP-SUFFIX'),
|
||||||
IP_ASN("IP-ASN"),
|
IP_ASN('IP-ASN'),
|
||||||
GEOIP("GEOIP"),
|
GEOIP('GEOIP'),
|
||||||
SRC_GEOIP("SRC-GEOIP"),
|
SRC_GEOIP('SRC-GEOIP'),
|
||||||
SRC_IP_ASN("SRC-IP-ASN"),
|
SRC_IP_ASN('SRC-IP-ASN'),
|
||||||
SRC_IP_CIDR("SRC-IP-CIDR"),
|
SRC_IP_CIDR('SRC-IP-CIDR'),
|
||||||
SRC_IP_SUFFIX("SRC-IP-SUFFIX"),
|
SRC_IP_SUFFIX('SRC-IP-SUFFIX'),
|
||||||
DST_PORT("DST-PORT"),
|
DST_PORT('DST-PORT'),
|
||||||
SRC_PORT("SRC-PORT"),
|
SRC_PORT('SRC-PORT'),
|
||||||
IN_PORT("IN-PORT"),
|
IN_PORT('IN-PORT'),
|
||||||
IN_TYPE("IN-TYPE"),
|
IN_TYPE('IN-TYPE'),
|
||||||
IN_USER("IN-USER"),
|
IN_USER('IN-USER'),
|
||||||
IN_NAME("IN-NAME"),
|
IN_NAME('IN-NAME'),
|
||||||
PROCESS_PATH("PROCESS-PATH"),
|
PROCESS_PATH('PROCESS-PATH'),
|
||||||
PROCESS_PATH_REGEX("PROCESS-PATH-REGEX"),
|
PROCESS_PATH_REGEX('PROCESS-PATH-REGEX'),
|
||||||
PROCESS_NAME("PROCESS-NAME"),
|
PROCESS_NAME('PROCESS-NAME'),
|
||||||
PROCESS_NAME_REGEX("PROCESS-NAME-REGEX"),
|
PROCESS_NAME_REGEX('PROCESS-NAME-REGEX'),
|
||||||
UID("UID"),
|
UID('UID'),
|
||||||
NETWORK("NETWORK"),
|
NETWORK('NETWORK'),
|
||||||
DSCP("DSCP"),
|
DSCP('DSCP'),
|
||||||
RULE_SET("RULE-SET"),
|
RULE_SET('RULE-SET'),
|
||||||
AND("AND"),
|
AND('AND'),
|
||||||
OR("OR"),
|
OR('OR'),
|
||||||
NOT("NOT"),
|
NOT('NOT'),
|
||||||
SUB_RULE("SUB-RULE"),
|
SUB_RULE('SUB-RULE'),
|
||||||
MATCH("MATCH");
|
MATCH('MATCH');
|
||||||
|
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
@@ -493,6 +507,7 @@ enum CacheTag {
|
|||||||
logs,
|
logs,
|
||||||
rules,
|
rules,
|
||||||
requests,
|
requests,
|
||||||
|
proxiesList,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Language {
|
enum Language {
|
||||||
@@ -504,3 +519,10 @@ enum ImportOption {
|
|||||||
file,
|
file,
|
||||||
url,
|
url,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ScrollPositionCacheKeys {
|
||||||
|
tools,
|
||||||
|
profiles,
|
||||||
|
proxiesList,
|
||||||
|
proxiesTabList,
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,19 +26,21 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
static String m1(label) =>
|
static String m1(label) =>
|
||||||
"Are you sure you want to delete the current ${label}?";
|
"Are you sure you want to delete the current ${label}?";
|
||||||
|
|
||||||
static String m2(label) => "${label} cannot be empty";
|
static String m2(label) => "${label} details";
|
||||||
|
|
||||||
static String m3(label) => "Current ${label} already exists";
|
static String m3(label) => "${label} cannot be empty";
|
||||||
|
|
||||||
static String m4(label) => "No ${label} at the moment";
|
static String m4(label) => "Current ${label} already exists";
|
||||||
|
|
||||||
static String m5(label) => "${label} must be a number";
|
static String m5(label) => "No ${label} at the moment";
|
||||||
|
|
||||||
static String m6(label) => "${label} must be between 1024 and 49151";
|
static String m6(label) => "${label} must be a number";
|
||||||
|
|
||||||
static String m7(count) => "${count} items have been selected";
|
static String m7(label) => "${label} must be between 1024 and 49151";
|
||||||
|
|
||||||
static String m8(label) => "${label} must be a url";
|
static String m8(count) => "${count} items have been selected";
|
||||||
|
|
||||||
|
static String m9(label) => "${label} must be a url";
|
||||||
|
|
||||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
@@ -175,6 +177,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Opening it will lose part of its application ability and gain the support of full amount of Clash.",
|
"Opening it will lose part of its application ability and gain the support of full amount of Clash.",
|
||||||
),
|
),
|
||||||
"confirm": MessageLookupByLibrary.simpleMessage("Confirm"),
|
"confirm": MessageLookupByLibrary.simpleMessage("Confirm"),
|
||||||
|
"connection": MessageLookupByLibrary.simpleMessage("Connection"),
|
||||||
"connections": MessageLookupByLibrary.simpleMessage("Connections"),
|
"connections": MessageLookupByLibrary.simpleMessage("Connections"),
|
||||||
"connectionsDesc": MessageLookupByLibrary.simpleMessage(
|
"connectionsDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"View current connections data",
|
"View current connections data",
|
||||||
@@ -194,6 +197,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"country": MessageLookupByLibrary.simpleMessage("Country"),
|
"country": MessageLookupByLibrary.simpleMessage("Country"),
|
||||||
"crashTest": MessageLookupByLibrary.simpleMessage("Crash test"),
|
"crashTest": MessageLookupByLibrary.simpleMessage("Crash test"),
|
||||||
"create": MessageLookupByLibrary.simpleMessage("Create"),
|
"create": MessageLookupByLibrary.simpleMessage("Create"),
|
||||||
|
"creationTime": MessageLookupByLibrary.simpleMessage("Creation time"),
|
||||||
"cut": MessageLookupByLibrary.simpleMessage("Cut"),
|
"cut": MessageLookupByLibrary.simpleMessage("Cut"),
|
||||||
"dark": MessageLookupByLibrary.simpleMessage("Dark"),
|
"dark": MessageLookupByLibrary.simpleMessage("Dark"),
|
||||||
"dashboard": MessageLookupByLibrary.simpleMessage("Dashboard"),
|
"dashboard": MessageLookupByLibrary.simpleMessage("Dashboard"),
|
||||||
@@ -214,6 +218,14 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"desc": MessageLookupByLibrary.simpleMessage(
|
"desc": MessageLookupByLibrary.simpleMessage(
|
||||||
"A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.",
|
"A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.",
|
||||||
),
|
),
|
||||||
|
"destination": MessageLookupByLibrary.simpleMessage("Destination"),
|
||||||
|
"destinationGeoIP": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Destination GeoIP",
|
||||||
|
),
|
||||||
|
"destinationIPASN": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Destination IPASN",
|
||||||
|
),
|
||||||
|
"details": m2,
|
||||||
"detectionTip": MessageLookupByLibrary.simpleMessage(
|
"detectionTip": MessageLookupByLibrary.simpleMessage(
|
||||||
"Relying on third-party api is for reference only",
|
"Relying on third-party api is for reference only",
|
||||||
),
|
),
|
||||||
@@ -242,7 +254,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"domain": MessageLookupByLibrary.simpleMessage("Domain"),
|
"domain": MessageLookupByLibrary.simpleMessage("Domain"),
|
||||||
"download": MessageLookupByLibrary.simpleMessage("Download"),
|
"download": MessageLookupByLibrary.simpleMessage("Download"),
|
||||||
"edit": MessageLookupByLibrary.simpleMessage("Edit"),
|
"edit": MessageLookupByLibrary.simpleMessage("Edit"),
|
||||||
"emptyTip": m2,
|
"emptyTip": m3,
|
||||||
"en": MessageLookupByLibrary.simpleMessage("English"),
|
"en": MessageLookupByLibrary.simpleMessage("English"),
|
||||||
"enableOverride": MessageLookupByLibrary.simpleMessage("Enable override"),
|
"enableOverride": MessageLookupByLibrary.simpleMessage("Enable override"),
|
||||||
"entries": MessageLookupByLibrary.simpleMessage(" entries"),
|
"entries": MessageLookupByLibrary.simpleMessage(" entries"),
|
||||||
@@ -250,7 +262,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"excludeDesc": MessageLookupByLibrary.simpleMessage(
|
"excludeDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"When the app is in the background, the app is hidden from the recent task",
|
"When the app is in the background, the app is hidden from the recent task",
|
||||||
),
|
),
|
||||||
"existsTip": m3,
|
"existsTip": m4,
|
||||||
"exit": MessageLookupByLibrary.simpleMessage("Exit"),
|
"exit": MessageLookupByLibrary.simpleMessage("Exit"),
|
||||||
"expand": MessageLookupByLibrary.simpleMessage("Standard"),
|
"expand": MessageLookupByLibrary.simpleMessage("Standard"),
|
||||||
"expirationTime": MessageLookupByLibrary.simpleMessage("Expiration time"),
|
"expirationTime": MessageLookupByLibrary.simpleMessage("Expiration time"),
|
||||||
@@ -312,6 +324,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"hasCacheChange": MessageLookupByLibrary.simpleMessage(
|
"hasCacheChange": MessageLookupByLibrary.simpleMessage(
|
||||||
"Do you want to cache the changes?",
|
"Do you want to cache the changes?",
|
||||||
),
|
),
|
||||||
|
"host": MessageLookupByLibrary.simpleMessage("Host"),
|
||||||
"hostsDesc": MessageLookupByLibrary.simpleMessage("Add Hosts"),
|
"hostsDesc": MessageLookupByLibrary.simpleMessage("Add Hosts"),
|
||||||
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("Hotkey conflict"),
|
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("Hotkey conflict"),
|
||||||
"hotkeyManagement": MessageLookupByLibrary.simpleMessage(
|
"hotkeyManagement": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -366,6 +379,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Recovery data from file",
|
"Recovery data from file",
|
||||||
),
|
),
|
||||||
|
"log": MessageLookupByLibrary.simpleMessage("Log"),
|
||||||
"logLevel": MessageLookupByLibrary.simpleMessage("LogLevel"),
|
"logLevel": MessageLookupByLibrary.simpleMessage("LogLevel"),
|
||||||
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
|
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
|
||||||
"logcatDesc": MessageLookupByLibrary.simpleMessage(
|
"logcatDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -415,6 +429,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Network detection",
|
"Network detection",
|
||||||
),
|
),
|
||||||
"networkSpeed": MessageLookupByLibrary.simpleMessage("Network speed"),
|
"networkSpeed": MessageLookupByLibrary.simpleMessage("Network speed"),
|
||||||
|
"networkType": MessageLookupByLibrary.simpleMessage("Network type"),
|
||||||
"neutralScheme": MessageLookupByLibrary.simpleMessage("Neutral"),
|
"neutralScheme": MessageLookupByLibrary.simpleMessage("Neutral"),
|
||||||
"noData": MessageLookupByLibrary.simpleMessage("No data"),
|
"noData": MessageLookupByLibrary.simpleMessage("No data"),
|
||||||
"noHotKey": MessageLookupByLibrary.simpleMessage("No HotKey"),
|
"noHotKey": MessageLookupByLibrary.simpleMessage("No HotKey"),
|
||||||
@@ -435,8 +450,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
|
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"No profile, Please add a profile",
|
"No profile, Please add a profile",
|
||||||
),
|
),
|
||||||
"nullTip": m4,
|
"nullTip": m5,
|
||||||
"numberTip": m5,
|
"numberTip": m6,
|
||||||
"oneColumn": MessageLookupByLibrary.simpleMessage("One column"),
|
"oneColumn": MessageLookupByLibrary.simpleMessage("One column"),
|
||||||
"onlyIcon": MessageLookupByLibrary.simpleMessage("Icon"),
|
"onlyIcon": MessageLookupByLibrary.simpleMessage("Icon"),
|
||||||
"onlyOtherApps": MessageLookupByLibrary.simpleMessage(
|
"onlyOtherApps": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -490,7 +505,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"portConflictTip": MessageLookupByLibrary.simpleMessage(
|
"portConflictTip": MessageLookupByLibrary.simpleMessage(
|
||||||
"Please enter a different port",
|
"Please enter a different port",
|
||||||
),
|
),
|
||||||
"portTip": m6,
|
"portTip": m7,
|
||||||
"preferH3Desc": MessageLookupByLibrary.simpleMessage(
|
"preferH3Desc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Prioritize the use of DOH\'s http/3",
|
"Prioritize the use of DOH\'s http/3",
|
||||||
),
|
),
|
||||||
@@ -524,10 +539,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
),
|
),
|
||||||
"profiles": MessageLookupByLibrary.simpleMessage("Profiles"),
|
"profiles": MessageLookupByLibrary.simpleMessage("Profiles"),
|
||||||
"profilesSort": MessageLookupByLibrary.simpleMessage("Profiles sort"),
|
"profilesSort": MessageLookupByLibrary.simpleMessage("Profiles sort"),
|
||||||
|
"progress": MessageLookupByLibrary.simpleMessage("Progress"),
|
||||||
"project": MessageLookupByLibrary.simpleMessage("Project"),
|
"project": MessageLookupByLibrary.simpleMessage("Project"),
|
||||||
"providers": MessageLookupByLibrary.simpleMessage("Providers"),
|
"providers": MessageLookupByLibrary.simpleMessage("Providers"),
|
||||||
"proxies": MessageLookupByLibrary.simpleMessage("Proxies"),
|
"proxies": MessageLookupByLibrary.simpleMessage("Proxies"),
|
||||||
"proxiesSetting": MessageLookupByLibrary.simpleMessage("Proxies setting"),
|
"proxiesSetting": MessageLookupByLibrary.simpleMessage("Proxies setting"),
|
||||||
|
"proxyChains": MessageLookupByLibrary.simpleMessage("Proxy chains"),
|
||||||
"proxyGroup": MessageLookupByLibrary.simpleMessage("Proxy group"),
|
"proxyGroup": MessageLookupByLibrary.simpleMessage("Proxy group"),
|
||||||
"proxyNameserver": MessageLookupByLibrary.simpleMessage("Proxy nameserver"),
|
"proxyNameserver": MessageLookupByLibrary.simpleMessage("Proxy nameserver"),
|
||||||
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage(
|
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -566,11 +583,15 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
|
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Backup local data to WebDAV",
|
"Backup local data to WebDAV",
|
||||||
),
|
),
|
||||||
|
"remoteDestination": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Remote destination",
|
||||||
|
),
|
||||||
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Recovery data from WebDAV",
|
"Recovery data from WebDAV",
|
||||||
),
|
),
|
||||||
"remove": MessageLookupByLibrary.simpleMessage("Remove"),
|
"remove": MessageLookupByLibrary.simpleMessage("Remove"),
|
||||||
"rename": MessageLookupByLibrary.simpleMessage("Rename"),
|
"rename": MessageLookupByLibrary.simpleMessage("Rename"),
|
||||||
|
"request": MessageLookupByLibrary.simpleMessage("Request"),
|
||||||
"requests": MessageLookupByLibrary.simpleMessage("Requests"),
|
"requests": MessageLookupByLibrary.simpleMessage("Requests"),
|
||||||
"requestsDesc": MessageLookupByLibrary.simpleMessage(
|
"requestsDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"View recently request records",
|
"View recently request records",
|
||||||
@@ -611,7 +632,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"seconds": MessageLookupByLibrary.simpleMessage("Seconds"),
|
"seconds": MessageLookupByLibrary.simpleMessage("Seconds"),
|
||||||
"selectAll": MessageLookupByLibrary.simpleMessage("Select all"),
|
"selectAll": MessageLookupByLibrary.simpleMessage("Select all"),
|
||||||
"selected": MessageLookupByLibrary.simpleMessage("Selected"),
|
"selected": MessageLookupByLibrary.simpleMessage("Selected"),
|
||||||
"selectedCountTitle": m7,
|
"selectedCountTitle": m8,
|
||||||
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
|
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
|
||||||
"show": MessageLookupByLibrary.simpleMessage("Show"),
|
"show": MessageLookupByLibrary.simpleMessage("Show"),
|
||||||
"shrink": MessageLookupByLibrary.simpleMessage("Shrink"),
|
"shrink": MessageLookupByLibrary.simpleMessage("Shrink"),
|
||||||
@@ -624,6 +645,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"sort": MessageLookupByLibrary.simpleMessage("Sort"),
|
"sort": MessageLookupByLibrary.simpleMessage("Sort"),
|
||||||
"source": MessageLookupByLibrary.simpleMessage("Source"),
|
"source": MessageLookupByLibrary.simpleMessage("Source"),
|
||||||
"sourceIp": MessageLookupByLibrary.simpleMessage("Source IP"),
|
"sourceIp": MessageLookupByLibrary.simpleMessage("Source IP"),
|
||||||
|
"specialProxy": MessageLookupByLibrary.simpleMessage("Special proxy"),
|
||||||
|
"specialRules": MessageLookupByLibrary.simpleMessage("special rules"),
|
||||||
"stackMode": MessageLookupByLibrary.simpleMessage("Stack mode"),
|
"stackMode": MessageLookupByLibrary.simpleMessage("Stack mode"),
|
||||||
"standard": MessageLookupByLibrary.simpleMessage("Standard"),
|
"standard": MessageLookupByLibrary.simpleMessage("Standard"),
|
||||||
"start": MessageLookupByLibrary.simpleMessage("Start"),
|
"start": MessageLookupByLibrary.simpleMessage("Start"),
|
||||||
@@ -692,7 +715,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"urlDesc": MessageLookupByLibrary.simpleMessage(
|
"urlDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Obtain profile through URL",
|
"Obtain profile through URL",
|
||||||
),
|
),
|
||||||
"urlTip": m8,
|
"urlTip": m9,
|
||||||
"useHosts": MessageLookupByLibrary.simpleMessage("Use hosts"),
|
"useHosts": MessageLookupByLibrary.simpleMessage("Use hosts"),
|
||||||
"useSystemHosts": MessageLookupByLibrary.simpleMessage("Use system hosts"),
|
"useSystemHosts": MessageLookupByLibrary.simpleMessage("Use system hosts"),
|
||||||
"value": MessageLookupByLibrary.simpleMessage("Value"),
|
"value": MessageLookupByLibrary.simpleMessage("Value"),
|
||||||
|
|||||||
@@ -24,19 +24,21 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
|
|
||||||
static String m1(label) => "現在の${label}を削除してもよろしいですか?";
|
static String m1(label) => "現在の${label}を削除してもよろしいですか?";
|
||||||
|
|
||||||
static String m2(label) => "${label}は空欄にできません";
|
static String m2(label) => "${label}詳細";
|
||||||
|
|
||||||
static String m3(label) => "現在の${label}は既に存在しています";
|
static String m3(label) => "${label}は空欄にできません";
|
||||||
|
|
||||||
static String m4(label) => "現在${label}はありません";
|
static String m4(label) => "現在の${label}は既に存在しています";
|
||||||
|
|
||||||
static String m5(label) => "${label}は数字でなければなりません";
|
static String m5(label) => "現在${label}はありません";
|
||||||
|
|
||||||
static String m6(label) => "${label} は 1024 から 49151 の間でなければなりません";
|
static String m6(label) => "${label}は数字でなければなりません";
|
||||||
|
|
||||||
static String m7(count) => "${count} 項目が選択されています";
|
static String m7(label) => "${label} は 1024 から 49151 の間でなければなりません";
|
||||||
|
|
||||||
static String m8(label) => "${label}はURLである必要があります";
|
static String m8(count) => "${count} 項目が選択されています";
|
||||||
|
|
||||||
|
static String m9(label) => "${label}はURLである必要があります";
|
||||||
|
|
||||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
@@ -131,6 +133,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"有効化すると一部機能を失いますが、Clashの完全サポートを獲得",
|
"有効化すると一部機能を失いますが、Clashの完全サポートを獲得",
|
||||||
),
|
),
|
||||||
"confirm": MessageLookupByLibrary.simpleMessage("確認"),
|
"confirm": MessageLookupByLibrary.simpleMessage("確認"),
|
||||||
|
"connection": MessageLookupByLibrary.simpleMessage("接続"),
|
||||||
"connections": MessageLookupByLibrary.simpleMessage("接続"),
|
"connections": MessageLookupByLibrary.simpleMessage("接続"),
|
||||||
"connectionsDesc": MessageLookupByLibrary.simpleMessage("現在の接続データを表示"),
|
"connectionsDesc": MessageLookupByLibrary.simpleMessage("現在の接続データを表示"),
|
||||||
"connectivity": MessageLookupByLibrary.simpleMessage("接続性:"),
|
"connectivity": MessageLookupByLibrary.simpleMessage("接続性:"),
|
||||||
@@ -146,6 +149,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"country": MessageLookupByLibrary.simpleMessage("国"),
|
"country": MessageLookupByLibrary.simpleMessage("国"),
|
||||||
"crashTest": MessageLookupByLibrary.simpleMessage("クラッシュテスト"),
|
"crashTest": MessageLookupByLibrary.simpleMessage("クラッシュテスト"),
|
||||||
"create": MessageLookupByLibrary.simpleMessage("作成"),
|
"create": MessageLookupByLibrary.simpleMessage("作成"),
|
||||||
|
"creationTime": MessageLookupByLibrary.simpleMessage("作成時間"),
|
||||||
"cut": MessageLookupByLibrary.simpleMessage("切り取り"),
|
"cut": MessageLookupByLibrary.simpleMessage("切り取り"),
|
||||||
"dark": MessageLookupByLibrary.simpleMessage("ダーク"),
|
"dark": MessageLookupByLibrary.simpleMessage("ダーク"),
|
||||||
"dashboard": MessageLookupByLibrary.simpleMessage("ダッシュボード"),
|
"dashboard": MessageLookupByLibrary.simpleMessage("ダッシュボード"),
|
||||||
@@ -164,6 +168,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"desc": MessageLookupByLibrary.simpleMessage(
|
"desc": MessageLookupByLibrary.simpleMessage(
|
||||||
"ClashMetaベースのマルチプラットフォームプロキシクライアント。シンプルで使いやすく、オープンソースで広告なし。",
|
"ClashMetaベースのマルチプラットフォームプロキシクライアント。シンプルで使いやすく、オープンソースで広告なし。",
|
||||||
),
|
),
|
||||||
|
"destination": MessageLookupByLibrary.simpleMessage("宛先"),
|
||||||
|
"destinationGeoIP": MessageLookupByLibrary.simpleMessage("宛先地理情報"),
|
||||||
|
"destinationIPASN": MessageLookupByLibrary.simpleMessage("宛先IP ASN"),
|
||||||
|
"details": m2,
|
||||||
"detectionTip": MessageLookupByLibrary.simpleMessage("サードパーティAPIに依存(参考値)"),
|
"detectionTip": MessageLookupByLibrary.simpleMessage("サードパーティAPIに依存(参考値)"),
|
||||||
"developerMode": MessageLookupByLibrary.simpleMessage("デベロッパーモード"),
|
"developerMode": MessageLookupByLibrary.simpleMessage("デベロッパーモード"),
|
||||||
"developerModeEnableTip": MessageLookupByLibrary.simpleMessage(
|
"developerModeEnableTip": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -182,7 +190,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"domain": MessageLookupByLibrary.simpleMessage("ドメイン"),
|
"domain": MessageLookupByLibrary.simpleMessage("ドメイン"),
|
||||||
"download": MessageLookupByLibrary.simpleMessage("ダウンロード"),
|
"download": MessageLookupByLibrary.simpleMessage("ダウンロード"),
|
||||||
"edit": MessageLookupByLibrary.simpleMessage("編集"),
|
"edit": MessageLookupByLibrary.simpleMessage("編集"),
|
||||||
"emptyTip": m2,
|
"emptyTip": m3,
|
||||||
"en": MessageLookupByLibrary.simpleMessage("英語"),
|
"en": MessageLookupByLibrary.simpleMessage("英語"),
|
||||||
"enableOverride": MessageLookupByLibrary.simpleMessage("上書きを有効化"),
|
"enableOverride": MessageLookupByLibrary.simpleMessage("上書きを有効化"),
|
||||||
"entries": MessageLookupByLibrary.simpleMessage(" エントリ"),
|
"entries": MessageLookupByLibrary.simpleMessage(" エントリ"),
|
||||||
@@ -190,7 +198,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"excludeDesc": MessageLookupByLibrary.simpleMessage(
|
"excludeDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"アプリがバックグラウンド時に最近のタスクから非表示",
|
"アプリがバックグラウンド時に最近のタスクから非表示",
|
||||||
),
|
),
|
||||||
"existsTip": m3,
|
"existsTip": m4,
|
||||||
"exit": MessageLookupByLibrary.simpleMessage("終了"),
|
"exit": MessageLookupByLibrary.simpleMessage("終了"),
|
||||||
"expand": MessageLookupByLibrary.simpleMessage("標準"),
|
"expand": MessageLookupByLibrary.simpleMessage("標準"),
|
||||||
"expirationTime": MessageLookupByLibrary.simpleMessage("有効期限"),
|
"expirationTime": MessageLookupByLibrary.simpleMessage("有効期限"),
|
||||||
@@ -236,6 +244,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"go": MessageLookupByLibrary.simpleMessage("移動"),
|
"go": MessageLookupByLibrary.simpleMessage("移動"),
|
||||||
"goDownload": MessageLookupByLibrary.simpleMessage("ダウンロードへ"),
|
"goDownload": MessageLookupByLibrary.simpleMessage("ダウンロードへ"),
|
||||||
"hasCacheChange": MessageLookupByLibrary.simpleMessage("変更をキャッシュしますか?"),
|
"hasCacheChange": MessageLookupByLibrary.simpleMessage("変更をキャッシュしますか?"),
|
||||||
|
"host": MessageLookupByLibrary.simpleMessage("ホスト"),
|
||||||
"hostsDesc": MessageLookupByLibrary.simpleMessage("ホストを追加"),
|
"hostsDesc": MessageLookupByLibrary.simpleMessage("ホストを追加"),
|
||||||
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("ホットキー競合"),
|
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("ホットキー競合"),
|
||||||
"hotkeyManagement": MessageLookupByLibrary.simpleMessage("ホットキー管理"),
|
"hotkeyManagement": MessageLookupByLibrary.simpleMessage("ホットキー管理"),
|
||||||
@@ -274,6 +283,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"local": MessageLookupByLibrary.simpleMessage("ローカル"),
|
"local": MessageLookupByLibrary.simpleMessage("ローカル"),
|
||||||
"localBackupDesc": MessageLookupByLibrary.simpleMessage("ローカルにデータをバックアップ"),
|
"localBackupDesc": MessageLookupByLibrary.simpleMessage("ローカルにデータをバックアップ"),
|
||||||
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("ファイルからデータを復元"),
|
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("ファイルからデータを復元"),
|
||||||
|
"log": MessageLookupByLibrary.simpleMessage("ログ"),
|
||||||
"logLevel": MessageLookupByLibrary.simpleMessage("ログレベル"),
|
"logLevel": MessageLookupByLibrary.simpleMessage("ログレベル"),
|
||||||
"logcat": MessageLookupByLibrary.simpleMessage("ログキャット"),
|
"logcat": MessageLookupByLibrary.simpleMessage("ログキャット"),
|
||||||
"logcatDesc": MessageLookupByLibrary.simpleMessage("無効化するとログエントリを非表示"),
|
"logcatDesc": MessageLookupByLibrary.simpleMessage("無効化するとログエントリを非表示"),
|
||||||
@@ -309,6 +319,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"networkDesc": MessageLookupByLibrary.simpleMessage("ネットワーク関連設定の変更"),
|
"networkDesc": MessageLookupByLibrary.simpleMessage("ネットワーク関連設定の変更"),
|
||||||
"networkDetection": MessageLookupByLibrary.simpleMessage("ネットワーク検出"),
|
"networkDetection": MessageLookupByLibrary.simpleMessage("ネットワーク検出"),
|
||||||
"networkSpeed": MessageLookupByLibrary.simpleMessage("ネットワーク速度"),
|
"networkSpeed": MessageLookupByLibrary.simpleMessage("ネットワーク速度"),
|
||||||
|
"networkType": MessageLookupByLibrary.simpleMessage("ネットワーク種別"),
|
||||||
"neutralScheme": MessageLookupByLibrary.simpleMessage("ニュートラル"),
|
"neutralScheme": MessageLookupByLibrary.simpleMessage("ニュートラル"),
|
||||||
"noData": MessageLookupByLibrary.simpleMessage("データなし"),
|
"noData": MessageLookupByLibrary.simpleMessage("データなし"),
|
||||||
"noHotKey": MessageLookupByLibrary.simpleMessage("ホットキーなし"),
|
"noHotKey": MessageLookupByLibrary.simpleMessage("ホットキーなし"),
|
||||||
@@ -329,8 +340,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
|
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"プロファイルがありません。追加してください",
|
"プロファイルがありません。追加してください",
|
||||||
),
|
),
|
||||||
"nullTip": m4,
|
"nullTip": m5,
|
||||||
"numberTip": m5,
|
"numberTip": m6,
|
||||||
"oneColumn": MessageLookupByLibrary.simpleMessage("1列"),
|
"oneColumn": MessageLookupByLibrary.simpleMessage("1列"),
|
||||||
"onlyIcon": MessageLookupByLibrary.simpleMessage("アイコンのみ"),
|
"onlyIcon": MessageLookupByLibrary.simpleMessage("アイコンのみ"),
|
||||||
"onlyOtherApps": MessageLookupByLibrary.simpleMessage("サードパーティアプリのみ"),
|
"onlyOtherApps": MessageLookupByLibrary.simpleMessage("サードパーティアプリのみ"),
|
||||||
@@ -372,7 +383,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
),
|
),
|
||||||
"port": MessageLookupByLibrary.simpleMessage("ポート"),
|
"port": MessageLookupByLibrary.simpleMessage("ポート"),
|
||||||
"portConflictTip": MessageLookupByLibrary.simpleMessage("別のポートを入力してください"),
|
"portConflictTip": MessageLookupByLibrary.simpleMessage("別のポートを入力してください"),
|
||||||
"portTip": m6,
|
"portTip": m7,
|
||||||
"preferH3Desc": MessageLookupByLibrary.simpleMessage("DOHのHTTP/3を優先使用"),
|
"preferH3Desc": MessageLookupByLibrary.simpleMessage("DOHのHTTP/3を優先使用"),
|
||||||
"pressKeyboard": MessageLookupByLibrary.simpleMessage("キーボードを押してください"),
|
"pressKeyboard": MessageLookupByLibrary.simpleMessage("キーボードを押してください"),
|
||||||
"preview": MessageLookupByLibrary.simpleMessage("プレビュー"),
|
"preview": MessageLookupByLibrary.simpleMessage("プレビュー"),
|
||||||
@@ -398,10 +409,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
),
|
),
|
||||||
"profiles": MessageLookupByLibrary.simpleMessage("プロファイル一覧"),
|
"profiles": MessageLookupByLibrary.simpleMessage("プロファイル一覧"),
|
||||||
"profilesSort": MessageLookupByLibrary.simpleMessage("プロファイルの並び替え"),
|
"profilesSort": MessageLookupByLibrary.simpleMessage("プロファイルの並び替え"),
|
||||||
|
"progress": MessageLookupByLibrary.simpleMessage("進捗"),
|
||||||
"project": MessageLookupByLibrary.simpleMessage("プロジェクト"),
|
"project": MessageLookupByLibrary.simpleMessage("プロジェクト"),
|
||||||
"providers": MessageLookupByLibrary.simpleMessage("プロバイダー"),
|
"providers": MessageLookupByLibrary.simpleMessage("プロバイダー"),
|
||||||
"proxies": MessageLookupByLibrary.simpleMessage("プロキシ"),
|
"proxies": MessageLookupByLibrary.simpleMessage("プロキシ"),
|
||||||
"proxiesSetting": MessageLookupByLibrary.simpleMessage("プロキシ設定"),
|
"proxiesSetting": MessageLookupByLibrary.simpleMessage("プロキシ設定"),
|
||||||
|
"proxyChains": MessageLookupByLibrary.simpleMessage("プロキシチェーン"),
|
||||||
"proxyGroup": MessageLookupByLibrary.simpleMessage("プロキシグループ"),
|
"proxyGroup": MessageLookupByLibrary.simpleMessage("プロキシグループ"),
|
||||||
"proxyNameserver": MessageLookupByLibrary.simpleMessage("プロキシネームサーバー"),
|
"proxyNameserver": MessageLookupByLibrary.simpleMessage("プロキシネームサーバー"),
|
||||||
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage(
|
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -430,11 +443,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
|
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"WebDAVにデータをバックアップ",
|
"WebDAVにデータをバックアップ",
|
||||||
),
|
),
|
||||||
|
"remoteDestination": MessageLookupByLibrary.simpleMessage("リモート宛先"),
|
||||||
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"WebDAVからデータを復元",
|
"WebDAVからデータを復元",
|
||||||
),
|
),
|
||||||
"remove": MessageLookupByLibrary.simpleMessage("削除"),
|
"remove": MessageLookupByLibrary.simpleMessage("削除"),
|
||||||
"rename": MessageLookupByLibrary.simpleMessage("リネーム"),
|
"rename": MessageLookupByLibrary.simpleMessage("リネーム"),
|
||||||
|
"request": MessageLookupByLibrary.simpleMessage("リクエスト"),
|
||||||
"requests": MessageLookupByLibrary.simpleMessage("リクエスト"),
|
"requests": MessageLookupByLibrary.simpleMessage("リクエスト"),
|
||||||
"requestsDesc": MessageLookupByLibrary.simpleMessage("最近のリクエスト記録を表示"),
|
"requestsDesc": MessageLookupByLibrary.simpleMessage("最近のリクエスト記録を表示"),
|
||||||
"reset": MessageLookupByLibrary.simpleMessage("リセット"),
|
"reset": MessageLookupByLibrary.simpleMessage("リセット"),
|
||||||
@@ -465,7 +480,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"seconds": MessageLookupByLibrary.simpleMessage("秒"),
|
"seconds": MessageLookupByLibrary.simpleMessage("秒"),
|
||||||
"selectAll": MessageLookupByLibrary.simpleMessage("すべて選択"),
|
"selectAll": MessageLookupByLibrary.simpleMessage("すべて選択"),
|
||||||
"selected": MessageLookupByLibrary.simpleMessage("選択済み"),
|
"selected": MessageLookupByLibrary.simpleMessage("選択済み"),
|
||||||
"selectedCountTitle": m7,
|
"selectedCountTitle": m8,
|
||||||
"settings": MessageLookupByLibrary.simpleMessage("設定"),
|
"settings": MessageLookupByLibrary.simpleMessage("設定"),
|
||||||
"show": MessageLookupByLibrary.simpleMessage("表示"),
|
"show": MessageLookupByLibrary.simpleMessage("表示"),
|
||||||
"shrink": MessageLookupByLibrary.simpleMessage("縮小"),
|
"shrink": MessageLookupByLibrary.simpleMessage("縮小"),
|
||||||
@@ -476,6 +491,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"sort": MessageLookupByLibrary.simpleMessage("並び替え"),
|
"sort": MessageLookupByLibrary.simpleMessage("並び替え"),
|
||||||
"source": MessageLookupByLibrary.simpleMessage("ソース"),
|
"source": MessageLookupByLibrary.simpleMessage("ソース"),
|
||||||
"sourceIp": MessageLookupByLibrary.simpleMessage("送信元IP"),
|
"sourceIp": MessageLookupByLibrary.simpleMessage("送信元IP"),
|
||||||
|
"specialProxy": MessageLookupByLibrary.simpleMessage("特殊プロキシ"),
|
||||||
|
"specialRules": MessageLookupByLibrary.simpleMessage("特殊ルール"),
|
||||||
"stackMode": MessageLookupByLibrary.simpleMessage("スタックモード"),
|
"stackMode": MessageLookupByLibrary.simpleMessage("スタックモード"),
|
||||||
"standard": MessageLookupByLibrary.simpleMessage("標準"),
|
"standard": MessageLookupByLibrary.simpleMessage("標準"),
|
||||||
"start": MessageLookupByLibrary.simpleMessage("開始"),
|
"start": MessageLookupByLibrary.simpleMessage("開始"),
|
||||||
@@ -532,7 +549,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"upload": MessageLookupByLibrary.simpleMessage("アップロード"),
|
"upload": MessageLookupByLibrary.simpleMessage("アップロード"),
|
||||||
"url": MessageLookupByLibrary.simpleMessage("URL"),
|
"url": MessageLookupByLibrary.simpleMessage("URL"),
|
||||||
"urlDesc": MessageLookupByLibrary.simpleMessage("URL経由でプロファイルを取得"),
|
"urlDesc": MessageLookupByLibrary.simpleMessage("URL経由でプロファイルを取得"),
|
||||||
"urlTip": m8,
|
"urlTip": m9,
|
||||||
"useHosts": MessageLookupByLibrary.simpleMessage("ホストを使用"),
|
"useHosts": MessageLookupByLibrary.simpleMessage("ホストを使用"),
|
||||||
"useSystemHosts": MessageLookupByLibrary.simpleMessage("システムホストを使用"),
|
"useSystemHosts": MessageLookupByLibrary.simpleMessage("システムホストを使用"),
|
||||||
"value": MessageLookupByLibrary.simpleMessage("値"),
|
"value": MessageLookupByLibrary.simpleMessage("値"),
|
||||||
|
|||||||
@@ -25,19 +25,21 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
|
|
||||||
static String m1(label) => "Вы уверены, что хотите удалить текущий ${label}?";
|
static String m1(label) => "Вы уверены, что хотите удалить текущий ${label}?";
|
||||||
|
|
||||||
static String m2(label) => "${label} не может быть пустым";
|
static String m2(label) => "Детали {}";
|
||||||
|
|
||||||
static String m3(label) => "Текущий ${label} уже существует";
|
static String m3(label) => "${label} не может быть пустым";
|
||||||
|
|
||||||
static String m4(label) => "Сейчас ${label} нет";
|
static String m4(label) => "Текущий ${label} уже существует";
|
||||||
|
|
||||||
static String m5(label) => "${label} должно быть числом";
|
static String m5(label) => "Сейчас ${label} нет";
|
||||||
|
|
||||||
static String m6(label) => "${label} должен быть числом от 1024 до 49151";
|
static String m6(label) => "${label} должно быть числом";
|
||||||
|
|
||||||
static String m7(count) => "Выбрано ${count} элементов";
|
static String m7(label) => "${label} должен быть числом от 1024 до 49151";
|
||||||
|
|
||||||
static String m8(label) => "${label} должен быть URL";
|
static String m8(count) => "Выбрано ${count} элементов";
|
||||||
|
|
||||||
|
static String m9(label) => "${label} должен быть URL";
|
||||||
|
|
||||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
@@ -180,6 +182,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Включение приведет к потере части функциональности приложения, но обеспечит полную поддержку Clash.",
|
"Включение приведет к потере части функциональности приложения, но обеспечит полную поддержку Clash.",
|
||||||
),
|
),
|
||||||
"confirm": MessageLookupByLibrary.simpleMessage("Подтвердить"),
|
"confirm": MessageLookupByLibrary.simpleMessage("Подтвердить"),
|
||||||
|
"connection": MessageLookupByLibrary.simpleMessage("Соединение"),
|
||||||
"connections": MessageLookupByLibrary.simpleMessage("Соединения"),
|
"connections": MessageLookupByLibrary.simpleMessage("Соединения"),
|
||||||
"connectionsDesc": MessageLookupByLibrary.simpleMessage(
|
"connectionsDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Просмотр текущих данных о соединениях",
|
"Просмотр текущих данных о соединениях",
|
||||||
@@ -199,6 +202,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"country": MessageLookupByLibrary.simpleMessage("Страна"),
|
"country": MessageLookupByLibrary.simpleMessage("Страна"),
|
||||||
"crashTest": MessageLookupByLibrary.simpleMessage("Тест на сбои"),
|
"crashTest": MessageLookupByLibrary.simpleMessage("Тест на сбои"),
|
||||||
"create": MessageLookupByLibrary.simpleMessage("Создать"),
|
"create": MessageLookupByLibrary.simpleMessage("Создать"),
|
||||||
|
"creationTime": MessageLookupByLibrary.simpleMessage("Время создания"),
|
||||||
"cut": MessageLookupByLibrary.simpleMessage("Вырезать"),
|
"cut": MessageLookupByLibrary.simpleMessage("Вырезать"),
|
||||||
"dark": MessageLookupByLibrary.simpleMessage("Темный"),
|
"dark": MessageLookupByLibrary.simpleMessage("Темный"),
|
||||||
"dashboard": MessageLookupByLibrary.simpleMessage("Панель управления"),
|
"dashboard": MessageLookupByLibrary.simpleMessage("Панель управления"),
|
||||||
@@ -221,6 +225,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"desc": MessageLookupByLibrary.simpleMessage(
|
"desc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Многоплатформенный прокси-клиент на основе ClashMeta, простой и удобный в использовании, с открытым исходным кодом и без рекламы.",
|
"Многоплатформенный прокси-клиент на основе ClashMeta, простой и удобный в использовании, с открытым исходным кодом и без рекламы.",
|
||||||
),
|
),
|
||||||
|
"destination": MessageLookupByLibrary.simpleMessage("Назначение"),
|
||||||
|
"destinationGeoIP": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Геолокация назначения",
|
||||||
|
),
|
||||||
|
"destinationIPASN": MessageLookupByLibrary.simpleMessage("ASN назначения"),
|
||||||
|
"details": m2,
|
||||||
"detectionTip": MessageLookupByLibrary.simpleMessage(
|
"detectionTip": MessageLookupByLibrary.simpleMessage(
|
||||||
"Опирается на сторонний API, только для справки",
|
"Опирается на сторонний API, только для справки",
|
||||||
),
|
),
|
||||||
@@ -251,7 +261,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"domain": MessageLookupByLibrary.simpleMessage("Домен"),
|
"domain": MessageLookupByLibrary.simpleMessage("Домен"),
|
||||||
"download": MessageLookupByLibrary.simpleMessage("Скачивание"),
|
"download": MessageLookupByLibrary.simpleMessage("Скачивание"),
|
||||||
"edit": MessageLookupByLibrary.simpleMessage("Редактировать"),
|
"edit": MessageLookupByLibrary.simpleMessage("Редактировать"),
|
||||||
"emptyTip": m2,
|
"emptyTip": m3,
|
||||||
"en": MessageLookupByLibrary.simpleMessage("Английский"),
|
"en": MessageLookupByLibrary.simpleMessage("Английский"),
|
||||||
"enableOverride": MessageLookupByLibrary.simpleMessage(
|
"enableOverride": MessageLookupByLibrary.simpleMessage(
|
||||||
"Включить переопределение",
|
"Включить переопределение",
|
||||||
@@ -263,7 +273,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"excludeDesc": MessageLookupByLibrary.simpleMessage(
|
"excludeDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Когда приложение находится в фоновом режиме, оно скрыто из последних задач",
|
"Когда приложение находится в фоновом режиме, оно скрыто из последних задач",
|
||||||
),
|
),
|
||||||
"existsTip": m3,
|
"existsTip": m4,
|
||||||
"exit": MessageLookupByLibrary.simpleMessage("Выход"),
|
"exit": MessageLookupByLibrary.simpleMessage("Выход"),
|
||||||
"expand": MessageLookupByLibrary.simpleMessage("Стандартный"),
|
"expand": MessageLookupByLibrary.simpleMessage("Стандартный"),
|
||||||
"expirationTime": MessageLookupByLibrary.simpleMessage("Время истечения"),
|
"expirationTime": MessageLookupByLibrary.simpleMessage("Время истечения"),
|
||||||
@@ -329,6 +339,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"hasCacheChange": MessageLookupByLibrary.simpleMessage(
|
"hasCacheChange": MessageLookupByLibrary.simpleMessage(
|
||||||
"Хотите сохранить изменения в кэше?",
|
"Хотите сохранить изменения в кэше?",
|
||||||
),
|
),
|
||||||
|
"host": MessageLookupByLibrary.simpleMessage("Хост"),
|
||||||
"hostsDesc": MessageLookupByLibrary.simpleMessage("Добавить Hosts"),
|
"hostsDesc": MessageLookupByLibrary.simpleMessage("Добавить Hosts"),
|
||||||
"hotkeyConflict": MessageLookupByLibrary.simpleMessage(
|
"hotkeyConflict": MessageLookupByLibrary.simpleMessage(
|
||||||
"Конфликт горячих клавиш",
|
"Конфликт горячих клавиш",
|
||||||
@@ -387,6 +398,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Восстановление данных из файла",
|
"Восстановление данных из файла",
|
||||||
),
|
),
|
||||||
|
"log": MessageLookupByLibrary.simpleMessage("Журнал"),
|
||||||
"logLevel": MessageLookupByLibrary.simpleMessage("Уровень логов"),
|
"logLevel": MessageLookupByLibrary.simpleMessage("Уровень логов"),
|
||||||
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
|
"logcat": MessageLookupByLibrary.simpleMessage("Logcat"),
|
||||||
"logcatDesc": MessageLookupByLibrary.simpleMessage(
|
"logcatDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -440,6 +452,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"Обнаружение сети",
|
"Обнаружение сети",
|
||||||
),
|
),
|
||||||
"networkSpeed": MessageLookupByLibrary.simpleMessage("Скорость сети"),
|
"networkSpeed": MessageLookupByLibrary.simpleMessage("Скорость сети"),
|
||||||
|
"networkType": MessageLookupByLibrary.simpleMessage("Тип сети"),
|
||||||
"neutralScheme": MessageLookupByLibrary.simpleMessage("Нейтральные"),
|
"neutralScheme": MessageLookupByLibrary.simpleMessage("Нейтральные"),
|
||||||
"noData": MessageLookupByLibrary.simpleMessage("Нет данных"),
|
"noData": MessageLookupByLibrary.simpleMessage("Нет данных"),
|
||||||
"noHotKey": MessageLookupByLibrary.simpleMessage("Нет горячей клавиши"),
|
"noHotKey": MessageLookupByLibrary.simpleMessage("Нет горячей клавиши"),
|
||||||
@@ -462,8 +475,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
|
"nullProfileDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Нет профиля, пожалуйста, добавьте профиль",
|
"Нет профиля, пожалуйста, добавьте профиль",
|
||||||
),
|
),
|
||||||
"nullTip": m4,
|
"nullTip": m5,
|
||||||
"numberTip": m5,
|
"numberTip": m6,
|
||||||
"oneColumn": MessageLookupByLibrary.simpleMessage("Один столбец"),
|
"oneColumn": MessageLookupByLibrary.simpleMessage("Один столбец"),
|
||||||
"onlyIcon": MessageLookupByLibrary.simpleMessage("Только иконка"),
|
"onlyIcon": MessageLookupByLibrary.simpleMessage("Только иконка"),
|
||||||
"onlyOtherApps": MessageLookupByLibrary.simpleMessage(
|
"onlyOtherApps": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -519,7 +532,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"portConflictTip": MessageLookupByLibrary.simpleMessage(
|
"portConflictTip": MessageLookupByLibrary.simpleMessage(
|
||||||
"Введите другой порт",
|
"Введите другой порт",
|
||||||
),
|
),
|
||||||
"portTip": m6,
|
"portTip": m7,
|
||||||
"preferH3Desc": MessageLookupByLibrary.simpleMessage(
|
"preferH3Desc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Приоритетное использование HTTP/3 для DOH",
|
"Приоритетное использование HTTP/3 для DOH",
|
||||||
),
|
),
|
||||||
@@ -553,10 +566,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
),
|
),
|
||||||
"profiles": MessageLookupByLibrary.simpleMessage("Профили"),
|
"profiles": MessageLookupByLibrary.simpleMessage("Профили"),
|
||||||
"profilesSort": MessageLookupByLibrary.simpleMessage("Сортировка профилей"),
|
"profilesSort": MessageLookupByLibrary.simpleMessage("Сортировка профилей"),
|
||||||
|
"progress": MessageLookupByLibrary.simpleMessage("Прогресс"),
|
||||||
"project": MessageLookupByLibrary.simpleMessage("Проект"),
|
"project": MessageLookupByLibrary.simpleMessage("Проект"),
|
||||||
"providers": MessageLookupByLibrary.simpleMessage("Провайдеры"),
|
"providers": MessageLookupByLibrary.simpleMessage("Провайдеры"),
|
||||||
"proxies": MessageLookupByLibrary.simpleMessage("Прокси"),
|
"proxies": MessageLookupByLibrary.simpleMessage("Прокси"),
|
||||||
"proxiesSetting": MessageLookupByLibrary.simpleMessage("Настройка прокси"),
|
"proxiesSetting": MessageLookupByLibrary.simpleMessage("Настройка прокси"),
|
||||||
|
"proxyChains": MessageLookupByLibrary.simpleMessage("Цепочки прокси"),
|
||||||
"proxyGroup": MessageLookupByLibrary.simpleMessage("Группа прокси"),
|
"proxyGroup": MessageLookupByLibrary.simpleMessage("Группа прокси"),
|
||||||
"proxyNameserver": MessageLookupByLibrary.simpleMessage(
|
"proxyNameserver": MessageLookupByLibrary.simpleMessage(
|
||||||
"Прокси-сервер имен",
|
"Прокси-сервер имен",
|
||||||
@@ -601,11 +616,15 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
|
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Резервное копирование локальных данных на WebDAV",
|
"Резервное копирование локальных данных на WebDAV",
|
||||||
),
|
),
|
||||||
|
"remoteDestination": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Удалённое назначение",
|
||||||
|
),
|
||||||
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Восстановление данных с WebDAV",
|
"Восстановление данных с WebDAV",
|
||||||
),
|
),
|
||||||
"remove": MessageLookupByLibrary.simpleMessage("Удалить"),
|
"remove": MessageLookupByLibrary.simpleMessage("Удалить"),
|
||||||
"rename": MessageLookupByLibrary.simpleMessage("Переименовать"),
|
"rename": MessageLookupByLibrary.simpleMessage("Переименовать"),
|
||||||
|
"request": MessageLookupByLibrary.simpleMessage("Запрос"),
|
||||||
"requests": MessageLookupByLibrary.simpleMessage("Запросы"),
|
"requests": MessageLookupByLibrary.simpleMessage("Запросы"),
|
||||||
"requestsDesc": MessageLookupByLibrary.simpleMessage(
|
"requestsDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Просмотр последних записей запросов",
|
"Просмотр последних записей запросов",
|
||||||
@@ -648,7 +667,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"seconds": MessageLookupByLibrary.simpleMessage("Секунд"),
|
"seconds": MessageLookupByLibrary.simpleMessage("Секунд"),
|
||||||
"selectAll": MessageLookupByLibrary.simpleMessage("Выбрать все"),
|
"selectAll": MessageLookupByLibrary.simpleMessage("Выбрать все"),
|
||||||
"selected": MessageLookupByLibrary.simpleMessage("Выбрано"),
|
"selected": MessageLookupByLibrary.simpleMessage("Выбрано"),
|
||||||
"selectedCountTitle": m7,
|
"selectedCountTitle": m8,
|
||||||
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
|
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
|
||||||
"show": MessageLookupByLibrary.simpleMessage("Показать"),
|
"show": MessageLookupByLibrary.simpleMessage("Показать"),
|
||||||
"shrink": MessageLookupByLibrary.simpleMessage("Сжать"),
|
"shrink": MessageLookupByLibrary.simpleMessage("Сжать"),
|
||||||
@@ -661,6 +680,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"sort": MessageLookupByLibrary.simpleMessage("Сортировка"),
|
"sort": MessageLookupByLibrary.simpleMessage("Сортировка"),
|
||||||
"source": MessageLookupByLibrary.simpleMessage("Источник"),
|
"source": MessageLookupByLibrary.simpleMessage("Источник"),
|
||||||
"sourceIp": MessageLookupByLibrary.simpleMessage("Исходный IP"),
|
"sourceIp": MessageLookupByLibrary.simpleMessage("Исходный IP"),
|
||||||
|
"specialProxy": MessageLookupByLibrary.simpleMessage("Специальный прокси"),
|
||||||
|
"specialRules": MessageLookupByLibrary.simpleMessage("Специальные правила"),
|
||||||
"stackMode": MessageLookupByLibrary.simpleMessage("Режим стека"),
|
"stackMode": MessageLookupByLibrary.simpleMessage("Режим стека"),
|
||||||
"standard": MessageLookupByLibrary.simpleMessage("Стандартный"),
|
"standard": MessageLookupByLibrary.simpleMessage("Стандартный"),
|
||||||
"start": MessageLookupByLibrary.simpleMessage("Старт"),
|
"start": MessageLookupByLibrary.simpleMessage("Старт"),
|
||||||
@@ -733,7 +754,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"urlDesc": MessageLookupByLibrary.simpleMessage(
|
"urlDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Получить профиль через URL",
|
"Получить профиль через URL",
|
||||||
),
|
),
|
||||||
"urlTip": m8,
|
"urlTip": m9,
|
||||||
"useHosts": MessageLookupByLibrary.simpleMessage("Использовать hosts"),
|
"useHosts": MessageLookupByLibrary.simpleMessage("Использовать hosts"),
|
||||||
"useSystemHosts": MessageLookupByLibrary.simpleMessage(
|
"useSystemHosts": MessageLookupByLibrary.simpleMessage(
|
||||||
"Использовать системные hosts",
|
"Использовать системные hosts",
|
||||||
|
|||||||
@@ -24,19 +24,21 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
|
|
||||||
static String m1(label) => "确定删除当前${label}吗?";
|
static String m1(label) => "确定删除当前${label}吗?";
|
||||||
|
|
||||||
static String m2(label) => "${label}不能为空";
|
static String m2(label) => "${label}详情";
|
||||||
|
|
||||||
static String m3(label) => "${label}当前已存在";
|
static String m3(label) => "${label}不能为空";
|
||||||
|
|
||||||
static String m4(label) => "暂无${label}";
|
static String m4(label) => "${label}当前已存在";
|
||||||
|
|
||||||
static String m5(label) => "${label}必须为数字";
|
static String m5(label) => "暂无${label}";
|
||||||
|
|
||||||
static String m6(label) => "${label} 必须在 1024 到 49151 之间";
|
static String m6(label) => "${label}必须为数字";
|
||||||
|
|
||||||
static String m7(count) => "已选择 ${count} 项";
|
static String m7(label) => "${label} 必须在 1024 到 49151 之间";
|
||||||
|
|
||||||
static String m8(label) => "${label}必须为URL";
|
static String m8(count) => "已选择 ${count} 项";
|
||||||
|
|
||||||
|
static String m9(label) => "${label}必须为URL";
|
||||||
|
|
||||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
@@ -121,6 +123,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"开启将失去部分应用能力,获得全量的Clash的支持",
|
"开启将失去部分应用能力,获得全量的Clash的支持",
|
||||||
),
|
),
|
||||||
"confirm": MessageLookupByLibrary.simpleMessage("确定"),
|
"confirm": MessageLookupByLibrary.simpleMessage("确定"),
|
||||||
|
"connection": MessageLookupByLibrary.simpleMessage("连接"),
|
||||||
"connections": MessageLookupByLibrary.simpleMessage("连接"),
|
"connections": MessageLookupByLibrary.simpleMessage("连接"),
|
||||||
"connectionsDesc": MessageLookupByLibrary.simpleMessage("查看当前连接数据"),
|
"connectionsDesc": MessageLookupByLibrary.simpleMessage("查看当前连接数据"),
|
||||||
"connectivity": MessageLookupByLibrary.simpleMessage("连通性:"),
|
"connectivity": MessageLookupByLibrary.simpleMessage("连通性:"),
|
||||||
@@ -136,6 +139,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"country": MessageLookupByLibrary.simpleMessage("区域"),
|
"country": MessageLookupByLibrary.simpleMessage("区域"),
|
||||||
"crashTest": MessageLookupByLibrary.simpleMessage("崩溃测试"),
|
"crashTest": MessageLookupByLibrary.simpleMessage("崩溃测试"),
|
||||||
"create": MessageLookupByLibrary.simpleMessage("创建"),
|
"create": MessageLookupByLibrary.simpleMessage("创建"),
|
||||||
|
"creationTime": MessageLookupByLibrary.simpleMessage("创建时间"),
|
||||||
"cut": MessageLookupByLibrary.simpleMessage("剪切"),
|
"cut": MessageLookupByLibrary.simpleMessage("剪切"),
|
||||||
"dark": MessageLookupByLibrary.simpleMessage("深色"),
|
"dark": MessageLookupByLibrary.simpleMessage("深色"),
|
||||||
"dashboard": MessageLookupByLibrary.simpleMessage("仪表盘"),
|
"dashboard": MessageLookupByLibrary.simpleMessage("仪表盘"),
|
||||||
@@ -152,6 +156,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"desc": MessageLookupByLibrary.simpleMessage(
|
"desc": MessageLookupByLibrary.simpleMessage(
|
||||||
"基于ClashMeta的多平台代理客户端,简单易用,开源无广告。",
|
"基于ClashMeta的多平台代理客户端,简单易用,开源无广告。",
|
||||||
),
|
),
|
||||||
|
"destination": MessageLookupByLibrary.simpleMessage("目标地址"),
|
||||||
|
"destinationGeoIP": MessageLookupByLibrary.simpleMessage("目标地理定位"),
|
||||||
|
"destinationIPASN": MessageLookupByLibrary.simpleMessage("目标IP ASN"),
|
||||||
|
"details": m2,
|
||||||
"detectionTip": MessageLookupByLibrary.simpleMessage("依赖第三方api,仅供参考"),
|
"detectionTip": MessageLookupByLibrary.simpleMessage("依赖第三方api,仅供参考"),
|
||||||
"developerMode": MessageLookupByLibrary.simpleMessage("开发者模式"),
|
"developerMode": MessageLookupByLibrary.simpleMessage("开发者模式"),
|
||||||
"developerModeEnableTip": MessageLookupByLibrary.simpleMessage("开发者模式已启用。"),
|
"developerModeEnableTip": MessageLookupByLibrary.simpleMessage("开发者模式已启用。"),
|
||||||
@@ -168,13 +176,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"domain": MessageLookupByLibrary.simpleMessage("域名"),
|
"domain": MessageLookupByLibrary.simpleMessage("域名"),
|
||||||
"download": MessageLookupByLibrary.simpleMessage("下载"),
|
"download": MessageLookupByLibrary.simpleMessage("下载"),
|
||||||
"edit": MessageLookupByLibrary.simpleMessage("编辑"),
|
"edit": MessageLookupByLibrary.simpleMessage("编辑"),
|
||||||
"emptyTip": m2,
|
"emptyTip": m3,
|
||||||
"en": MessageLookupByLibrary.simpleMessage("英语"),
|
"en": MessageLookupByLibrary.simpleMessage("英语"),
|
||||||
"enableOverride": MessageLookupByLibrary.simpleMessage("启用覆写"),
|
"enableOverride": MessageLookupByLibrary.simpleMessage("启用覆写"),
|
||||||
"entries": MessageLookupByLibrary.simpleMessage("个条目"),
|
"entries": MessageLookupByLibrary.simpleMessage("个条目"),
|
||||||
"exclude": MessageLookupByLibrary.simpleMessage("从最近任务中隐藏"),
|
"exclude": MessageLookupByLibrary.simpleMessage("从最近任务中隐藏"),
|
||||||
"excludeDesc": MessageLookupByLibrary.simpleMessage("应用在后台时,从最近任务中隐藏应用"),
|
"excludeDesc": MessageLookupByLibrary.simpleMessage("应用在后台时,从最近任务中隐藏应用"),
|
||||||
"existsTip": m3,
|
"existsTip": m4,
|
||||||
"exit": MessageLookupByLibrary.simpleMessage("退出"),
|
"exit": MessageLookupByLibrary.simpleMessage("退出"),
|
||||||
"expand": MessageLookupByLibrary.simpleMessage("标准"),
|
"expand": MessageLookupByLibrary.simpleMessage("标准"),
|
||||||
"expirationTime": MessageLookupByLibrary.simpleMessage("到期时间"),
|
"expirationTime": MessageLookupByLibrary.simpleMessage("到期时间"),
|
||||||
@@ -214,6 +222,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"go": MessageLookupByLibrary.simpleMessage("前往"),
|
"go": MessageLookupByLibrary.simpleMessage("前往"),
|
||||||
"goDownload": MessageLookupByLibrary.simpleMessage("前往下载"),
|
"goDownload": MessageLookupByLibrary.simpleMessage("前往下载"),
|
||||||
"hasCacheChange": MessageLookupByLibrary.simpleMessage("是否缓存修改"),
|
"hasCacheChange": MessageLookupByLibrary.simpleMessage("是否缓存修改"),
|
||||||
|
"host": MessageLookupByLibrary.simpleMessage("主机"),
|
||||||
"hostsDesc": MessageLookupByLibrary.simpleMessage("追加Hosts"),
|
"hostsDesc": MessageLookupByLibrary.simpleMessage("追加Hosts"),
|
||||||
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("快捷键冲突"),
|
"hotkeyConflict": MessageLookupByLibrary.simpleMessage("快捷键冲突"),
|
||||||
"hotkeyManagement": MessageLookupByLibrary.simpleMessage("快捷键管理"),
|
"hotkeyManagement": MessageLookupByLibrary.simpleMessage("快捷键管理"),
|
||||||
@@ -248,6 +257,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"local": MessageLookupByLibrary.simpleMessage("本地"),
|
"local": MessageLookupByLibrary.simpleMessage("本地"),
|
||||||
"localBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到本地"),
|
"localBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到本地"),
|
||||||
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过文件恢复数据"),
|
"localRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过文件恢复数据"),
|
||||||
|
"log": MessageLookupByLibrary.simpleMessage("日志"),
|
||||||
"logLevel": MessageLookupByLibrary.simpleMessage("日志等级"),
|
"logLevel": MessageLookupByLibrary.simpleMessage("日志等级"),
|
||||||
"logcat": MessageLookupByLibrary.simpleMessage("日志捕获"),
|
"logcat": MessageLookupByLibrary.simpleMessage("日志捕获"),
|
||||||
"logcatDesc": MessageLookupByLibrary.simpleMessage("禁用将会隐藏日志入口"),
|
"logcatDesc": MessageLookupByLibrary.simpleMessage("禁用将会隐藏日志入口"),
|
||||||
@@ -279,6 +289,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"networkDesc": MessageLookupByLibrary.simpleMessage("修改网络相关设置"),
|
"networkDesc": MessageLookupByLibrary.simpleMessage("修改网络相关设置"),
|
||||||
"networkDetection": MessageLookupByLibrary.simpleMessage("网络检测"),
|
"networkDetection": MessageLookupByLibrary.simpleMessage("网络检测"),
|
||||||
"networkSpeed": MessageLookupByLibrary.simpleMessage("网络速度"),
|
"networkSpeed": MessageLookupByLibrary.simpleMessage("网络速度"),
|
||||||
|
"networkType": MessageLookupByLibrary.simpleMessage("网络类型"),
|
||||||
"neutralScheme": MessageLookupByLibrary.simpleMessage("中性"),
|
"neutralScheme": MessageLookupByLibrary.simpleMessage("中性"),
|
||||||
"noData": MessageLookupByLibrary.simpleMessage("暂无数据"),
|
"noData": MessageLookupByLibrary.simpleMessage("暂无数据"),
|
||||||
"noHotKey": MessageLookupByLibrary.simpleMessage("暂无快捷键"),
|
"noHotKey": MessageLookupByLibrary.simpleMessage("暂无快捷键"),
|
||||||
@@ -293,8 +304,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"none": MessageLookupByLibrary.simpleMessage("无"),
|
"none": MessageLookupByLibrary.simpleMessage("无"),
|
||||||
"notSelectedTip": MessageLookupByLibrary.simpleMessage("当前代理组无法选中"),
|
"notSelectedTip": MessageLookupByLibrary.simpleMessage("当前代理组无法选中"),
|
||||||
"nullProfileDesc": MessageLookupByLibrary.simpleMessage("没有配置文件,请先添加配置文件"),
|
"nullProfileDesc": MessageLookupByLibrary.simpleMessage("没有配置文件,请先添加配置文件"),
|
||||||
"nullTip": m4,
|
"nullTip": m5,
|
||||||
"numberTip": m5,
|
"numberTip": m6,
|
||||||
"oneColumn": MessageLookupByLibrary.simpleMessage("一列"),
|
"oneColumn": MessageLookupByLibrary.simpleMessage("一列"),
|
||||||
"onlyIcon": MessageLookupByLibrary.simpleMessage("仅图标"),
|
"onlyIcon": MessageLookupByLibrary.simpleMessage("仅图标"),
|
||||||
"onlyOtherApps": MessageLookupByLibrary.simpleMessage("仅第三方应用"),
|
"onlyOtherApps": MessageLookupByLibrary.simpleMessage("仅第三方应用"),
|
||||||
@@ -326,7 +337,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
),
|
),
|
||||||
"port": MessageLookupByLibrary.simpleMessage("端口"),
|
"port": MessageLookupByLibrary.simpleMessage("端口"),
|
||||||
"portConflictTip": MessageLookupByLibrary.simpleMessage("请输入不同的端口"),
|
"portConflictTip": MessageLookupByLibrary.simpleMessage("请输入不同的端口"),
|
||||||
"portTip": m6,
|
"portTip": m7,
|
||||||
"preferH3Desc": MessageLookupByLibrary.simpleMessage("优先使用DOH的http/3"),
|
"preferH3Desc": MessageLookupByLibrary.simpleMessage("优先使用DOH的http/3"),
|
||||||
"pressKeyboard": MessageLookupByLibrary.simpleMessage("请按下按键"),
|
"pressKeyboard": MessageLookupByLibrary.simpleMessage("请按下按键"),
|
||||||
"preview": MessageLookupByLibrary.simpleMessage("预览"),
|
"preview": MessageLookupByLibrary.simpleMessage("预览"),
|
||||||
@@ -350,10 +361,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
),
|
),
|
||||||
"profiles": MessageLookupByLibrary.simpleMessage("配置"),
|
"profiles": MessageLookupByLibrary.simpleMessage("配置"),
|
||||||
"profilesSort": MessageLookupByLibrary.simpleMessage("配置排序"),
|
"profilesSort": MessageLookupByLibrary.simpleMessage("配置排序"),
|
||||||
|
"progress": MessageLookupByLibrary.simpleMessage("进度"),
|
||||||
"project": MessageLookupByLibrary.simpleMessage("项目"),
|
"project": MessageLookupByLibrary.simpleMessage("项目"),
|
||||||
"providers": MessageLookupByLibrary.simpleMessage("提供者"),
|
"providers": MessageLookupByLibrary.simpleMessage("提供者"),
|
||||||
"proxies": MessageLookupByLibrary.simpleMessage("代理"),
|
"proxies": MessageLookupByLibrary.simpleMessage("代理"),
|
||||||
"proxiesSetting": MessageLookupByLibrary.simpleMessage("代理设置"),
|
"proxiesSetting": MessageLookupByLibrary.simpleMessage("代理设置"),
|
||||||
|
"proxyChains": MessageLookupByLibrary.simpleMessage("代理链"),
|
||||||
"proxyGroup": MessageLookupByLibrary.simpleMessage("代理组"),
|
"proxyGroup": MessageLookupByLibrary.simpleMessage("代理组"),
|
||||||
"proxyNameserver": MessageLookupByLibrary.simpleMessage("代理域名服务器"),
|
"proxyNameserver": MessageLookupByLibrary.simpleMessage("代理域名服务器"),
|
||||||
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage("用于解析代理节点的域名"),
|
"proxyNameserverDesc": MessageLookupByLibrary.simpleMessage("用于解析代理节点的域名"),
|
||||||
@@ -376,9 +389,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"regExp": MessageLookupByLibrary.simpleMessage("正则"),
|
"regExp": MessageLookupByLibrary.simpleMessage("正则"),
|
||||||
"remote": MessageLookupByLibrary.simpleMessage("远程"),
|
"remote": MessageLookupByLibrary.simpleMessage("远程"),
|
||||||
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到WebDAV"),
|
"remoteBackupDesc": MessageLookupByLibrary.simpleMessage("备份数据到WebDAV"),
|
||||||
|
"remoteDestination": MessageLookupByLibrary.simpleMessage("远程目标"),
|
||||||
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过WebDAV恢复数据"),
|
"remoteRecoveryDesc": MessageLookupByLibrary.simpleMessage("通过WebDAV恢复数据"),
|
||||||
"remove": MessageLookupByLibrary.simpleMessage("移除"),
|
"remove": MessageLookupByLibrary.simpleMessage("移除"),
|
||||||
"rename": MessageLookupByLibrary.simpleMessage("重命名"),
|
"rename": MessageLookupByLibrary.simpleMessage("重命名"),
|
||||||
|
"request": MessageLookupByLibrary.simpleMessage("请求"),
|
||||||
"requests": MessageLookupByLibrary.simpleMessage("请求"),
|
"requests": MessageLookupByLibrary.simpleMessage("请求"),
|
||||||
"requestsDesc": MessageLookupByLibrary.simpleMessage("查看最近请求记录"),
|
"requestsDesc": MessageLookupByLibrary.simpleMessage("查看最近请求记录"),
|
||||||
"reset": MessageLookupByLibrary.simpleMessage("重置"),
|
"reset": MessageLookupByLibrary.simpleMessage("重置"),
|
||||||
@@ -407,7 +422,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"seconds": MessageLookupByLibrary.simpleMessage("秒"),
|
"seconds": MessageLookupByLibrary.simpleMessage("秒"),
|
||||||
"selectAll": MessageLookupByLibrary.simpleMessage("全选"),
|
"selectAll": MessageLookupByLibrary.simpleMessage("全选"),
|
||||||
"selected": MessageLookupByLibrary.simpleMessage("已选择"),
|
"selected": MessageLookupByLibrary.simpleMessage("已选择"),
|
||||||
"selectedCountTitle": m7,
|
"selectedCountTitle": m8,
|
||||||
"settings": MessageLookupByLibrary.simpleMessage("设置"),
|
"settings": MessageLookupByLibrary.simpleMessage("设置"),
|
||||||
"show": MessageLookupByLibrary.simpleMessage("显示"),
|
"show": MessageLookupByLibrary.simpleMessage("显示"),
|
||||||
"shrink": MessageLookupByLibrary.simpleMessage("紧凑"),
|
"shrink": MessageLookupByLibrary.simpleMessage("紧凑"),
|
||||||
@@ -418,6 +433,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"sort": MessageLookupByLibrary.simpleMessage("排序"),
|
"sort": MessageLookupByLibrary.simpleMessage("排序"),
|
||||||
"source": MessageLookupByLibrary.simpleMessage("来源"),
|
"source": MessageLookupByLibrary.simpleMessage("来源"),
|
||||||
"sourceIp": MessageLookupByLibrary.simpleMessage("源IP"),
|
"sourceIp": MessageLookupByLibrary.simpleMessage("源IP"),
|
||||||
|
"specialProxy": MessageLookupByLibrary.simpleMessage("特殊代理"),
|
||||||
|
"specialRules": MessageLookupByLibrary.simpleMessage("特殊规则"),
|
||||||
"stackMode": MessageLookupByLibrary.simpleMessage("栈模式"),
|
"stackMode": MessageLookupByLibrary.simpleMessage("栈模式"),
|
||||||
"standard": MessageLookupByLibrary.simpleMessage("标准"),
|
"standard": MessageLookupByLibrary.simpleMessage("标准"),
|
||||||
"start": MessageLookupByLibrary.simpleMessage("启动"),
|
"start": MessageLookupByLibrary.simpleMessage("启动"),
|
||||||
@@ -470,7 +487,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"upload": MessageLookupByLibrary.simpleMessage("上传"),
|
"upload": MessageLookupByLibrary.simpleMessage("上传"),
|
||||||
"url": MessageLookupByLibrary.simpleMessage("URL"),
|
"url": MessageLookupByLibrary.simpleMessage("URL"),
|
||||||
"urlDesc": MessageLookupByLibrary.simpleMessage("通过URL获取配置文件"),
|
"urlDesc": MessageLookupByLibrary.simpleMessage("通过URL获取配置文件"),
|
||||||
"urlTip": m8,
|
"urlTip": m9,
|
||||||
"useHosts": MessageLookupByLibrary.simpleMessage("使用Hosts"),
|
"useHosts": MessageLookupByLibrary.simpleMessage("使用Hosts"),
|
||||||
"useSystemHosts": MessageLookupByLibrary.simpleMessage("使用系统Hosts"),
|
"useSystemHosts": MessageLookupByLibrary.simpleMessage("使用系统Hosts"),
|
||||||
"value": MessageLookupByLibrary.simpleMessage("值"),
|
"value": MessageLookupByLibrary.simpleMessage("值"),
|
||||||
|
|||||||
@@ -3139,6 +3139,126 @@ class AppLocalizations {
|
|||||||
args: [],
|
args: [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `{label} details`
|
||||||
|
String details(Object label) {
|
||||||
|
return Intl.message(
|
||||||
|
'$label details',
|
||||||
|
name: 'details',
|
||||||
|
desc: '',
|
||||||
|
args: [label],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Creation time`
|
||||||
|
String get creationTime {
|
||||||
|
return Intl.message(
|
||||||
|
'Creation time',
|
||||||
|
name: 'creationTime',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Progress`
|
||||||
|
String get progress {
|
||||||
|
return Intl.message('Progress', name: 'progress', desc: '', args: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Host`
|
||||||
|
String get host {
|
||||||
|
return Intl.message('Host', name: 'host', desc: '', args: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Destination`
|
||||||
|
String get destination {
|
||||||
|
return Intl.message('Destination', name: 'destination', desc: '', args: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Destination GeoIP`
|
||||||
|
String get destinationGeoIP {
|
||||||
|
return Intl.message(
|
||||||
|
'Destination GeoIP',
|
||||||
|
name: 'destinationGeoIP',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Destination IPASN`
|
||||||
|
String get destinationIPASN {
|
||||||
|
return Intl.message(
|
||||||
|
'Destination IPASN',
|
||||||
|
name: 'destinationIPASN',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Special proxy`
|
||||||
|
String get specialProxy {
|
||||||
|
return Intl.message(
|
||||||
|
'Special proxy',
|
||||||
|
name: 'specialProxy',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `special rules`
|
||||||
|
String get specialRules {
|
||||||
|
return Intl.message(
|
||||||
|
'special rules',
|
||||||
|
name: 'specialRules',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Remote destination`
|
||||||
|
String get remoteDestination {
|
||||||
|
return Intl.message(
|
||||||
|
'Remote destination',
|
||||||
|
name: 'remoteDestination',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Network type`
|
||||||
|
String get networkType {
|
||||||
|
return Intl.message(
|
||||||
|
'Network type',
|
||||||
|
name: 'networkType',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Proxy chains`
|
||||||
|
String get proxyChains {
|
||||||
|
return Intl.message(
|
||||||
|
'Proxy chains',
|
||||||
|
name: 'proxyChains',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Log`
|
||||||
|
String get log {
|
||||||
|
return Intl.message('Log', name: 'log', desc: '', args: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Connection`
|
||||||
|
String get connection {
|
||||||
|
return Intl.message('Connection', name: 'connection', desc: '', args: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Request`
|
||||||
|
String get request {
|
||||||
|
return Intl.message('Request', name: 'request', desc: '', args: []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {
|
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ Future<void> main() async {
|
|||||||
Future<void> _service(List<String> flags) async {
|
Future<void> _service(List<String> flags) async {
|
||||||
globalState.isService = true;
|
globalState.isService = true;
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
final quickStart = flags.contains("quick");
|
final quickStart = flags.contains('quick');
|
||||||
final clashLibHandler = ClashLibHandler();
|
final clashLibHandler = ClashLibHandler();
|
||||||
await globalState.init();
|
await globalState.init();
|
||||||
|
|
||||||
@@ -54,15 +54,14 @@ Future<void> _service(List<String> flags) async {
|
|||||||
vpn?.handleGetStartForegroundParams = () {
|
vpn?.handleGetStartForegroundParams = () {
|
||||||
final traffic = clashLibHandler.getTraffic();
|
final traffic = clashLibHandler.getTraffic();
|
||||||
return json.encode({
|
return json.encode({
|
||||||
"title": clashLibHandler.getCurrentProfileName(),
|
'title': clashLibHandler.getCurrentProfileName(),
|
||||||
"content": "$traffic"
|
'content': '$traffic'
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
vpn?.addListener(
|
vpn?.addListener(
|
||||||
_VpnListenerWithService(
|
_VpnListenerWithService(
|
||||||
onDnsChanged: (String dns) {
|
onDnsChanged: (String dns) {
|
||||||
print("handle dns $dns");
|
|
||||||
clashLibHandler.updateDns(dns);
|
clashLibHandler.updateDns(dns);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -70,7 +69,7 @@ Future<void> _service(List<String> flags) async {
|
|||||||
if (!quickStart) {
|
if (!quickStart) {
|
||||||
_handleMainIpc(clashLibHandler);
|
_handleMainIpc(clashLibHandler);
|
||||||
} else {
|
} else {
|
||||||
commonPrint.log("quick start");
|
commonPrint.log('quick start');
|
||||||
await ClashCore.initGeo();
|
await ClashCore.initGeo();
|
||||||
app?.tip(appLocalizations.startVpn);
|
app?.tip(appLocalizations.startVpn);
|
||||||
final homeDirPath = await appPath.homeDirPath;
|
final homeDirPath = await appPath.homeDirPath;
|
||||||
@@ -107,7 +106,7 @@ Future<void> _service(List<String> flags) async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleMainIpc(ClashLibHandler clashLibHandler) {
|
void _handleMainIpc(ClashLibHandler clashLibHandler) {
|
||||||
final sendPort = IsolateNameServer.lookupPortByName(mainIsolate);
|
final sendPort = IsolateNameServer.lookupPortByName(mainIsolate);
|
||||||
if (sendPort == null) {
|
if (sendPort == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:fl_clash/plugins/app.dart';
|
import 'package:fl_clash/plugins/app.dart';
|
||||||
import 'package:fl_clash/providers/config.dart';
|
import 'package:fl_clash/providers/providers.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
class AndroidManager extends ConsumerStatefulWidget {
|
class AndroidManager extends ConsumerStatefulWidget {
|
||||||
@@ -20,14 +19,10 @@ class _AndroidContainerState extends ConsumerState<AndroidManager> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
ref.listenManual(appSettingProvider.select((state) => state.hidden),
|
||||||
ref.listenManual(
|
(prev, next) {
|
||||||
appSettingProvider.select((state) => state.hidden),
|
app?.updateExcludeFromRecents(next);
|
||||||
(prev, next) {
|
}, fireImmediately: true);
|
||||||
app?.updateExcludeFromRecents(next);
|
|
||||||
},
|
|
||||||
fireImmediately: true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
286
lib/manager/app_manager.dart
Normal file
286
lib/manager/app_manager.dart
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:fl_clash/common/common.dart';
|
||||||
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
|
import 'package:fl_clash/manager/window_manager.dart';
|
||||||
|
import 'package:fl_clash/providers/providers.dart';
|
||||||
|
import 'package:fl_clash/state.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_acrylic/widgets/transparent_macos_sidebar.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
class AppStateManager extends ConsumerStatefulWidget {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const AppStateManager({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<AppStateManager> createState() => _AppStateManagerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppStateManagerState extends ConsumerState<AppStateManager>
|
||||||
|
with WidgetsBindingObserver {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
ref.listenManual(layoutChangeProvider, (prev, next) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (prev != next) {
|
||||||
|
globalState.computeHeightMapCache = {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ref.listenManual(
|
||||||
|
checkIpProvider,
|
||||||
|
(prev, next) {
|
||||||
|
if (prev != next && next.b) {
|
||||||
|
detectionState.startCheck();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fireImmediately: true,
|
||||||
|
);
|
||||||
|
ref.listenManual(configStateProvider, (prev, next) {
|
||||||
|
if (prev != next) {
|
||||||
|
globalState.appController.savePreferencesDebounce();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ref.listenManual(
|
||||||
|
autoSetSystemDnsStateProvider,
|
||||||
|
(prev, next) async {
|
||||||
|
if (prev == next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (next.a == true && next.b == true) {
|
||||||
|
macOS?.updateDns(false);
|
||||||
|
} else {
|
||||||
|
macOS?.updateDns(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
ref.listenManual(
|
||||||
|
currentBrightnessProvider,
|
||||||
|
(prev, next) {
|
||||||
|
if (prev == next) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window?.updateMacOSBrightness(next);
|
||||||
|
},
|
||||||
|
fireImmediately: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
|
||||||
|
commonPrint.log('$state');
|
||||||
|
if (state == AppLifecycleState.paused ||
|
||||||
|
state == AppLifecycleState.inactive) {
|
||||||
|
globalState.appController.savePreferences();
|
||||||
|
} else {
|
||||||
|
render?.resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangePlatformBrightness() {
|
||||||
|
globalState.appController.updateBrightness();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Listener(
|
||||||
|
onPointerHover: (_) {
|
||||||
|
render?.resume();
|
||||||
|
},
|
||||||
|
child: widget.child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppEnvManager extends StatelessWidget {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const AppEnvManager({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
if (globalState.isPre) {
|
||||||
|
return Banner(
|
||||||
|
message: 'DEBUG',
|
||||||
|
location: BannerLocation.topEnd,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (globalState.isPre) {
|
||||||
|
return Banner(
|
||||||
|
message: 'PRE',
|
||||||
|
location: BannerLocation.topEnd,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppSidebarContainer extends ConsumerWidget {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const AppSidebarContainer({
|
||||||
|
super.key,
|
||||||
|
required this.child,
|
||||||
|
});
|
||||||
|
|
||||||
|
Widget _buildLoading() {
|
||||||
|
return Consumer(
|
||||||
|
builder: (_, ref, __) {
|
||||||
|
final loading = ref.watch(loadingProvider);
|
||||||
|
final isMobileView = ref.watch(isMobileViewProvider);
|
||||||
|
return loading && !isMobileView
|
||||||
|
? RotatedBox(
|
||||||
|
quarterTurns: 1,
|
||||||
|
child: const LinearProgressIndicator(),
|
||||||
|
)
|
||||||
|
: Container();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBackground({
|
||||||
|
required BuildContext context,
|
||||||
|
required Widget child,
|
||||||
|
}) {
|
||||||
|
if (!system.isMacOS) {
|
||||||
|
return Material(
|
||||||
|
color: context.colorScheme.surfaceContainer,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return TransparentMacOSSidebar(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final navigationState = ref.watch(navigationStateProvider);
|
||||||
|
final navigationItems = navigationState.navigationItems;
|
||||||
|
final isMobileView = navigationState.viewMode == ViewMode.mobile;
|
||||||
|
if (isMobileView) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
final currentIndex = navigationState.currentIndex;
|
||||||
|
final showLabel = ref.watch(appSettingProvider).showLabel;
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
alignment: Alignment.topRight,
|
||||||
|
children: [
|
||||||
|
_buildBackground(
|
||||||
|
context: context,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 32,
|
||||||
|
),
|
||||||
|
if (system.isWindows) ...[
|
||||||
|
AppIcon(),
|
||||||
|
SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
Expanded(
|
||||||
|
child: ScrollConfiguration(
|
||||||
|
behavior: HiddenBarScrollBehavior(),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: IntrinsicHeight(
|
||||||
|
child: NavigationRail(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
selectedLabelTextStyle:
|
||||||
|
context.textTheme.labelLarge!.copyWith(
|
||||||
|
color: context.colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
unselectedLabelTextStyle:
|
||||||
|
context.textTheme.labelLarge!.copyWith(
|
||||||
|
color: context.colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
destinations: navigationItems
|
||||||
|
.map(
|
||||||
|
(e) => NavigationRailDestination(
|
||||||
|
icon: e.icon,
|
||||||
|
label: Text(
|
||||||
|
Intl.message(e.label.name),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
onDestinationSelected: (index) {
|
||||||
|
globalState.appController
|
||||||
|
.toPage(navigationItems[index].label);
|
||||||
|
},
|
||||||
|
extended: false,
|
||||||
|
selectedIndex: currentIndex,
|
||||||
|
labelType: showLabel
|
||||||
|
? NavigationRailLabelType.all
|
||||||
|
: NavigationRailLabelType.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
ref.read(appSettingProvider.notifier).updateState(
|
||||||
|
(state) => state.copyWith(
|
||||||
|
showLabel: !state.showLabel,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.menu,
|
||||||
|
color: context.colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_buildLoading(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: ClipRect(
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
|
||||||
import 'package:fl_clash/providers/providers.dart';
|
|
||||||
import 'package:fl_clash/state.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
||||||
|
|
||||||
class AppStateManager extends ConsumerStatefulWidget {
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const AppStateManager({
|
|
||||||
super.key,
|
|
||||||
required this.child,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
ConsumerState<AppStateManager> createState() => _AppStateManagerState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AppStateManagerState extends ConsumerState<AppStateManager>
|
|
||||||
with WidgetsBindingObserver {
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
WidgetsBinding.instance.addObserver(this);
|
|
||||||
ref.listenManual(layoutChangeProvider, (prev, next) {
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
if (prev != next) {
|
|
||||||
globalState.cacheHeightMap = {};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
ref.listenManual(
|
|
||||||
checkIpProvider,
|
|
||||||
(prev, next) {
|
|
||||||
if (prev != next && next.b) {
|
|
||||||
detectionState.startCheck();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fireImmediately: true,
|
|
||||||
);
|
|
||||||
ref.listenManual(configStateProvider, (prev, next) {
|
|
||||||
if (prev != next) {
|
|
||||||
globalState.appController.savePreferencesDebounce();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ref.listenManual(
|
|
||||||
autoSetSystemDnsStateProvider,
|
|
||||||
(prev, next) async {
|
|
||||||
if (prev == next) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (next.a == true && next.b == true) {
|
|
||||||
system.setMacOSDns(false);
|
|
||||||
} else {
|
|
||||||
system.setMacOSDns(true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
reassemble() {
|
|
||||||
super.reassemble();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() async {
|
|
||||||
await system.setMacOSDns(true);
|
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
|
|
||||||
commonPrint.log("$state");
|
|
||||||
if (state == AppLifecycleState.paused ||
|
|
||||||
state == AppLifecycleState.inactive) {
|
|
||||||
globalState.appController.savePreferences();
|
|
||||||
} else {
|
|
||||||
render?.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangePlatformBrightness() {
|
|
||||||
globalState.appController.updateBrightness(
|
|
||||||
WidgetsBinding.instance.platformDispatcher.platformBrightness,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Listener(
|
|
||||||
onPointerHover: (_) {
|
|
||||||
render?.resume();
|
|
||||||
},
|
|
||||||
child: widget.child,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AppEnvManager extends StatelessWidget {
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const AppEnvManager({
|
|
||||||
super.key,
|
|
||||||
required this.child,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if (kDebugMode) {
|
|
||||||
if (globalState.isPre) {
|
|
||||||
return Banner(
|
|
||||||
message: 'DEBUG',
|
|
||||||
location: BannerLocation.topEnd,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (globalState.isPre) {
|
|
||||||
return Banner(
|
|
||||||
message: 'PRE',
|
|
||||||
location: BannerLocation.topEnd,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -74,7 +74,7 @@ class _ClashContainerState extends ConsumerState<ClashManager>
|
|||||||
debouncer.call(
|
debouncer.call(
|
||||||
FunctionTag.updateDelay,
|
FunctionTag.updateDelay,
|
||||||
() async {
|
() async {
|
||||||
await appController.updateGroupsDebounce();
|
appController.updateGroupsDebounce();
|
||||||
},
|
},
|
||||||
duration: const Duration(milliseconds: 5000),
|
duration: const Duration(milliseconds: 5000),
|
||||||
);
|
);
|
||||||
@@ -90,9 +90,9 @@ class _ClashContainerState extends ConsumerState<ClashManager>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onRequest(Connection connection) async {
|
void onRequest(TrackerInfo trackerInfo) async {
|
||||||
ref.read(requestsProvider.notifier).addRequest(connection);
|
ref.read(requestsProvider.notifier).addRequest(trackerInfo);
|
||||||
super.onRequest(connection);
|
super.onRequest(trackerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -102,7 +102,7 @@ class _ClashContainerState extends ConsumerState<ClashManager>
|
|||||||
providerName,
|
providerName,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await globalState.appController.updateGroupsDebounce();
|
globalState.appController.updateGroupsDebounce();
|
||||||
super.onLoaded(providerName);
|
super.onLoaded(providerName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleHotKeyAction(HotAction action) async {
|
Future<void> _handleHotKeyAction(HotAction action) async {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case HotAction.mode:
|
case HotAction.mode:
|
||||||
globalState.appController.updateMode();
|
globalState.appController.updateMode();
|
||||||
@@ -50,7 +50,7 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateHotKeys({
|
Future<void> _updateHotKeys({
|
||||||
required List<HotKeyAction> hotKeyActions,
|
required List<HotKeyAction> hotKeyActions,
|
||||||
}) async {
|
}) async {
|
||||||
await hotKeyManager.unregisterAll();
|
await hotKeyManager.unregisterAll();
|
||||||
@@ -78,7 +78,7 @@ class _HotKeyManagerState extends ConsumerState<HotKeyManager> {
|
|||||||
await Future.wait(hotkeyActionHandles);
|
await Future.wait(hotkeyActionHandles);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildShortcuts(Widget child) {
|
Shortcuts _buildShortcuts(Widget child) {
|
||||||
return Shortcuts(
|
return Shortcuts(
|
||||||
shortcuts: {
|
shortcuts: {
|
||||||
utils.controlSingleActivator(LogicalKeyboardKey.keyW):
|
utils.controlSingleActivator(LogicalKeyboardKey.keyW):
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
export 'tray_manager.dart';
|
|
||||||
export 'window_manager.dart';
|
|
||||||
export 'android_manager.dart';
|
export 'android_manager.dart';
|
||||||
|
export 'app_manager.dart';
|
||||||
export 'clash_manager.dart';
|
export 'clash_manager.dart';
|
||||||
export 'tile_manager.dart';
|
|
||||||
export 'app_state_manager.dart';
|
|
||||||
export 'vpn_manager.dart';
|
|
||||||
export 'proxy_manager.dart';
|
|
||||||
export 'connectivity_manager.dart';
|
export 'connectivity_manager.dart';
|
||||||
export 'message_manager.dart';
|
export 'message_manager.dart';
|
||||||
export 'theme_manager.dart';
|
export 'proxy_manager.dart';
|
||||||
|
export 'theme_manager.dart';
|
||||||
|
export 'tile_manager.dart';
|
||||||
|
export 'tray_manager.dart';
|
||||||
|
export 'vpn_manager.dart';
|
||||||
|
export 'window_manager.dart';
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class MessageManagerState extends State<MessageManager> {
|
|||||||
await _showMessage();
|
await _showMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
_showMessage() async {
|
Future<void> _showMessage() async {
|
||||||
if (_pushing == true) {
|
if (_pushing == true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ class MessageManagerState extends State<MessageManager> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleRemove(CommonMessage commonMessage) async {
|
Future<void> _handleRemove(CommonMessage commonMessage) async {
|
||||||
_messagesNotifier.value = List<CommonMessage>.from(_messagesNotifier.value)
|
_messagesNotifier.value = List<CommonMessage>.from(_messagesNotifier.value)
|
||||||
..remove(commonMessage);
|
..remove(commonMessage);
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ class MessageManagerState extends State<MessageManager> {
|
|||||||
key: Key(messages.last.id),
|
key: Key(messages.last.id),
|
||||||
builder: (_, constraints) {
|
builder: (_, constraints) {
|
||||||
return Card(
|
return Card(
|
||||||
shape: const RoundedSuperellipseBorder(
|
shape: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
Radius.circular(12.0),
|
Radius.circular(12.0),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class ProxyManager extends ConsumerStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ProxyManagerState extends ConsumerState<ProxyManager> {
|
class _ProxyManagerState extends ConsumerState<ProxyManager> {
|
||||||
_updateProxy(ProxyState proxyState) async {
|
Future<void> _updateProxy(ProxyState proxyState) async {
|
||||||
final isStart = proxyState.isStart;
|
final isStart = proxyState.isStart;
|
||||||
final systemProxy = proxyState.systemProxy;
|
final systemProxy = proxyState.systemProxy;
|
||||||
final port = proxyState.port;
|
final port = proxyState.port;
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:fl_clash/common/constant.dart';
|
|
||||||
import 'package:fl_clash/common/measure.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/common/theme.dart';
|
import 'package:fl_clash/common/theme.dart';
|
||||||
import 'package:fl_clash/providers/config.dart';
|
import 'package:fl_clash/providers/config.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
import '../providers/state.dart';
|
||||||
|
|
||||||
class ThemeManager extends ConsumerWidget {
|
class ThemeManager extends ConsumerWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
@@ -15,6 +18,54 @@ class ThemeManager extends ConsumerWidget {
|
|||||||
required this.child,
|
required this.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Widget _buildSystemUi(Widget child) {
|
||||||
|
if (!system.isAndroid) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
return AnnotatedRegion<SystemUiMode>(
|
||||||
|
sized: false,
|
||||||
|
value: SystemUiMode.edgeToEdge,
|
||||||
|
child: Consumer(
|
||||||
|
builder: (context, ref, _) {
|
||||||
|
final brightness = ref.watch(currentBrightnessProvider);
|
||||||
|
final iconBrightness = brightness == Brightness.light
|
||||||
|
? Brightness.dark
|
||||||
|
: Brightness.light;
|
||||||
|
globalState.appState = globalState.appState.copyWith(
|
||||||
|
systemUiOverlayStyle: SystemUiOverlayStyle(
|
||||||
|
statusBarColor: Colors.transparent,
|
||||||
|
statusBarIconBrightness: iconBrightness,
|
||||||
|
systemNavigationBarIconBrightness: iconBrightness,
|
||||||
|
systemNavigationBarColor: context.colorScheme.surface,
|
||||||
|
systemNavigationBarDividerColor: Colors.transparent,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
|
value: globalState.appState.systemUiOverlayStyle,
|
||||||
|
sized: false,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// _buildScrollbar(Widget child) {
|
||||||
|
// return Consumer(
|
||||||
|
// builder: (_, ref, child) {
|
||||||
|
// final isMobileView = ref.read(isMobileViewProvider);
|
||||||
|
// if (isMobileView) {
|
||||||
|
// return ScrollConfiguration(
|
||||||
|
// behavior: HiddenBarScrollBehavior(),
|
||||||
|
// child: child!,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// return child!;
|
||||||
|
// },
|
||||||
|
// child: child,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final textScale = ref.read(
|
final textScale = ref.read(
|
||||||
@@ -49,7 +100,7 @@ class ThemeManager extends ConsumerWidget {
|
|||||||
container.maxHeight,
|
container.maxHeight,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return child;
|
return _buildSystemUi(child);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class _VpnContainerState extends ConsumerState<VpnManager> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showTip() {
|
void showTip() {
|
||||||
debouncer.call(
|
debouncer.call(
|
||||||
FunctionTag.vpnTip,
|
FunctionTag.vpnTip,
|
||||||
() {
|
() {
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/providers/app.dart';
|
import 'package:fl_clash/providers/providers.dart';
|
||||||
import 'package:fl_clash/providers/config.dart';
|
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@@ -59,7 +57,7 @@ class _WindowContainerState extends ConsumerState<WindowManager>
|
|||||||
@override
|
@override
|
||||||
void onWindowFocus() {
|
void onWindowFocus() {
|
||||||
super.onWindowFocus();
|
super.onWindowFocus();
|
||||||
commonPrint.log("focus");
|
commonPrint.log('focus');
|
||||||
render?.resume();
|
render?.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,14 +94,14 @@ class _WindowContainerState extends ConsumerState<WindowManager>
|
|||||||
@override
|
@override
|
||||||
void onWindowMinimize() async {
|
void onWindowMinimize() async {
|
||||||
globalState.appController.savePreferencesDebounce();
|
globalState.appController.savePreferencesDebounce();
|
||||||
commonPrint.log("minimize");
|
commonPrint.log('minimize');
|
||||||
render?.pause();
|
render?.pause();
|
||||||
super.onWindowMinimize();
|
super.onWindowMinimize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onWindowRestore() {
|
void onWindowRestore() {
|
||||||
commonPrint.log("restore");
|
commonPrint.log('restore');
|
||||||
render?.resume();
|
render?.resume();
|
||||||
super.onWindowRestore();
|
super.onWindowRestore();
|
||||||
}
|
}
|
||||||
@@ -128,8 +126,9 @@ class WindowHeaderContainer extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer(
|
return Consumer(
|
||||||
builder: (_, ref, child) {
|
builder: (_, ref, child) {
|
||||||
|
final isMobileView = ref.watch(isMobileViewProvider);
|
||||||
final version = ref.watch(versionProvider);
|
final version = ref.watch(versionProvider);
|
||||||
if (version <= 10 && Platform.isMacOS) {
|
if ((version <= 10 || !isMobileView) && system.isMacOS) {
|
||||||
return child!;
|
return child!;
|
||||||
}
|
}
|
||||||
return Stack(
|
return Stack(
|
||||||
@@ -171,7 +170,7 @@ class _WindowHeaderState extends State<WindowHeader> {
|
|||||||
_initNotifier();
|
_initNotifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
_initNotifier() async {
|
Future<void> _initNotifier() async {
|
||||||
isMaximizedNotifier.value = await windowManager.isMaximized();
|
isMaximizedNotifier.value = await windowManager.isMaximized();
|
||||||
isPinNotifier.value = await windowManager.isAlwaysOnTop();
|
isPinNotifier.value = await windowManager.isAlwaysOnTop();
|
||||||
}
|
}
|
||||||
@@ -183,7 +182,7 @@ class _WindowHeaderState extends State<WindowHeader> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateMaximized() async {
|
Future<void> _updateMaximized() async {
|
||||||
final isMaximized = await windowManager.isMaximized();
|
final isMaximized = await windowManager.isMaximized();
|
||||||
switch (isMaximized) {
|
switch (isMaximized) {
|
||||||
case true:
|
case true:
|
||||||
@@ -196,13 +195,13 @@ class _WindowHeaderState extends State<WindowHeader> {
|
|||||||
isMaximizedNotifier.value = await windowManager.isMaximized();
|
isMaximizedNotifier.value = await windowManager.isMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
_updatePin() async {
|
Future<void> _updatePin() async {
|
||||||
final isAlwaysOnTop = await windowManager.isAlwaysOnTop();
|
final isAlwaysOnTop = await windowManager.isAlwaysOnTop();
|
||||||
await windowManager.setAlwaysOnTop(!isAlwaysOnTop);
|
await windowManager.setAlwaysOnTop(!isAlwaysOnTop);
|
||||||
isPinNotifier.value = await windowManager.isAlwaysOnTop();
|
isPinNotifier.value = await windowManager.isAlwaysOnTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildActions() {
|
Widget _buildActions() {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
@@ -280,15 +279,11 @@ class _WindowHeaderState extends State<WindowHeader> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (Platform.isMacOS)
|
if (system.isMacOS)
|
||||||
const Text(
|
const Text(
|
||||||
appName,
|
appName,
|
||||||
)
|
)
|
||||||
else ...[
|
else ...[
|
||||||
const Positioned(
|
|
||||||
left: 0,
|
|
||||||
child: AppIcon(),
|
|
||||||
),
|
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 0,
|
right: 0,
|
||||||
child: _buildActions(),
|
child: _buildActions(),
|
||||||
@@ -306,24 +301,18 @@ class AppIcon extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(left: 8),
|
decoration: BoxDecoration(
|
||||||
child: const Row(
|
color: context.colorScheme.primaryContainer,
|
||||||
children: [
|
borderRadius: BorderRadius.circular(12),
|
||||||
SizedBox(
|
),
|
||||||
width: 24,
|
padding: EdgeInsets.all(6),
|
||||||
height: 24,
|
child: SizedBox(
|
||||||
child: CircleAvatar(
|
width: 28,
|
||||||
foregroundImage: AssetImage("assets/images/icon.png"),
|
height: 28,
|
||||||
backgroundColor: Colors.transparent,
|
child: CircleAvatar(
|
||||||
),
|
foregroundImage: AssetImage('assets/images/icon.png'),
|
||||||
),
|
backgroundColor: Colors.transparent,
|
||||||
SizedBox(
|
),
|
||||||
width: 8,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
appName,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
@@ -22,17 +22,18 @@ class AppState with _$AppState {
|
|||||||
@Default({}) DelayMap delayMap,
|
@Default({}) DelayMap delayMap,
|
||||||
@Default([]) List<Group> groups,
|
@Default([]) List<Group> groups,
|
||||||
@Default(0) int checkIpNum,
|
@Default(0) int checkIpNum,
|
||||||
Brightness? brightness,
|
required Brightness brightness,
|
||||||
int? runTime,
|
int? runTime,
|
||||||
@Default([]) List<ExternalProvider> providers,
|
@Default([]) List<ExternalProvider> providers,
|
||||||
String? localIp,
|
String? localIp,
|
||||||
required FixedList<Connection> requests,
|
required FixedList<TrackerInfo> requests,
|
||||||
required int version,
|
required int version,
|
||||||
required FixedList<Log> logs,
|
required FixedList<Log> logs,
|
||||||
required FixedList<Traffic> traffics,
|
required FixedList<Traffic> traffics,
|
||||||
required Traffic totalTraffic,
|
required Traffic totalTraffic,
|
||||||
@Default("") String proxiesQuery,
|
|
||||||
@Default(false) bool realTunEnable,
|
@Default(false) bool realTunEnable,
|
||||||
|
@Default(false) bool loading,
|
||||||
|
required SystemUiOverlayStyle systemUiOverlayStyle,
|
||||||
}) = _AppState;
|
}) = _AppState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,88 +19,88 @@ const defaultMixedPort = 7890;
|
|||||||
const defaultKeepAliveInterval = 30;
|
const defaultKeepAliveInterval = 30;
|
||||||
|
|
||||||
const defaultBypassPrivateRouteAddress = [
|
const defaultBypassPrivateRouteAddress = [
|
||||||
"1.0.0.0/8",
|
'1.0.0.0/8',
|
||||||
"2.0.0.0/7",
|
'2.0.0.0/7',
|
||||||
"4.0.0.0/6",
|
'4.0.0.0/6',
|
||||||
"8.0.0.0/7",
|
'8.0.0.0/7',
|
||||||
"11.0.0.0/8",
|
'11.0.0.0/8',
|
||||||
"12.0.0.0/6",
|
'12.0.0.0/6',
|
||||||
"16.0.0.0/4",
|
'16.0.0.0/4',
|
||||||
"32.0.0.0/3",
|
'32.0.0.0/3',
|
||||||
"64.0.0.0/3",
|
'64.0.0.0/3',
|
||||||
"96.0.0.0/4",
|
'96.0.0.0/4',
|
||||||
"112.0.0.0/5",
|
'112.0.0.0/5',
|
||||||
"120.0.0.0/6",
|
'120.0.0.0/6',
|
||||||
"124.0.0.0/7",
|
'124.0.0.0/7',
|
||||||
"126.0.0.0/8",
|
'126.0.0.0/8',
|
||||||
"128.0.0.0/3",
|
'128.0.0.0/3',
|
||||||
"160.0.0.0/5",
|
'160.0.0.0/5',
|
||||||
"168.0.0.0/8",
|
'168.0.0.0/8',
|
||||||
"169.0.0.0/9",
|
'169.0.0.0/9',
|
||||||
"169.128.0.0/10",
|
'169.128.0.0/10',
|
||||||
"169.192.0.0/11",
|
'169.192.0.0/11',
|
||||||
"169.224.0.0/12",
|
'169.224.0.0/12',
|
||||||
"169.240.0.0/13",
|
'169.240.0.0/13',
|
||||||
"169.248.0.0/14",
|
'169.248.0.0/14',
|
||||||
"169.252.0.0/15",
|
'169.252.0.0/15',
|
||||||
"169.255.0.0/16",
|
'169.255.0.0/16',
|
||||||
"170.0.0.0/7",
|
'170.0.0.0/7',
|
||||||
"172.0.0.0/12",
|
'172.0.0.0/12',
|
||||||
"172.32.0.0/11",
|
'172.32.0.0/11',
|
||||||
"172.64.0.0/10",
|
'172.64.0.0/10',
|
||||||
"172.128.0.0/9",
|
'172.128.0.0/9',
|
||||||
"173.0.0.0/8",
|
'173.0.0.0/8',
|
||||||
"174.0.0.0/7",
|
'174.0.0.0/7',
|
||||||
"176.0.0.0/4",
|
'176.0.0.0/4',
|
||||||
"192.0.0.0/9",
|
'192.0.0.0/9',
|
||||||
"192.128.0.0/11",
|
'192.128.0.0/11',
|
||||||
"192.160.0.0/13",
|
'192.160.0.0/13',
|
||||||
"192.169.0.0/16",
|
'192.169.0.0/16',
|
||||||
"192.170.0.0/15",
|
'192.170.0.0/15',
|
||||||
"192.172.0.0/14",
|
'192.172.0.0/14',
|
||||||
"192.176.0.0/12",
|
'192.176.0.0/12',
|
||||||
"192.192.0.0/10",
|
'192.192.0.0/10',
|
||||||
"193.0.0.0/8",
|
'193.0.0.0/8',
|
||||||
"194.0.0.0/7",
|
'194.0.0.0/7',
|
||||||
"196.0.0.0/6",
|
'196.0.0.0/6',
|
||||||
"200.0.0.0/5",
|
'200.0.0.0/5',
|
||||||
"208.0.0.0/4",
|
'208.0.0.0/4',
|
||||||
"240.0.0.0/5",
|
'240.0.0.0/5',
|
||||||
"248.0.0.0/6",
|
'248.0.0.0/6',
|
||||||
"252.0.0.0/7",
|
'252.0.0.0/7',
|
||||||
"254.0.0.0/8",
|
'254.0.0.0/8',
|
||||||
"255.0.0.0/9",
|
'255.0.0.0/9',
|
||||||
"255.128.0.0/10",
|
'255.128.0.0/10',
|
||||||
"255.192.0.0/11",
|
'255.192.0.0/11',
|
||||||
"255.224.0.0/12",
|
'255.224.0.0/12',
|
||||||
"255.240.0.0/13",
|
'255.240.0.0/13',
|
||||||
"255.248.0.0/14",
|
'255.248.0.0/14',
|
||||||
"255.252.0.0/15",
|
'255.252.0.0/15',
|
||||||
"255.254.0.0/16",
|
'255.254.0.0/16',
|
||||||
"255.255.0.0/17",
|
'255.255.0.0/17',
|
||||||
"255.255.128.0/18",
|
'255.255.128.0/18',
|
||||||
"255.255.192.0/19",
|
'255.255.192.0/19',
|
||||||
"255.255.224.0/20",
|
'255.255.224.0/20',
|
||||||
"255.255.240.0/21",
|
'255.255.240.0/21',
|
||||||
"255.255.248.0/22",
|
'255.255.248.0/22',
|
||||||
"255.255.252.0/23",
|
'255.255.252.0/23',
|
||||||
"255.255.254.0/24",
|
'255.255.254.0/24',
|
||||||
"255.255.255.0/25",
|
'255.255.255.0/25',
|
||||||
"255.255.255.128/26",
|
'255.255.255.128/26',
|
||||||
"255.255.255.192/27",
|
'255.255.255.192/27',
|
||||||
"255.255.255.224/28",
|
'255.255.255.224/28',
|
||||||
"255.255.255.240/29",
|
'255.255.255.240/29',
|
||||||
"255.255.255.248/30",
|
'255.255.255.248/30',
|
||||||
"255.255.255.252/31",
|
'255.255.255.252/31',
|
||||||
"255.255.255.254/32",
|
'255.255.255.254/32',
|
||||||
"::/1",
|
'::/1',
|
||||||
"8000::/2",
|
'8000::/2',
|
||||||
"c000::/3",
|
'c000::/3',
|
||||||
"e000::/4",
|
'e000::/4',
|
||||||
"f000::/5",
|
'f000::/5',
|
||||||
"f800::/6",
|
'f800::/6',
|
||||||
"fe00::/9",
|
'fe00::/9',
|
||||||
"fec0::/10"
|
'fec0::/10'
|
||||||
];
|
];
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@@ -117,11 +117,11 @@ class ProxyGroup with _$ProxyGroup {
|
|||||||
bool? lazy,
|
bool? lazy,
|
||||||
String? url,
|
String? url,
|
||||||
int? timeout,
|
int? timeout,
|
||||||
@JsonKey(name: "max-failed-times") int? maxFailedTimes,
|
@JsonKey(name: 'max-failed-times') int? maxFailedTimes,
|
||||||
String? filter,
|
String? filter,
|
||||||
@JsonKey(name: "expected-filter") String? excludeFilter,
|
@JsonKey(name: 'expected-filter') String? excludeFilter,
|
||||||
@JsonKey(name: "exclude-type") String? excludeType,
|
@JsonKey(name: 'exclude-type') String? excludeType,
|
||||||
@JsonKey(name: "expected-status") dynamic expectedStatus,
|
@JsonKey(name: 'expected-status') dynamic expectedStatus,
|
||||||
bool? hidden,
|
bool? hidden,
|
||||||
String? icon,
|
String? icon,
|
||||||
}) = _ProxyGroup;
|
}) = _ProxyGroup;
|
||||||
@@ -144,15 +144,15 @@ class RuleProvider with _$RuleProvider {
|
|||||||
class Sniffer with _$Sniffer {
|
class Sniffer with _$Sniffer {
|
||||||
const factory Sniffer({
|
const factory Sniffer({
|
||||||
@Default(false) bool enable,
|
@Default(false) bool enable,
|
||||||
@Default(true) @JsonKey(name: "override-destination") bool overrideDest,
|
@Default(true) @JsonKey(name: 'override-destination') bool overrideDest,
|
||||||
@Default([]) List<String> sniffing,
|
@Default([]) List<String> sniffing,
|
||||||
@Default([]) @JsonKey(name: "force-domain") List<String> forceDomain,
|
@Default([]) @JsonKey(name: 'force-domain') List<String> forceDomain,
|
||||||
@Default([]) @JsonKey(name: "skip-src-address") List<String> skipSrcAddress,
|
@Default([]) @JsonKey(name: 'skip-src-address') List<String> skipSrcAddress,
|
||||||
@Default([]) @JsonKey(name: "skip-dst-address") List<String> skipDstAddress,
|
@Default([]) @JsonKey(name: 'skip-dst-address') List<String> skipDstAddress,
|
||||||
@Default([]) @JsonKey(name: "skip-domain") List<String> skipDomain,
|
@Default([]) @JsonKey(name: 'skip-domain') List<String> skipDomain,
|
||||||
@Default([]) @JsonKey(name: "port-whitelist") List<String> port,
|
@Default([]) @JsonKey(name: 'port-whitelist') List<String> port,
|
||||||
@Default(true) @JsonKey(name: "force-dns-mapping") bool forceDnsMapping,
|
@Default(true) @JsonKey(name: 'force-dns-mapping') bool forceDnsMapping,
|
||||||
@Default(true) @JsonKey(name: "parse-pure-ip") bool parsePureIp,
|
@Default(true) @JsonKey(name: 'parse-pure-ip') bool parsePureIp,
|
||||||
@Default({}) Map<String, SnifferConfig> sniff,
|
@Default({}) Map<String, SnifferConfig> sniff,
|
||||||
}) = _Sniffer;
|
}) = _Sniffer;
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ List<String> _formJsonPorts(List? ports) {
|
|||||||
class SnifferConfig with _$SnifferConfig {
|
class SnifferConfig with _$SnifferConfig {
|
||||||
const factory SnifferConfig({
|
const factory SnifferConfig({
|
||||||
@Default([]) @JsonKey(fromJson: _formJsonPorts) List<String> ports,
|
@Default([]) @JsonKey(fromJson: _formJsonPorts) List<String> ports,
|
||||||
@JsonKey(name: "override-destination") bool? overrideDest,
|
@JsonKey(name: 'override-destination') bool? overrideDest,
|
||||||
}) = _SnifferConfig;
|
}) = _SnifferConfig;
|
||||||
|
|
||||||
factory SnifferConfig.fromJson(Map<String, Object?> json) =>
|
factory SnifferConfig.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -180,10 +180,10 @@ class Tun with _$Tun {
|
|||||||
const factory Tun({
|
const factory Tun({
|
||||||
@Default(false) bool enable,
|
@Default(false) bool enable,
|
||||||
@Default(appName) String device,
|
@Default(appName) String device,
|
||||||
@JsonKey(name: "auto-route") @Default(false) bool autoRoute,
|
@JsonKey(name: 'auto-route') @Default(false) bool autoRoute,
|
||||||
@Default(TunStack.mixed) TunStack stack,
|
@Default(TunStack.mixed) TunStack stack,
|
||||||
@JsonKey(name: "dns-hijack") @Default(["any:53"]) List<String> dnsHijack,
|
@JsonKey(name: 'dns-hijack') @Default(['any:53']) List<String> dnsHijack,
|
||||||
@JsonKey(name: "route-address") @Default([]) List<String> routeAddress,
|
@JsonKey(name: 'route-address') @Default([]) List<String> routeAddress,
|
||||||
}) = _Tun;
|
}) = _Tun;
|
||||||
|
|
||||||
factory Tun.fromJson(Map<String, Object?> json) => _$TunFromJson(json);
|
factory Tun.fromJson(Map<String, Object?> json) => _$TunFromJson(json);
|
||||||
@@ -222,13 +222,13 @@ extension TunExt on Tun {
|
|||||||
class FallbackFilter with _$FallbackFilter {
|
class FallbackFilter with _$FallbackFilter {
|
||||||
const factory FallbackFilter({
|
const factory FallbackFilter({
|
||||||
@Default(true) bool geoip,
|
@Default(true) bool geoip,
|
||||||
@Default("CN") @JsonKey(name: "geoip-code") String geoipCode,
|
@Default('CN') @JsonKey(name: 'geoip-code') String geoipCode,
|
||||||
@Default(["gfw"]) List<String> geosite,
|
@Default(['gfw']) List<String> geosite,
|
||||||
@Default(["240.0.0.0/4"]) List<String> ipcidr,
|
@Default(['240.0.0.0/4']) List<String> ipcidr,
|
||||||
@Default([
|
@Default([
|
||||||
"+.google.com",
|
'+.google.com',
|
||||||
"+.facebook.com",
|
'+.facebook.com',
|
||||||
"+.youtube.com",
|
'+.youtube.com',
|
||||||
])
|
])
|
||||||
List<String> domain,
|
List<String> domain,
|
||||||
}) = _FallbackFilter;
|
}) = _FallbackFilter;
|
||||||
@@ -241,51 +241,51 @@ class FallbackFilter with _$FallbackFilter {
|
|||||||
class Dns with _$Dns {
|
class Dns with _$Dns {
|
||||||
const factory Dns({
|
const factory Dns({
|
||||||
@Default(true) bool enable,
|
@Default(true) bool enable,
|
||||||
@Default("0.0.0.0:1053") String listen,
|
@Default('0.0.0.0:1053') String listen,
|
||||||
@Default(false) @JsonKey(name: "prefer-h3") bool preferH3,
|
@Default(false) @JsonKey(name: 'prefer-h3') bool preferH3,
|
||||||
@Default(true) @JsonKey(name: "use-hosts") bool useHosts,
|
@Default(true) @JsonKey(name: 'use-hosts') bool useHosts,
|
||||||
@Default(true) @JsonKey(name: "use-system-hosts") bool useSystemHosts,
|
@Default(true) @JsonKey(name: 'use-system-hosts') bool useSystemHosts,
|
||||||
@Default(false) @JsonKey(name: "respect-rules") bool respectRules,
|
@Default(false) @JsonKey(name: 'respect-rules') bool respectRules,
|
||||||
@Default(false) bool ipv6,
|
@Default(false) bool ipv6,
|
||||||
@Default(["223.5.5.5"])
|
@Default(['223.5.5.5'])
|
||||||
@JsonKey(name: "default-nameserver")
|
@JsonKey(name: 'default-nameserver')
|
||||||
List<String> defaultNameserver,
|
List<String> defaultNameserver,
|
||||||
@Default(DnsMode.fakeIp)
|
@Default(DnsMode.fakeIp)
|
||||||
@JsonKey(name: "enhanced-mode")
|
@JsonKey(name: 'enhanced-mode')
|
||||||
DnsMode enhancedMode,
|
DnsMode enhancedMode,
|
||||||
@Default("198.18.0.1/16")
|
@Default('198.18.0.1/16')
|
||||||
@JsonKey(name: "fake-ip-range")
|
@JsonKey(name: 'fake-ip-range')
|
||||||
String fakeIpRange,
|
String fakeIpRange,
|
||||||
@Default([
|
@Default([
|
||||||
"*.lan",
|
'*.lan',
|
||||||
"localhost.ptlogin2.qq.com",
|
'localhost.ptlogin2.qq.com',
|
||||||
])
|
])
|
||||||
@JsonKey(name: "fake-ip-filter")
|
@JsonKey(name: 'fake-ip-filter')
|
||||||
List<String> fakeIpFilter,
|
List<String> fakeIpFilter,
|
||||||
@Default({
|
@Default({
|
||||||
"www.baidu.com": "114.114.114.114",
|
'www.baidu.com': '114.114.114.114',
|
||||||
"+.internal.crop.com": "10.0.0.1",
|
'+.internal.crop.com': '10.0.0.1',
|
||||||
"geosite:cn": "https://doh.pub/dns-query"
|
'geosite:cn': 'https://doh.pub/dns-query'
|
||||||
})
|
})
|
||||||
@JsonKey(name: "nameserver-policy")
|
@JsonKey(name: 'nameserver-policy')
|
||||||
Map<String, String> nameserverPolicy,
|
Map<String, String> nameserverPolicy,
|
||||||
@Default([
|
@Default([
|
||||||
"https://doh.pub/dns-query",
|
'https://doh.pub/dns-query',
|
||||||
"https://dns.alidns.com/dns-query",
|
'https://dns.alidns.com/dns-query',
|
||||||
])
|
])
|
||||||
List<String> nameserver,
|
List<String> nameserver,
|
||||||
@Default([
|
@Default([
|
||||||
"tls://8.8.4.4",
|
'tls://8.8.4.4',
|
||||||
"tls://1.1.1.1",
|
'tls://1.1.1.1',
|
||||||
])
|
])
|
||||||
List<String> fallback,
|
List<String> fallback,
|
||||||
@Default([
|
@Default([
|
||||||
"https://doh.pub/dns-query",
|
'https://doh.pub/dns-query',
|
||||||
])
|
])
|
||||||
@JsonKey(name: "proxy-server-nameserver")
|
@JsonKey(name: 'proxy-server-nameserver')
|
||||||
List<String> proxyServerNameserver,
|
List<String> proxyServerNameserver,
|
||||||
@Default(FallbackFilter())
|
@Default(FallbackFilter())
|
||||||
@JsonKey(name: "fallback-filter")
|
@JsonKey(name: 'fallback-filter')
|
||||||
FallbackFilter fallbackFilter,
|
FallbackFilter fallbackFilter,
|
||||||
}) = _Dns;
|
}) = _Dns;
|
||||||
|
|
||||||
@@ -304,19 +304,19 @@ class Dns with _$Dns {
|
|||||||
class GeoXUrl with _$GeoXUrl {
|
class GeoXUrl with _$GeoXUrl {
|
||||||
const factory GeoXUrl({
|
const factory GeoXUrl({
|
||||||
@Default(
|
@Default(
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb',
|
||||||
)
|
)
|
||||||
String mmdb,
|
String mmdb,
|
||||||
@Default(
|
@Default(
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb',
|
||||||
)
|
)
|
||||||
String asn,
|
String asn,
|
||||||
@Default(
|
@Default(
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat',
|
||||||
)
|
)
|
||||||
String geoip,
|
String geoip,
|
||||||
@Default(
|
@Default(
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat',
|
||||||
)
|
)
|
||||||
String geosite,
|
String geosite,
|
||||||
}) = _GeoXUrl;
|
}) = _GeoXUrl;
|
||||||
@@ -349,10 +349,10 @@ class ParsedRule with _$ParsedRule {
|
|||||||
}) = _ParsedRule;
|
}) = _ParsedRule;
|
||||||
|
|
||||||
factory ParsedRule.parseString(String value) {
|
factory ParsedRule.parseString(String value) {
|
||||||
final splits = value.split(",");
|
final splits = value.split(',');
|
||||||
final shortSplits = splits
|
final shortSplits = splits
|
||||||
.where(
|
.where(
|
||||||
(item) => !item.contains("src") && !item.contains("no-resolve"),
|
(item) => !item.contains('src') && !item.contains('no-resolve'),
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
final ruleAction = RuleAction.values.firstWhere(
|
final ruleAction = RuleAction.values.firstWhere(
|
||||||
@@ -372,17 +372,17 @@ class ParsedRule with _$ParsedRule {
|
|||||||
String? ruleProvider;
|
String? ruleProvider;
|
||||||
|
|
||||||
if (ruleAction == RuleAction.RULE_SET) {
|
if (ruleAction == RuleAction.RULE_SET) {
|
||||||
ruleProvider = shortSplits.sublist(1, shortSplits.length - 1).join(",");
|
ruleProvider = shortSplits.sublist(1, shortSplits.length - 1).join(',');
|
||||||
} else {
|
} else {
|
||||||
content = shortSplits.sublist(1, shortSplits.length - 1).join(",");
|
content = shortSplits.sublist(1, shortSplits.length - 1).join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParsedRule(
|
return ParsedRule(
|
||||||
ruleAction: ruleAction,
|
ruleAction: ruleAction,
|
||||||
content: content,
|
content: content,
|
||||||
src: splits.contains("src"),
|
src: splits.contains('src'),
|
||||||
ruleProvider: ruleProvider,
|
ruleProvider: ruleProvider,
|
||||||
noResolve: splits.contains("no-resolve"),
|
noResolve: splits.contains('no-resolve'),
|
||||||
subRule: subRule,
|
subRule: subRule,
|
||||||
ruleTarget: ruleTarget,
|
ruleTarget: ruleTarget,
|
||||||
);
|
);
|
||||||
@@ -396,10 +396,10 @@ extension ParsedRuleExt on ParsedRule {
|
|||||||
ruleAction == RuleAction.RULE_SET ? ruleProvider : content,
|
ruleAction == RuleAction.RULE_SET ? ruleProvider : content,
|
||||||
ruleAction == RuleAction.SUB_RULE ? subRule : ruleTarget,
|
ruleAction == RuleAction.SUB_RULE ? subRule : ruleTarget,
|
||||||
if (ruleAction.hasParams) ...[
|
if (ruleAction.hasParams) ...[
|
||||||
if (src) "src",
|
if (src) 'src',
|
||||||
if (noResolve) "no-resolve",
|
if (noResolve) 'no-resolve',
|
||||||
]
|
]
|
||||||
].join(",");
|
].join(',');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +430,7 @@ class SubRule with _$SubRule {
|
|||||||
_$SubRuleFromJson(json);
|
_$SubRuleFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
_genRule(List<dynamic>? rules) {
|
List<Rule> _genRule(List<dynamic>? rules) {
|
||||||
if (rules == null) {
|
if (rules == null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -458,12 +458,12 @@ List<SubRule> _genSubRules(Map<String, dynamic> json) {
|
|||||||
@freezed
|
@freezed
|
||||||
class ClashConfigSnippet with _$ClashConfigSnippet {
|
class ClashConfigSnippet with _$ClashConfigSnippet {
|
||||||
const factory ClashConfigSnippet({
|
const factory ClashConfigSnippet({
|
||||||
@Default([]) @JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
@Default([]) @JsonKey(name: 'proxy-groups') List<ProxyGroup> proxyGroups,
|
||||||
@JsonKey(fromJson: _genRule, name: "rules") @Default([]) List<Rule> rule,
|
@JsonKey(fromJson: _genRule, name: 'rules') @Default([]) List<Rule> rule,
|
||||||
@JsonKey(name: "rule-providers", fromJson: _genRuleProviders)
|
@JsonKey(name: 'rule-providers', fromJson: _genRuleProviders)
|
||||||
@Default([])
|
@Default([])
|
||||||
List<RuleProvider> ruleProvider,
|
List<RuleProvider> ruleProvider,
|
||||||
@JsonKey(name: "sub-rules", fromJson: _genSubRules)
|
@JsonKey(name: 'sub-rules', fromJson: _genSubRules)
|
||||||
@Default([])
|
@Default([])
|
||||||
List<SubRule> subRules,
|
List<SubRule> subRules,
|
||||||
}) = _ClashConfigSnippet;
|
}) = _ClashConfigSnippet;
|
||||||
@@ -475,39 +475,39 @@ class ClashConfigSnippet with _$ClashConfigSnippet {
|
|||||||
@freezed
|
@freezed
|
||||||
class ClashConfig with _$ClashConfig {
|
class ClashConfig with _$ClashConfig {
|
||||||
const factory ClashConfig({
|
const factory ClashConfig({
|
||||||
@Default(defaultMixedPort) @JsonKey(name: "mixed-port") int mixedPort,
|
@Default(defaultMixedPort) @JsonKey(name: 'mixed-port') int mixedPort,
|
||||||
@Default(0) @JsonKey(name: "socks-port") int socksPort,
|
@Default(0) @JsonKey(name: 'socks-port') int socksPort,
|
||||||
@Default(0) @JsonKey(name: "port") int port,
|
@Default(0) @JsonKey(name: 'port') int port,
|
||||||
@Default(0) @JsonKey(name: "redir-port") int redirPort,
|
@Default(0) @JsonKey(name: 'redir-port') int redirPort,
|
||||||
@Default(0) @JsonKey(name: "tproxy-port") int tproxyPort,
|
@Default(0) @JsonKey(name: 'tproxy-port') int tproxyPort,
|
||||||
@Default(Mode.rule) Mode mode,
|
@Default(Mode.rule) Mode mode,
|
||||||
@Default(false) @JsonKey(name: "allow-lan") bool allowLan,
|
@Default(false) @JsonKey(name: 'allow-lan') bool allowLan,
|
||||||
@Default(LogLevel.error) @JsonKey(name: "log-level") LogLevel logLevel,
|
@Default(LogLevel.error) @JsonKey(name: 'log-level') LogLevel logLevel,
|
||||||
@Default(false) bool ipv6,
|
@Default(false) bool ipv6,
|
||||||
@Default(FindProcessMode.off)
|
@Default(FindProcessMode.off)
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: "find-process-mode",
|
name: 'find-process-mode',
|
||||||
unknownEnumValue: FindProcessMode.always,
|
unknownEnumValue: FindProcessMode.always,
|
||||||
)
|
)
|
||||||
FindProcessMode findProcessMode,
|
FindProcessMode findProcessMode,
|
||||||
@Default(defaultKeepAliveInterval)
|
@Default(defaultKeepAliveInterval)
|
||||||
@JsonKey(name: "keep-alive-interval")
|
@JsonKey(name: 'keep-alive-interval')
|
||||||
int keepAliveInterval,
|
int keepAliveInterval,
|
||||||
@Default(true) @JsonKey(name: "unified-delay") bool unifiedDelay,
|
@Default(true) @JsonKey(name: 'unified-delay') bool unifiedDelay,
|
||||||
@Default(true) @JsonKey(name: "tcp-concurrent") bool tcpConcurrent,
|
@Default(true) @JsonKey(name: 'tcp-concurrent') bool tcpConcurrent,
|
||||||
@Default(defaultTun) @JsonKey(fromJson: Tun.safeFormJson) Tun tun,
|
@Default(defaultTun) @JsonKey(fromJson: Tun.safeFormJson) Tun tun,
|
||||||
@Default(defaultDns) @JsonKey(fromJson: Dns.safeDnsFromJson) Dns dns,
|
@Default(defaultDns) @JsonKey(fromJson: Dns.safeDnsFromJson) Dns dns,
|
||||||
@Default(defaultGeoXUrl)
|
@Default(defaultGeoXUrl)
|
||||||
@JsonKey(name: "geox-url", fromJson: GeoXUrl.safeFormJson)
|
@JsonKey(name: 'geox-url', fromJson: GeoXUrl.safeFormJson)
|
||||||
GeoXUrl geoXUrl,
|
GeoXUrl geoXUrl,
|
||||||
@Default(GeodataLoader.memconservative)
|
@Default(GeodataLoader.memconservative)
|
||||||
@JsonKey(name: "geodata-loader")
|
@JsonKey(name: 'geodata-loader')
|
||||||
GeodataLoader geodataLoader,
|
GeodataLoader geodataLoader,
|
||||||
@Default([]) @JsonKey(name: "proxy-groups") List<ProxyGroup> proxyGroups,
|
@Default([]) @JsonKey(name: 'proxy-groups') List<ProxyGroup> proxyGroups,
|
||||||
@Default([]) List<String> rule,
|
@Default([]) List<String> rule,
|
||||||
@JsonKey(name: "global-ua") String? globalUa,
|
@JsonKey(name: 'global-ua') String? globalUa,
|
||||||
@Default(ExternalControllerStatus.close)
|
@Default(ExternalControllerStatus.close)
|
||||||
@JsonKey(name: "external-controller")
|
@JsonKey(name: 'external-controller')
|
||||||
ExternalControllerStatus externalController,
|
ExternalControllerStatus externalController,
|
||||||
@Default({}) HostsMap hosts,
|
@Default({}) HostsMap hosts,
|
||||||
}) = _ClashConfig;
|
}) = _ClashConfig;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class NavigationItem with _$NavigationItem {
|
|||||||
required Icon icon,
|
required Icon icon,
|
||||||
required PageLabel label,
|
required PageLabel label,
|
||||||
final String? description,
|
final String? description,
|
||||||
required Widget view,
|
required WidgetBuilder builder,
|
||||||
@Default(true) bool keep,
|
@Default(true) bool keep,
|
||||||
String? path,
|
String? path,
|
||||||
@Default([NavigationItemMode.mobile, NavigationItemMode.desktop])
|
@Default([NavigationItemMode.mobile, NavigationItemMode.desktop])
|
||||||
@@ -41,15 +41,23 @@ class Package with _$Package {
|
|||||||
@freezed
|
@freezed
|
||||||
class Metadata with _$Metadata {
|
class Metadata with _$Metadata {
|
||||||
const factory Metadata({
|
const factory Metadata({
|
||||||
required int uid,
|
@Default(0) int uid,
|
||||||
required String network,
|
@Default('') String network,
|
||||||
required String sourceIP,
|
@Default('') String sourceIP,
|
||||||
required String sourcePort,
|
@Default('') String sourcePort,
|
||||||
required String destinationIP,
|
@Default('') String destinationIP,
|
||||||
required String destinationPort,
|
@Default('') String destinationPort,
|
||||||
required String host,
|
@Default('') String host,
|
||||||
required String process,
|
DnsMode? dnsMode,
|
||||||
required String remoteDestination,
|
@Default('') String process,
|
||||||
|
@Default('') String processPath,
|
||||||
|
@Default('') String remoteDestination,
|
||||||
|
@Default([]) List<String> sourceGeoIP,
|
||||||
|
@Default([]) List<String> destinationGeoIP,
|
||||||
|
@Default('') String destinationIPASN,
|
||||||
|
@Default('') String sourceIPASN,
|
||||||
|
@Default('') String specialRules,
|
||||||
|
@Default('') String specialProxy,
|
||||||
}) = _Metadata;
|
}) = _Metadata;
|
||||||
|
|
||||||
factory Metadata.fromJson(Map<String, Object?> json) =>
|
factory Metadata.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -57,35 +65,48 @@ class Metadata with _$Metadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class Connection with _$Connection {
|
class TrackerInfo with _$TrackerInfo {
|
||||||
const factory Connection({
|
const factory TrackerInfo({
|
||||||
required String id,
|
required String id,
|
||||||
num? upload,
|
@Default(0) int upload,
|
||||||
num? download,
|
@Default(0) int download,
|
||||||
required DateTime start,
|
required DateTime start,
|
||||||
required Metadata metadata,
|
required Metadata metadata,
|
||||||
required List<String> chains,
|
required List<String> chains,
|
||||||
}) = _Connection;
|
required String rule,
|
||||||
|
required String rulePayload,
|
||||||
|
int? downloadSpeed,
|
||||||
|
int? uploadSpeed,
|
||||||
|
}) = _TrackerInfo;
|
||||||
|
|
||||||
factory Connection.fromJson(Map<String, Object?> json) =>
|
factory TrackerInfo.fromJson(Map<String, Object?> json) =>
|
||||||
_$ConnectionFromJson(json);
|
_$TrackerInfoFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ConnectionExt on Connection {
|
extension TrackerInfoExt on TrackerInfo {
|
||||||
String get desc {
|
String get desc {
|
||||||
var text = "${metadata.network}://";
|
var text = '${metadata.network}://';
|
||||||
final ips = [
|
final ips = [
|
||||||
metadata.host,
|
metadata.host,
|
||||||
metadata.destinationIP,
|
metadata.destinationIP,
|
||||||
].where((ip) => ip.isNotEmpty);
|
].where((ip) => ip.isNotEmpty);
|
||||||
text += ips.join("/");
|
text += ips.join('/');
|
||||||
text += ":${metadata.destinationPort}";
|
text += ':${metadata.destinationPort}';
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get progressText {
|
||||||
|
final process = metadata.process;
|
||||||
|
final uid = metadata.uid;
|
||||||
|
if (uid != 0) {
|
||||||
|
return '$process($uid)';
|
||||||
|
}
|
||||||
|
return process;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _logDateTime(_) {
|
String _logDateTime(dynamic _) {
|
||||||
return DateTime.now().toString();
|
return DateTime.now().showFull;
|
||||||
}
|
}
|
||||||
|
|
||||||
// String _logId(_) {
|
// String _logId(_) {
|
||||||
@@ -95,8 +116,9 @@ String _logDateTime(_) {
|
|||||||
@freezed
|
@freezed
|
||||||
class Log with _$Log {
|
class Log with _$Log {
|
||||||
const factory Log({
|
const factory Log({
|
||||||
@JsonKey(name: "LogLevel") @Default(LogLevel.app) LogLevel logLevel,
|
// @JsonKey(fromJson: _logId) required String id,
|
||||||
@JsonKey(name: "Payload") @Default("") String payload,
|
@JsonKey(name: 'LogLevel') @Default(LogLevel.info) LogLevel logLevel,
|
||||||
|
@JsonKey(name: 'Payload') @Default('') String payload,
|
||||||
@JsonKey(fromJson: _logDateTime) required String dateTime,
|
@JsonKey(fromJson: _logDateTime) required String dateTime,
|
||||||
}) = _Log;
|
}) = _Log;
|
||||||
|
|
||||||
@@ -118,8 +140,8 @@ class LogsState with _$LogsState {
|
|||||||
const factory LogsState({
|
const factory LogsState({
|
||||||
@Default([]) List<Log> logs,
|
@Default([]) List<Log> logs,
|
||||||
@Default([]) List<String> keywords,
|
@Default([]) List<String> keywords,
|
||||||
@Default("") String query,
|
@Default('') String query,
|
||||||
@Default(false) bool loading,
|
@Default(true) bool autoScrollToEnd,
|
||||||
}) = _LogsState;
|
}) = _LogsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,27 +160,28 @@ extension LogsStateExt on LogsState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ConnectionsState with _$ConnectionsState {
|
class TrackerInfosState with _$TrackerInfosState {
|
||||||
const factory ConnectionsState({
|
const factory TrackerInfosState({
|
||||||
@Default([]) List<Connection> connections,
|
@Default([]) List<TrackerInfo> trackerInfos,
|
||||||
@Default([]) List<String> keywords,
|
@Default([]) List<String> keywords,
|
||||||
@Default("") String query,
|
@Default('') String query,
|
||||||
@Default(false) bool loading,
|
@Default(true) bool autoScrollToEnd,
|
||||||
}) = _ConnectionsState;
|
}) = _TrackerInfosState;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ConnectionsStateExt on ConnectionsState {
|
extension TrackerInfosStateExt on TrackerInfosState {
|
||||||
List<Connection> get list {
|
List<TrackerInfo> get list {
|
||||||
final lowerQuery = query.toLowerCase().trim();
|
final lowerQuery = query.toLowerCase().trim();
|
||||||
final lowQuery = query.toLowerCase();
|
final lowQuery = query.toLowerCase();
|
||||||
return connections.where((connection) {
|
return trackerInfos.where((trackerInfo) {
|
||||||
final chains = connection.chains;
|
final chains = trackerInfo.chains;
|
||||||
final process = connection.metadata.process;
|
final process = trackerInfo.metadata.process;
|
||||||
final networkText = connection.metadata.network.toLowerCase();
|
final networkText = trackerInfo.metadata.network.toLowerCase();
|
||||||
final hostText = connection.metadata.host.toLowerCase();
|
final hostText = trackerInfo.metadata.host.toLowerCase();
|
||||||
final destinationIPText = connection.metadata.destinationIP.toLowerCase();
|
final destinationIPText =
|
||||||
final processText = connection.metadata.process.toLowerCase();
|
trackerInfo.metadata.destinationIP.toLowerCase();
|
||||||
final chainsText = chains.join("").toLowerCase();
|
final processText = trackerInfo.metadata.process.toLowerCase();
|
||||||
|
final chainsText = chains.join('').toLowerCase();
|
||||||
return {...chains, process}.containsAll(keywords) &&
|
return {...chains, process}.containsAll(keywords) &&
|
||||||
(networkText.contains(lowerQuery) ||
|
(networkText.contains(lowerQuery) ||
|
||||||
hostText.contains(lowerQuery) ||
|
hostText.contains(lowerQuery) ||
|
||||||
@@ -169,7 +192,7 @@ extension ConnectionsStateExt on ConnectionsState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultDavFileName = "backup.zip";
|
const defaultDavFileName = 'backup.zip';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class DAV with _$DAV {
|
class DAV with _$DAV {
|
||||||
@@ -193,14 +216,14 @@ class FileInfo with _$FileInfo {
|
|||||||
|
|
||||||
extension FileInfoExt on FileInfo {
|
extension FileInfoExt on FileInfo {
|
||||||
String get desc =>
|
String get desc =>
|
||||||
"${TrafficValue(value: size).show} · ${lastModified.lastUpdateTimeDesc}";
|
'${TrafficValue(value: size).show} · ${lastModified.lastUpdateTimeDesc}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class VersionInfo with _$VersionInfo {
|
class VersionInfo with _$VersionInfo {
|
||||||
const factory VersionInfo({
|
const factory VersionInfo({
|
||||||
@Default("") String clashName,
|
@Default('') String clashName,
|
||||||
@Default("") String version,
|
@Default('') String version,
|
||||||
}) = _VersionInfo;
|
}) = _VersionInfo;
|
||||||
|
|
||||||
factory VersionInfo.fromJson(Map<String, Object?> json) =>
|
factory VersionInfo.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -226,6 +249,10 @@ class Traffic {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String toSpeedText() {
|
||||||
|
return '↑ $up/s ↓ $down/s';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return '$up↑ $down↓';
|
return '$up↑ $down↓';
|
||||||
@@ -274,7 +301,7 @@ class Group with _$Group {
|
|||||||
String? now,
|
String? now,
|
||||||
bool? hidden,
|
bool? hidden,
|
||||||
String? testUrl,
|
String? testUrl,
|
||||||
@Default("") String icon,
|
@Default('') String icon,
|
||||||
required String name,
|
required String name,
|
||||||
}) = _Group;
|
}) = _Group;
|
||||||
|
|
||||||
@@ -289,7 +316,7 @@ extension GroupsExt on List<Group> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension GroupExt on Group {
|
extension GroupExt on Group {
|
||||||
String get realNow => now ?? "";
|
String get realNow => now ?? '';
|
||||||
|
|
||||||
String getCurrentSelectedName(String proxyName) {
|
String getCurrentSelectedName(String proxyName) {
|
||||||
if (type.isComputedSelected) {
|
if (type.isComputedSelected) {
|
||||||
@@ -307,10 +334,10 @@ class TrafficValue {
|
|||||||
|
|
||||||
int get value => _value;
|
int get value => _value;
|
||||||
|
|
||||||
String get show => "$showValue $showUnit";
|
String get show => '$showValue $showUnit';
|
||||||
|
|
||||||
String get shortShow =>
|
String get shortShow =>
|
||||||
"${trafficValueShow.value.fixed(decimals: 1)} $showUnit";
|
'${trafficValueShow.value.fixed(decimals: 1)} $showUnit';
|
||||||
|
|
||||||
String get showValue => trafficValueShow.value.fixed();
|
String get showValue => trafficValueShow.value.fixed();
|
||||||
|
|
||||||
@@ -347,7 +374,7 @@ class TrafficValue {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return "$showValue$showUnit";
|
return '$showValue$showUnit';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -411,56 +438,56 @@ class IpInfo {
|
|||||||
static IpInfo fromIpInfoIoJson(Map<String, dynamic> json) {
|
static IpInfo fromIpInfoIoJson(Map<String, dynamic> json) {
|
||||||
return switch (json) {
|
return switch (json) {
|
||||||
{
|
{
|
||||||
"ip": final String ip,
|
'ip': final String ip,
|
||||||
"country": final String country,
|
'country': final String country,
|
||||||
} =>
|
} =>
|
||||||
IpInfo(
|
IpInfo(
|
||||||
ip: ip,
|
ip: ip,
|
||||||
countryCode: country,
|
countryCode: country,
|
||||||
),
|
),
|
||||||
_ => throw const FormatException("invalid json"),
|
_ => throw const FormatException('invalid json'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static IpInfo fromIpApiCoJson(Map<String, dynamic> json) {
|
static IpInfo fromIpApiCoJson(Map<String, dynamic> json) {
|
||||||
return switch (json) {
|
return switch (json) {
|
||||||
{
|
{
|
||||||
"ip": final String ip,
|
'ip': final String ip,
|
||||||
"country_code": final String countryCode,
|
'country_code': final String countryCode,
|
||||||
} =>
|
} =>
|
||||||
IpInfo(
|
IpInfo(
|
||||||
ip: ip,
|
ip: ip,
|
||||||
countryCode: countryCode,
|
countryCode: countryCode,
|
||||||
),
|
),
|
||||||
_ => throw const FormatException("invalid json"),
|
_ => throw const FormatException('invalid json'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static IpInfo fromIpSbJson(Map<String, dynamic> json) {
|
static IpInfo fromIpSbJson(Map<String, dynamic> json) {
|
||||||
return switch (json) {
|
return switch (json) {
|
||||||
{
|
{
|
||||||
"ip": final String ip,
|
'ip': final String ip,
|
||||||
"country_code": final String countryCode,
|
'country_code': final String countryCode,
|
||||||
} =>
|
} =>
|
||||||
IpInfo(
|
IpInfo(
|
||||||
ip: ip,
|
ip: ip,
|
||||||
countryCode: countryCode,
|
countryCode: countryCode,
|
||||||
),
|
),
|
||||||
_ => throw const FormatException("invalid json"),
|
_ => throw const FormatException('invalid json'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static IpInfo fromIpwhoIsJson(Map<String, dynamic> json) {
|
static IpInfo fromIpwhoIsJson(Map<String, dynamic> json) {
|
||||||
return switch (json) {
|
return switch (json) {
|
||||||
{
|
{
|
||||||
"ip": final String ip,
|
'ip': final String ip,
|
||||||
"country_code": final String countryCode,
|
'country_code': final String countryCode,
|
||||||
} =>
|
} =>
|
||||||
IpInfo(
|
IpInfo(
|
||||||
ip: ip,
|
ip: ip,
|
||||||
countryCode: countryCode,
|
countryCode: countryCode,
|
||||||
),
|
),
|
||||||
_ => throw const FormatException("invalid json"),
|
_ => throw const FormatException('invalid json'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,7 +566,7 @@ class Result<T> with _$Result<T> {
|
|||||||
factory Result.success(T data) => Result(
|
factory Result.success(T data) => Result(
|
||||||
data: data,
|
data: data,
|
||||||
type: ResultType.success,
|
type: ResultType.success,
|
||||||
message: "",
|
message: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
factory Result.error(String message) => Result(
|
factory Result.error(String message) => Result(
|
||||||
|
|||||||
@@ -11,23 +11,23 @@ part 'generated/config.freezed.dart';
|
|||||||
part 'generated/config.g.dart';
|
part 'generated/config.g.dart';
|
||||||
|
|
||||||
const defaultBypassDomain = [
|
const defaultBypassDomain = [
|
||||||
"*zhihu.com",
|
'*zhihu.com',
|
||||||
"*zhimg.com",
|
'*zhimg.com',
|
||||||
"*jd.com",
|
'*jd.com',
|
||||||
"100ime-iat-api.xfyun.cn",
|
'100ime-iat-api.xfyun.cn',
|
||||||
"*360buyimg.com",
|
'*360buyimg.com',
|
||||||
"localhost",
|
'localhost',
|
||||||
"*.local",
|
'*.local',
|
||||||
"127.*",
|
'127.*',
|
||||||
"10.*",
|
'10.*',
|
||||||
"172.16.*",
|
'172.16.*',
|
||||||
"172.17.*",
|
'172.17.*',
|
||||||
"172.18.*",
|
'172.18.*',
|
||||||
"172.19.*",
|
'172.19.*',
|
||||||
"172.2*",
|
'172.2*',
|
||||||
"172.30.*",
|
'172.30.*',
|
||||||
"172.31.*",
|
'172.31.*',
|
||||||
"192.168.*"
|
'192.168.*'
|
||||||
];
|
];
|
||||||
|
|
||||||
const defaultAppSettingProps = AppSettingProps();
|
const defaultAppSettingProps = AppSettingProps();
|
||||||
@@ -178,8 +178,8 @@ class ProxiesStyle with _$ProxiesStyle {
|
|||||||
@freezed
|
@freezed
|
||||||
class TextScale with _$TextScale {
|
class TextScale with _$TextScale {
|
||||||
const factory TextScale({
|
const factory TextScale({
|
||||||
@Default(false) enable,
|
@Default(false) bool enable,
|
||||||
@Default(1.0) scale,
|
@Default(1.0) double scale,
|
||||||
}) = _TextScale;
|
}) = _TextScale;
|
||||||
|
|
||||||
factory TextScale.fromJson(Map<String, Object?> json) =>
|
factory TextScale.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -265,12 +265,12 @@ class Config with _$Config {
|
|||||||
|
|
||||||
factory Config.compatibleFromJson(Map<String, Object?> json) {
|
factory Config.compatibleFromJson(Map<String, Object?> json) {
|
||||||
try {
|
try {
|
||||||
final accessControlMap = json["accessControl"];
|
final accessControlMap = json['accessControl'];
|
||||||
final isAccessControl = json["isAccessControl"];
|
final isAccessControl = json['isAccessControl'];
|
||||||
if (accessControlMap != null) {
|
if (accessControlMap != null) {
|
||||||
(accessControlMap as Map)["enable"] = isAccessControl;
|
(accessControlMap as Map)['enable'] = isAccessControl;
|
||||||
if (json["vpnProps"] != null) {
|
if (json['vpnProps'] != null) {
|
||||||
(json["vpnProps"] as Map)["accessControl"] = accessControlMap;
|
(json['vpnProps'] as Map)['accessControl'] = accessControlMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ abstract mixin class AppMessageListener {
|
|||||||
|
|
||||||
void onDelay(Delay delay) {}
|
void onDelay(Delay delay) {}
|
||||||
|
|
||||||
void onRequest(Connection connection) {}
|
void onRequest(TrackerInfo connection) {}
|
||||||
|
|
||||||
void onLoaded(String providerName) {}
|
void onLoaded(String providerName) {}
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,9 @@ abstract mixin class AppMessageListener {
|
|||||||
@freezed
|
@freezed
|
||||||
class SetupParams with _$SetupParams {
|
class SetupParams with _$SetupParams {
|
||||||
const factory SetupParams({
|
const factory SetupParams({
|
||||||
@JsonKey(name: "config") required Map<String, dynamic> config,
|
@JsonKey(name: 'config') required Map<String, dynamic> config,
|
||||||
@JsonKey(name: "selected-map") required Map<String, String> selectedMap,
|
@JsonKey(name: 'selected-map') required Map<String, String> selectedMap,
|
||||||
@JsonKey(name: "test-url") required String testUrl,
|
@JsonKey(name: 'test-url') required String testUrl,
|
||||||
}) = _SetupParams;
|
}) = _SetupParams;
|
||||||
|
|
||||||
factory SetupParams.fromJson(Map<String, dynamic> json) =>
|
factory SetupParams.fromJson(Map<String, dynamic> json) =>
|
||||||
@@ -68,10 +68,10 @@ class UpdateParams with _$UpdateParams {
|
|||||||
@freezed
|
@freezed
|
||||||
class CoreState with _$CoreState {
|
class CoreState with _$CoreState {
|
||||||
const factory CoreState({
|
const factory CoreState({
|
||||||
@JsonKey(name: "vpn-props") required VpnProps vpnProps,
|
@JsonKey(name: 'vpn-props') required VpnProps vpnProps,
|
||||||
@JsonKey(name: "only-statistics-proxy") required bool onlyStatisticsProxy,
|
@JsonKey(name: 'only-statistics-proxy') required bool onlyStatisticsProxy,
|
||||||
@JsonKey(name: "current-profile-name") required String currentProfileName,
|
@JsonKey(name: 'current-profile-name') required String currentProfileName,
|
||||||
@JsonKey(name: "bypass-domain") @Default([]) List<String> bypassDomain,
|
@JsonKey(name: 'bypass-domain') @Default([]) List<String> bypassDomain,
|
||||||
}) = _CoreState;
|
}) = _CoreState;
|
||||||
|
|
||||||
factory CoreState.fromJson(Map<String, Object?> json) =>
|
factory CoreState.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -100,7 +100,7 @@ class AndroidVpnOptions with _$AndroidVpnOptions {
|
|||||||
@freezed
|
@freezed
|
||||||
class InitParams with _$InitParams {
|
class InitParams with _$InitParams {
|
||||||
const factory InitParams({
|
const factory InitParams({
|
||||||
@JsonKey(name: "home-dir") required String homeDir,
|
@JsonKey(name: 'home-dir') required String homeDir,
|
||||||
required int version,
|
required int version,
|
||||||
}) = _InitParams;
|
}) = _InitParams;
|
||||||
|
|
||||||
@@ -111,8 +111,8 @@ class InitParams with _$InitParams {
|
|||||||
@freezed
|
@freezed
|
||||||
class ChangeProxyParams with _$ChangeProxyParams {
|
class ChangeProxyParams with _$ChangeProxyParams {
|
||||||
const factory ChangeProxyParams({
|
const factory ChangeProxyParams({
|
||||||
@JsonKey(name: "group-name") required String groupName,
|
@JsonKey(name: 'group-name') required String groupName,
|
||||||
@JsonKey(name: "proxy-name") required String proxyName,
|
@JsonKey(name: 'proxy-name') required String proxyName,
|
||||||
}) = _ChangeProxyParams;
|
}) = _ChangeProxyParams;
|
||||||
|
|
||||||
factory ChangeProxyParams.fromJson(Map<String, Object?> json) =>
|
factory ChangeProxyParams.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -122,8 +122,8 @@ class ChangeProxyParams with _$ChangeProxyParams {
|
|||||||
@freezed
|
@freezed
|
||||||
class UpdateGeoDataParams with _$UpdateGeoDataParams {
|
class UpdateGeoDataParams with _$UpdateGeoDataParams {
|
||||||
const factory UpdateGeoDataParams({
|
const factory UpdateGeoDataParams({
|
||||||
@JsonKey(name: "geo-type") required String geoType,
|
@JsonKey(name: 'geo-type') required String geoType,
|
||||||
@JsonKey(name: "geo-name") required String geoName,
|
@JsonKey(name: 'geo-name') required String geoName,
|
||||||
}) = _UpdateGeoDataParams;
|
}) = _UpdateGeoDataParams;
|
||||||
|
|
||||||
factory UpdateGeoDataParams.fromJson(Map<String, Object?> json) =>
|
factory UpdateGeoDataParams.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -197,10 +197,10 @@ class Now with _$Now {
|
|||||||
@freezed
|
@freezed
|
||||||
class ProviderSubscriptionInfo with _$ProviderSubscriptionInfo {
|
class ProviderSubscriptionInfo with _$ProviderSubscriptionInfo {
|
||||||
const factory ProviderSubscriptionInfo({
|
const factory ProviderSubscriptionInfo({
|
||||||
@JsonKey(name: "UPLOAD") @Default(0) int upload,
|
@JsonKey(name: 'UPLOAD') @Default(0) int upload,
|
||||||
@JsonKey(name: "DOWNLOAD") @Default(0) int download,
|
@JsonKey(name: 'DOWNLOAD') @Default(0) int download,
|
||||||
@JsonKey(name: "TOTAL") @Default(0) int total,
|
@JsonKey(name: 'TOTAL') @Default(0) int total,
|
||||||
@JsonKey(name: "EXPIRE") @Default(0) int expire,
|
@JsonKey(name: 'EXPIRE') @Default(0) int expire,
|
||||||
}) = _ProviderSubscriptionInfo;
|
}) = _ProviderSubscriptionInfo;
|
||||||
|
|
||||||
factory ProviderSubscriptionInfo.fromJson(Map<String, Object?> json) =>
|
factory ProviderSubscriptionInfo.fromJson(Map<String, Object?> json) =>
|
||||||
@@ -224,11 +224,11 @@ class ExternalProvider with _$ExternalProvider {
|
|||||||
required String type,
|
required String type,
|
||||||
String? path,
|
String? path,
|
||||||
required int count,
|
required int count,
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
SubscriptionInfo? subscriptionInfo,
|
SubscriptionInfo? subscriptionInfo,
|
||||||
@Default(false) bool isUpdating,
|
@Default(false) bool isUpdating,
|
||||||
@JsonKey(name: "vehicle-type") required String vehicleType,
|
@JsonKey(name: 'vehicle-type') required String vehicleType,
|
||||||
@JsonKey(name: "update-at") required DateTime updateAt,
|
@JsonKey(name: 'update-at') required DateTime updateAt,
|
||||||
}) = _ExternalProvider;
|
}) = _ExternalProvider;
|
||||||
|
|
||||||
factory ExternalProvider.fromJson(Map<String, Object?> json) =>
|
factory ExternalProvider.fromJson(Map<String, Object?> json) =>
|
||||||
|
|||||||
@@ -26,17 +26,19 @@ mixin _$AppState {
|
|||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
List<Group> get groups => throw _privateConstructorUsedError;
|
List<Group> get groups => throw _privateConstructorUsedError;
|
||||||
int get checkIpNum => throw _privateConstructorUsedError;
|
int get checkIpNum => throw _privateConstructorUsedError;
|
||||||
Brightness? get brightness => throw _privateConstructorUsedError;
|
Brightness get brightness => throw _privateConstructorUsedError;
|
||||||
int? get runTime => throw _privateConstructorUsedError;
|
int? get runTime => throw _privateConstructorUsedError;
|
||||||
List<ExternalProvider> get providers => throw _privateConstructorUsedError;
|
List<ExternalProvider> get providers => throw _privateConstructorUsedError;
|
||||||
String? get localIp => throw _privateConstructorUsedError;
|
String? get localIp => throw _privateConstructorUsedError;
|
||||||
FixedList<Connection> get requests => throw _privateConstructorUsedError;
|
FixedList<TrackerInfo> get requests => throw _privateConstructorUsedError;
|
||||||
int get version => throw _privateConstructorUsedError;
|
int get version => throw _privateConstructorUsedError;
|
||||||
FixedList<Log> get logs => throw _privateConstructorUsedError;
|
FixedList<Log> get logs => throw _privateConstructorUsedError;
|
||||||
FixedList<Traffic> get traffics => throw _privateConstructorUsedError;
|
FixedList<Traffic> get traffics => throw _privateConstructorUsedError;
|
||||||
Traffic get totalTraffic => throw _privateConstructorUsedError;
|
Traffic get totalTraffic => throw _privateConstructorUsedError;
|
||||||
String get proxiesQuery => throw _privateConstructorUsedError;
|
|
||||||
bool get realTunEnable => throw _privateConstructorUsedError;
|
bool get realTunEnable => throw _privateConstructorUsedError;
|
||||||
|
bool get loading => throw _privateConstructorUsedError;
|
||||||
|
SystemUiOverlayStyle get systemUiOverlayStyle =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Create a copy of AppState
|
/// Create a copy of AppState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -60,17 +62,18 @@ abstract class $AppStateCopyWith<$Res> {
|
|||||||
Map<String, Map<String, int?>> delayMap,
|
Map<String, Map<String, int?>> delayMap,
|
||||||
List<Group> groups,
|
List<Group> groups,
|
||||||
int checkIpNum,
|
int checkIpNum,
|
||||||
Brightness? brightness,
|
Brightness brightness,
|
||||||
int? runTime,
|
int? runTime,
|
||||||
List<ExternalProvider> providers,
|
List<ExternalProvider> providers,
|
||||||
String? localIp,
|
String? localIp,
|
||||||
FixedList<Connection> requests,
|
FixedList<TrackerInfo> requests,
|
||||||
int version,
|
int version,
|
||||||
FixedList<Log> logs,
|
FixedList<Log> logs,
|
||||||
FixedList<Traffic> traffics,
|
FixedList<Traffic> traffics,
|
||||||
Traffic totalTraffic,
|
Traffic totalTraffic,
|
||||||
String proxiesQuery,
|
bool realTunEnable,
|
||||||
bool realTunEnable});
|
bool loading,
|
||||||
|
SystemUiOverlayStyle systemUiOverlayStyle});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -97,7 +100,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
|
|||||||
Object? delayMap = null,
|
Object? delayMap = null,
|
||||||
Object? groups = null,
|
Object? groups = null,
|
||||||
Object? checkIpNum = null,
|
Object? checkIpNum = null,
|
||||||
Object? brightness = freezed,
|
Object? brightness = null,
|
||||||
Object? runTime = freezed,
|
Object? runTime = freezed,
|
||||||
Object? providers = null,
|
Object? providers = null,
|
||||||
Object? localIp = freezed,
|
Object? localIp = freezed,
|
||||||
@@ -106,8 +109,9 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
|
|||||||
Object? logs = null,
|
Object? logs = null,
|
||||||
Object? traffics = null,
|
Object? traffics = null,
|
||||||
Object? totalTraffic = null,
|
Object? totalTraffic = null,
|
||||||
Object? proxiesQuery = null,
|
|
||||||
Object? realTunEnable = null,
|
Object? realTunEnable = null,
|
||||||
|
Object? loading = null,
|
||||||
|
Object? systemUiOverlayStyle = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
isInit: null == isInit
|
isInit: null == isInit
|
||||||
@@ -146,10 +150,10 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
|
|||||||
? _value.checkIpNum
|
? _value.checkIpNum
|
||||||
: checkIpNum // ignore: cast_nullable_to_non_nullable
|
: checkIpNum // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
brightness: freezed == brightness
|
brightness: null == brightness
|
||||||
? _value.brightness
|
? _value.brightness
|
||||||
: brightness // ignore: cast_nullable_to_non_nullable
|
: brightness // ignore: cast_nullable_to_non_nullable
|
||||||
as Brightness?,
|
as Brightness,
|
||||||
runTime: freezed == runTime
|
runTime: freezed == runTime
|
||||||
? _value.runTime
|
? _value.runTime
|
||||||
: runTime // ignore: cast_nullable_to_non_nullable
|
: runTime // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -165,7 +169,7 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
|
|||||||
requests: null == requests
|
requests: null == requests
|
||||||
? _value.requests
|
? _value.requests
|
||||||
: requests // ignore: cast_nullable_to_non_nullable
|
: requests // ignore: cast_nullable_to_non_nullable
|
||||||
as FixedList<Connection>,
|
as FixedList<TrackerInfo>,
|
||||||
version: null == version
|
version: null == version
|
||||||
? _value.version
|
? _value.version
|
||||||
: version // ignore: cast_nullable_to_non_nullable
|
: version // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -182,14 +186,18 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
|
|||||||
? _value.totalTraffic
|
? _value.totalTraffic
|
||||||
: totalTraffic // ignore: cast_nullable_to_non_nullable
|
: totalTraffic // ignore: cast_nullable_to_non_nullable
|
||||||
as Traffic,
|
as Traffic,
|
||||||
proxiesQuery: null == proxiesQuery
|
|
||||||
? _value.proxiesQuery
|
|
||||||
: proxiesQuery // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
realTunEnable: null == realTunEnable
|
realTunEnable: null == realTunEnable
|
||||||
? _value.realTunEnable
|
? _value.realTunEnable
|
||||||
: realTunEnable // ignore: cast_nullable_to_non_nullable
|
: realTunEnable // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
|
loading: null == loading
|
||||||
|
? _value.loading
|
||||||
|
: loading // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
systemUiOverlayStyle: null == systemUiOverlayStyle
|
||||||
|
? _value.systemUiOverlayStyle
|
||||||
|
: systemUiOverlayStyle // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SystemUiOverlayStyle,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,17 +220,18 @@ abstract class _$$AppStateImplCopyWith<$Res>
|
|||||||
Map<String, Map<String, int?>> delayMap,
|
Map<String, Map<String, int?>> delayMap,
|
||||||
List<Group> groups,
|
List<Group> groups,
|
||||||
int checkIpNum,
|
int checkIpNum,
|
||||||
Brightness? brightness,
|
Brightness brightness,
|
||||||
int? runTime,
|
int? runTime,
|
||||||
List<ExternalProvider> providers,
|
List<ExternalProvider> providers,
|
||||||
String? localIp,
|
String? localIp,
|
||||||
FixedList<Connection> requests,
|
FixedList<TrackerInfo> requests,
|
||||||
int version,
|
int version,
|
||||||
FixedList<Log> logs,
|
FixedList<Log> logs,
|
||||||
FixedList<Traffic> traffics,
|
FixedList<Traffic> traffics,
|
||||||
Traffic totalTraffic,
|
Traffic totalTraffic,
|
||||||
String proxiesQuery,
|
bool realTunEnable,
|
||||||
bool realTunEnable});
|
bool loading,
|
||||||
|
SystemUiOverlayStyle systemUiOverlayStyle});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -247,7 +256,7 @@ class __$$AppStateImplCopyWithImpl<$Res>
|
|||||||
Object? delayMap = null,
|
Object? delayMap = null,
|
||||||
Object? groups = null,
|
Object? groups = null,
|
||||||
Object? checkIpNum = null,
|
Object? checkIpNum = null,
|
||||||
Object? brightness = freezed,
|
Object? brightness = null,
|
||||||
Object? runTime = freezed,
|
Object? runTime = freezed,
|
||||||
Object? providers = null,
|
Object? providers = null,
|
||||||
Object? localIp = freezed,
|
Object? localIp = freezed,
|
||||||
@@ -256,8 +265,9 @@ class __$$AppStateImplCopyWithImpl<$Res>
|
|||||||
Object? logs = null,
|
Object? logs = null,
|
||||||
Object? traffics = null,
|
Object? traffics = null,
|
||||||
Object? totalTraffic = null,
|
Object? totalTraffic = null,
|
||||||
Object? proxiesQuery = null,
|
|
||||||
Object? realTunEnable = null,
|
Object? realTunEnable = null,
|
||||||
|
Object? loading = null,
|
||||||
|
Object? systemUiOverlayStyle = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$AppStateImpl(
|
return _then(_$AppStateImpl(
|
||||||
isInit: null == isInit
|
isInit: null == isInit
|
||||||
@@ -296,10 +306,10 @@ class __$$AppStateImplCopyWithImpl<$Res>
|
|||||||
? _value.checkIpNum
|
? _value.checkIpNum
|
||||||
: checkIpNum // ignore: cast_nullable_to_non_nullable
|
: checkIpNum // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
brightness: freezed == brightness
|
brightness: null == brightness
|
||||||
? _value.brightness
|
? _value.brightness
|
||||||
: brightness // ignore: cast_nullable_to_non_nullable
|
: brightness // ignore: cast_nullable_to_non_nullable
|
||||||
as Brightness?,
|
as Brightness,
|
||||||
runTime: freezed == runTime
|
runTime: freezed == runTime
|
||||||
? _value.runTime
|
? _value.runTime
|
||||||
: runTime // ignore: cast_nullable_to_non_nullable
|
: runTime // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -315,7 +325,7 @@ class __$$AppStateImplCopyWithImpl<$Res>
|
|||||||
requests: null == requests
|
requests: null == requests
|
||||||
? _value.requests
|
? _value.requests
|
||||||
: requests // ignore: cast_nullable_to_non_nullable
|
: requests // ignore: cast_nullable_to_non_nullable
|
||||||
as FixedList<Connection>,
|
as FixedList<TrackerInfo>,
|
||||||
version: null == version
|
version: null == version
|
||||||
? _value.version
|
? _value.version
|
||||||
: version // ignore: cast_nullable_to_non_nullable
|
: version // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -332,14 +342,18 @@ class __$$AppStateImplCopyWithImpl<$Res>
|
|||||||
? _value.totalTraffic
|
? _value.totalTraffic
|
||||||
: totalTraffic // ignore: cast_nullable_to_non_nullable
|
: totalTraffic // ignore: cast_nullable_to_non_nullable
|
||||||
as Traffic,
|
as Traffic,
|
||||||
proxiesQuery: null == proxiesQuery
|
|
||||||
? _value.proxiesQuery
|
|
||||||
: proxiesQuery // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
|
||||||
realTunEnable: null == realTunEnable
|
realTunEnable: null == realTunEnable
|
||||||
? _value.realTunEnable
|
? _value.realTunEnable
|
||||||
: realTunEnable // ignore: cast_nullable_to_non_nullable
|
: realTunEnable // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
|
loading: null == loading
|
||||||
|
? _value.loading
|
||||||
|
: loading // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
systemUiOverlayStyle: null == systemUiOverlayStyle
|
||||||
|
? _value.systemUiOverlayStyle
|
||||||
|
: systemUiOverlayStyle // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SystemUiOverlayStyle,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,7 +371,7 @@ class _$AppStateImpl implements _AppState {
|
|||||||
final Map<String, Map<String, int?>> delayMap = const {},
|
final Map<String, Map<String, int?>> delayMap = const {},
|
||||||
final List<Group> groups = const [],
|
final List<Group> groups = const [],
|
||||||
this.checkIpNum = 0,
|
this.checkIpNum = 0,
|
||||||
this.brightness,
|
required this.brightness,
|
||||||
this.runTime,
|
this.runTime,
|
||||||
final List<ExternalProvider> providers = const [],
|
final List<ExternalProvider> providers = const [],
|
||||||
this.localIp,
|
this.localIp,
|
||||||
@@ -366,8 +380,9 @@ class _$AppStateImpl implements _AppState {
|
|||||||
required this.logs,
|
required this.logs,
|
||||||
required this.traffics,
|
required this.traffics,
|
||||||
required this.totalTraffic,
|
required this.totalTraffic,
|
||||||
this.proxiesQuery = "",
|
this.realTunEnable = false,
|
||||||
this.realTunEnable = false})
|
this.loading = false,
|
||||||
|
required this.systemUiOverlayStyle})
|
||||||
: _packages = packages,
|
: _packages = packages,
|
||||||
_delayMap = delayMap,
|
_delayMap = delayMap,
|
||||||
_groups = groups,
|
_groups = groups,
|
||||||
@@ -418,7 +433,7 @@ class _$AppStateImpl implements _AppState {
|
|||||||
@JsonKey()
|
@JsonKey()
|
||||||
final int checkIpNum;
|
final int checkIpNum;
|
||||||
@override
|
@override
|
||||||
final Brightness? brightness;
|
final Brightness brightness;
|
||||||
@override
|
@override
|
||||||
final int? runTime;
|
final int? runTime;
|
||||||
final List<ExternalProvider> _providers;
|
final List<ExternalProvider> _providers;
|
||||||
@@ -433,7 +448,7 @@ class _$AppStateImpl implements _AppState {
|
|||||||
@override
|
@override
|
||||||
final String? localIp;
|
final String? localIp;
|
||||||
@override
|
@override
|
||||||
final FixedList<Connection> requests;
|
final FixedList<TrackerInfo> requests;
|
||||||
@override
|
@override
|
||||||
final int version;
|
final int version;
|
||||||
@override
|
@override
|
||||||
@@ -444,14 +459,16 @@ class _$AppStateImpl implements _AppState {
|
|||||||
final Traffic totalTraffic;
|
final Traffic totalTraffic;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final String proxiesQuery;
|
final bool realTunEnable;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final bool realTunEnable;
|
final bool loading;
|
||||||
|
@override
|
||||||
|
final SystemUiOverlayStyle systemUiOverlayStyle;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, proxiesQuery: $proxiesQuery, realTunEnable: $realTunEnable)';
|
return 'AppState(isInit: $isInit, backBlock: $backBlock, pageLabel: $pageLabel, packages: $packages, sortNum: $sortNum, viewSize: $viewSize, delayMap: $delayMap, groups: $groups, checkIpNum: $checkIpNum, brightness: $brightness, runTime: $runTime, providers: $providers, localIp: $localIp, requests: $requests, version: $version, logs: $logs, traffics: $traffics, totalTraffic: $totalTraffic, realTunEnable: $realTunEnable, loading: $loading, systemUiOverlayStyle: $systemUiOverlayStyle)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -486,10 +503,11 @@ class _$AppStateImpl implements _AppState {
|
|||||||
other.traffics == traffics) &&
|
other.traffics == traffics) &&
|
||||||
(identical(other.totalTraffic, totalTraffic) ||
|
(identical(other.totalTraffic, totalTraffic) ||
|
||||||
other.totalTraffic == totalTraffic) &&
|
other.totalTraffic == totalTraffic) &&
|
||||||
(identical(other.proxiesQuery, proxiesQuery) ||
|
|
||||||
other.proxiesQuery == proxiesQuery) &&
|
|
||||||
(identical(other.realTunEnable, realTunEnable) ||
|
(identical(other.realTunEnable, realTunEnable) ||
|
||||||
other.realTunEnable == realTunEnable));
|
other.realTunEnable == realTunEnable) &&
|
||||||
|
(identical(other.loading, loading) || other.loading == loading) &&
|
||||||
|
(identical(other.systemUiOverlayStyle, systemUiOverlayStyle) ||
|
||||||
|
other.systemUiOverlayStyle == systemUiOverlayStyle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -513,8 +531,9 @@ class _$AppStateImpl implements _AppState {
|
|||||||
logs,
|
logs,
|
||||||
traffics,
|
traffics,
|
||||||
totalTraffic,
|
totalTraffic,
|
||||||
proxiesQuery,
|
realTunEnable,
|
||||||
realTunEnable
|
loading,
|
||||||
|
systemUiOverlayStyle
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// Create a copy of AppState
|
/// Create a copy of AppState
|
||||||
@@ -528,26 +547,28 @@ class _$AppStateImpl implements _AppState {
|
|||||||
|
|
||||||
abstract class _AppState implements AppState {
|
abstract class _AppState implements AppState {
|
||||||
const factory _AppState(
|
const factory _AppState(
|
||||||
{final bool isInit,
|
{final bool isInit,
|
||||||
final bool backBlock,
|
final bool backBlock,
|
||||||
final PageLabel pageLabel,
|
final PageLabel pageLabel,
|
||||||
final List<Package> packages,
|
final List<Package> packages,
|
||||||
final int sortNum,
|
final int sortNum,
|
||||||
required final Size viewSize,
|
required final Size viewSize,
|
||||||
final Map<String, Map<String, int?>> delayMap,
|
final Map<String, Map<String, int?>> delayMap,
|
||||||
final List<Group> groups,
|
final List<Group> groups,
|
||||||
final int checkIpNum,
|
final int checkIpNum,
|
||||||
final Brightness? brightness,
|
required final Brightness brightness,
|
||||||
final int? runTime,
|
final int? runTime,
|
||||||
final List<ExternalProvider> providers,
|
final List<ExternalProvider> providers,
|
||||||
final String? localIp,
|
final String? localIp,
|
||||||
required final FixedList<Connection> requests,
|
required final FixedList<TrackerInfo> requests,
|
||||||
required final int version,
|
required final int version,
|
||||||
required final FixedList<Log> logs,
|
required final FixedList<Log> logs,
|
||||||
required final FixedList<Traffic> traffics,
|
required final FixedList<Traffic> traffics,
|
||||||
required final Traffic totalTraffic,
|
required final Traffic totalTraffic,
|
||||||
final String proxiesQuery,
|
final bool realTunEnable,
|
||||||
final bool realTunEnable}) = _$AppStateImpl;
|
final bool loading,
|
||||||
|
required final SystemUiOverlayStyle systemUiOverlayStyle}) =
|
||||||
|
_$AppStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get isInit;
|
bool get isInit;
|
||||||
@@ -568,7 +589,7 @@ abstract class _AppState implements AppState {
|
|||||||
@override
|
@override
|
||||||
int get checkIpNum;
|
int get checkIpNum;
|
||||||
@override
|
@override
|
||||||
Brightness? get brightness;
|
Brightness get brightness;
|
||||||
@override
|
@override
|
||||||
int? get runTime;
|
int? get runTime;
|
||||||
@override
|
@override
|
||||||
@@ -576,7 +597,7 @@ abstract class _AppState implements AppState {
|
|||||||
@override
|
@override
|
||||||
String? get localIp;
|
String? get localIp;
|
||||||
@override
|
@override
|
||||||
FixedList<Connection> get requests;
|
FixedList<TrackerInfo> get requests;
|
||||||
@override
|
@override
|
||||||
int get version;
|
int get version;
|
||||||
@override
|
@override
|
||||||
@@ -586,9 +607,11 @@ abstract class _AppState implements AppState {
|
|||||||
@override
|
@override
|
||||||
Traffic get totalTraffic;
|
Traffic get totalTraffic;
|
||||||
@override
|
@override
|
||||||
String get proxiesQuery;
|
|
||||||
@override
|
|
||||||
bool get realTunEnable;
|
bool get realTunEnable;
|
||||||
|
@override
|
||||||
|
bool get loading;
|
||||||
|
@override
|
||||||
|
SystemUiOverlayStyle get systemUiOverlayStyle;
|
||||||
|
|
||||||
/// Create a copy of AppState
|
/// Create a copy of AppState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -138,7 +138,7 @@ _$TunImpl _$$TunImplFromJson(Map<String, dynamic> json) => _$TunImpl(
|
|||||||
dnsHijack: (json['dns-hijack'] as List<dynamic>?)
|
dnsHijack: (json['dns-hijack'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["any:53"],
|
const ['any:53'],
|
||||||
routeAddress: (json['route-address'] as List<dynamic>?)
|
routeAddress: (json['route-address'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
@@ -163,19 +163,19 @@ const _$TunStackEnumMap = {
|
|||||||
_$FallbackFilterImpl _$$FallbackFilterImplFromJson(Map<String, dynamic> json) =>
|
_$FallbackFilterImpl _$$FallbackFilterImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$FallbackFilterImpl(
|
_$FallbackFilterImpl(
|
||||||
geoip: json['geoip'] as bool? ?? true,
|
geoip: json['geoip'] as bool? ?? true,
|
||||||
geoipCode: json['geoip-code'] as String? ?? "CN",
|
geoipCode: json['geoip-code'] as String? ?? 'CN',
|
||||||
geosite: (json['geosite'] as List<dynamic>?)
|
geosite: (json['geosite'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["gfw"],
|
const ['gfw'],
|
||||||
ipcidr: (json['ipcidr'] as List<dynamic>?)
|
ipcidr: (json['ipcidr'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["240.0.0.0/4"],
|
const ['240.0.0.0/4'],
|
||||||
domain: (json['domain'] as List<dynamic>?)
|
domain: (json['domain'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["+.google.com", "+.facebook.com", "+.youtube.com"],
|
const ['+.google.com', '+.facebook.com', '+.youtube.com'],
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$FallbackFilterImplToJson(
|
Map<String, dynamic> _$$FallbackFilterImplToJson(
|
||||||
@@ -190,7 +190,7 @@ Map<String, dynamic> _$$FallbackFilterImplToJson(
|
|||||||
|
|
||||||
_$DnsImpl _$$DnsImplFromJson(Map<String, dynamic> json) => _$DnsImpl(
|
_$DnsImpl _$$DnsImplFromJson(Map<String, dynamic> json) => _$DnsImpl(
|
||||||
enable: json['enable'] as bool? ?? true,
|
enable: json['enable'] as bool? ?? true,
|
||||||
listen: json['listen'] as String? ?? "0.0.0.0:1053",
|
listen: json['listen'] as String? ?? '0.0.0.0:1053',
|
||||||
preferH3: json['prefer-h3'] as bool? ?? false,
|
preferH3: json['prefer-h3'] as bool? ?? false,
|
||||||
useHosts: json['use-hosts'] as bool? ?? true,
|
useHosts: json['use-hosts'] as bool? ?? true,
|
||||||
useSystemHosts: json['use-system-hosts'] as bool? ?? true,
|
useSystemHosts: json['use-system-hosts'] as bool? ?? true,
|
||||||
@@ -199,39 +199,39 @@ _$DnsImpl _$$DnsImplFromJson(Map<String, dynamic> json) => _$DnsImpl(
|
|||||||
defaultNameserver: (json['default-nameserver'] as List<dynamic>?)
|
defaultNameserver: (json['default-nameserver'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["223.5.5.5"],
|
const ['223.5.5.5'],
|
||||||
enhancedMode:
|
enhancedMode:
|
||||||
$enumDecodeNullable(_$DnsModeEnumMap, json['enhanced-mode']) ??
|
$enumDecodeNullable(_$DnsModeEnumMap, json['enhanced-mode']) ??
|
||||||
DnsMode.fakeIp,
|
DnsMode.fakeIp,
|
||||||
fakeIpRange: json['fake-ip-range'] as String? ?? "198.18.0.1/16",
|
fakeIpRange: json['fake-ip-range'] as String? ?? '198.18.0.1/16',
|
||||||
fakeIpFilter: (json['fake-ip-filter'] as List<dynamic>?)
|
fakeIpFilter: (json['fake-ip-filter'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["*.lan", "localhost.ptlogin2.qq.com"],
|
const ['*.lan', 'localhost.ptlogin2.qq.com'],
|
||||||
nameserverPolicy:
|
nameserverPolicy:
|
||||||
(json['nameserver-policy'] as Map<String, dynamic>?)?.map(
|
(json['nameserver-policy'] as Map<String, dynamic>?)?.map(
|
||||||
(k, e) => MapEntry(k, e as String),
|
(k, e) => MapEntry(k, e as String),
|
||||||
) ??
|
) ??
|
||||||
const {
|
const {
|
||||||
"www.baidu.com": "114.114.114.114",
|
'www.baidu.com': '114.114.114.114',
|
||||||
"+.internal.crop.com": "10.0.0.1",
|
'+.internal.crop.com': '10.0.0.1',
|
||||||
"geosite:cn": "https://doh.pub/dns-query"
|
'geosite:cn': 'https://doh.pub/dns-query'
|
||||||
},
|
},
|
||||||
nameserver: (json['nameserver'] as List<dynamic>?)
|
nameserver: (json['nameserver'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const [
|
const [
|
||||||
"https://doh.pub/dns-query",
|
'https://doh.pub/dns-query',
|
||||||
"https://dns.alidns.com/dns-query"
|
'https://dns.alidns.com/dns-query'
|
||||||
],
|
],
|
||||||
fallback: (json['fallback'] as List<dynamic>?)
|
fallback: (json['fallback'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["tls://8.8.4.4", "tls://1.1.1.1"],
|
const ['tls://8.8.4.4', 'tls://1.1.1.1'],
|
||||||
proxyServerNameserver: (json['proxy-server-nameserver'] as List<dynamic>?)
|
proxyServerNameserver: (json['proxy-server-nameserver'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const ["https://doh.pub/dns-query"],
|
const ['https://doh.pub/dns-query'],
|
||||||
fallbackFilter: json['fallback-filter'] == null
|
fallbackFilter: json['fallback-filter'] == null
|
||||||
? const FallbackFilter()
|
? const FallbackFilter()
|
||||||
: FallbackFilter.fromJson(
|
: FallbackFilter.fromJson(
|
||||||
@@ -267,13 +267,13 @@ const _$DnsModeEnumMap = {
|
|||||||
_$GeoXUrlImpl _$$GeoXUrlImplFromJson(Map<String, dynamic> json) =>
|
_$GeoXUrlImpl _$$GeoXUrlImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$GeoXUrlImpl(
|
_$GeoXUrlImpl(
|
||||||
mmdb: json['mmdb'] as String? ??
|
mmdb: json['mmdb'] as String? ??
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb',
|
||||||
asn: json['asn'] as String? ??
|
asn: json['asn'] as String? ??
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb',
|
||||||
geoip: json['geoip'] as String? ??
|
geoip: json['geoip'] as String? ??
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat',
|
||||||
geosite: json['geosite'] as String? ??
|
geosite: json['geosite'] as String? ??
|
||||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat",
|
'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat',
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$GeoXUrlImplToJson(_$GeoXUrlImpl instance) =>
|
Map<String, dynamic> _$$GeoXUrlImplToJson(_$GeoXUrlImpl instance) =>
|
||||||
@@ -418,7 +418,6 @@ const _$LogLevelEnumMap = {
|
|||||||
LogLevel.warning: 'warning',
|
LogLevel.warning: 'warning',
|
||||||
LogLevel.error: 'error',
|
LogLevel.error: 'error',
|
||||||
LogLevel.silent: 'silent',
|
LogLevel.silent: 'silent',
|
||||||
LogLevel.app: 'app',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const _$FindProcessModeEnumMap = {
|
const _$FindProcessModeEnumMap = {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -26,15 +26,29 @@ Map<String, dynamic> _$$PackageImplToJson(_$PackageImpl instance) =>
|
|||||||
|
|
||||||
_$MetadataImpl _$$MetadataImplFromJson(Map<String, dynamic> json) =>
|
_$MetadataImpl _$$MetadataImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$MetadataImpl(
|
_$MetadataImpl(
|
||||||
uid: (json['uid'] as num).toInt(),
|
uid: (json['uid'] as num?)?.toInt() ?? 0,
|
||||||
network: json['network'] as String,
|
network: json['network'] as String? ?? '',
|
||||||
sourceIP: json['sourceIP'] as String,
|
sourceIP: json['sourceIP'] as String? ?? '',
|
||||||
sourcePort: json['sourcePort'] as String,
|
sourcePort: json['sourcePort'] as String? ?? '',
|
||||||
destinationIP: json['destinationIP'] as String,
|
destinationIP: json['destinationIP'] as String? ?? '',
|
||||||
destinationPort: json['destinationPort'] as String,
|
destinationPort: json['destinationPort'] as String? ?? '',
|
||||||
host: json['host'] as String,
|
host: json['host'] as String? ?? '',
|
||||||
process: json['process'] as String,
|
dnsMode: $enumDecodeNullable(_$DnsModeEnumMap, json['dnsMode']),
|
||||||
remoteDestination: json['remoteDestination'] as String,
|
process: json['process'] as String? ?? '',
|
||||||
|
processPath: json['processPath'] as String? ?? '',
|
||||||
|
remoteDestination: json['remoteDestination'] as String? ?? '',
|
||||||
|
sourceGeoIP: (json['sourceGeoIP'] as List<dynamic>?)
|
||||||
|
?.map((e) => e as String)
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
|
destinationGeoIP: (json['destinationGeoIP'] as List<dynamic>?)
|
||||||
|
?.map((e) => e as String)
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
|
destinationIPASN: json['destinationIPASN'] as String? ?? '',
|
||||||
|
sourceIPASN: json['sourceIPASN'] as String? ?? '',
|
||||||
|
specialRules: json['specialRules'] as String? ?? '',
|
||||||
|
specialProxy: json['specialProxy'] as String? ?? '',
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$MetadataImplToJson(_$MetadataImpl instance) =>
|
Map<String, dynamic> _$$MetadataImplToJson(_$MetadataImpl instance) =>
|
||||||
@@ -46,22 +60,41 @@ Map<String, dynamic> _$$MetadataImplToJson(_$MetadataImpl instance) =>
|
|||||||
'destinationIP': instance.destinationIP,
|
'destinationIP': instance.destinationIP,
|
||||||
'destinationPort': instance.destinationPort,
|
'destinationPort': instance.destinationPort,
|
||||||
'host': instance.host,
|
'host': instance.host,
|
||||||
|
'dnsMode': _$DnsModeEnumMap[instance.dnsMode],
|
||||||
'process': instance.process,
|
'process': instance.process,
|
||||||
|
'processPath': instance.processPath,
|
||||||
'remoteDestination': instance.remoteDestination,
|
'remoteDestination': instance.remoteDestination,
|
||||||
|
'sourceGeoIP': instance.sourceGeoIP,
|
||||||
|
'destinationGeoIP': instance.destinationGeoIP,
|
||||||
|
'destinationIPASN': instance.destinationIPASN,
|
||||||
|
'sourceIPASN': instance.sourceIPASN,
|
||||||
|
'specialRules': instance.specialRules,
|
||||||
|
'specialProxy': instance.specialProxy,
|
||||||
};
|
};
|
||||||
|
|
||||||
_$ConnectionImpl _$$ConnectionImplFromJson(Map<String, dynamic> json) =>
|
const _$DnsModeEnumMap = {
|
||||||
_$ConnectionImpl(
|
DnsMode.normal: 'normal',
|
||||||
|
DnsMode.fakeIp: 'fake-ip',
|
||||||
|
DnsMode.redirHost: 'redir-host',
|
||||||
|
DnsMode.hosts: 'hosts',
|
||||||
|
};
|
||||||
|
|
||||||
|
_$TrackerInfoImpl _$$TrackerInfoImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TrackerInfoImpl(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
upload: json['upload'] as num?,
|
upload: (json['upload'] as num?)?.toInt() ?? 0,
|
||||||
download: json['download'] as num?,
|
download: (json['download'] as num?)?.toInt() ?? 0,
|
||||||
start: DateTime.parse(json['start'] as String),
|
start: DateTime.parse(json['start'] as String),
|
||||||
metadata: Metadata.fromJson(json['metadata'] as Map<String, dynamic>),
|
metadata: Metadata.fromJson(json['metadata'] as Map<String, dynamic>),
|
||||||
chains:
|
chains:
|
||||||
(json['chains'] as List<dynamic>).map((e) => e as String).toList(),
|
(json['chains'] as List<dynamic>).map((e) => e as String).toList(),
|
||||||
|
rule: json['rule'] as String,
|
||||||
|
rulePayload: json['rulePayload'] as String,
|
||||||
|
downloadSpeed: (json['downloadSpeed'] as num?)?.toInt(),
|
||||||
|
uploadSpeed: (json['uploadSpeed'] as num?)?.toInt(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$ConnectionImplToJson(_$ConnectionImpl instance) =>
|
Map<String, dynamic> _$$TrackerInfoImplToJson(_$TrackerInfoImpl instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'upload': instance.upload,
|
'upload': instance.upload,
|
||||||
@@ -69,12 +102,16 @@ Map<String, dynamic> _$$ConnectionImplToJson(_$ConnectionImpl instance) =>
|
|||||||
'start': instance.start.toIso8601String(),
|
'start': instance.start.toIso8601String(),
|
||||||
'metadata': instance.metadata,
|
'metadata': instance.metadata,
|
||||||
'chains': instance.chains,
|
'chains': instance.chains,
|
||||||
|
'rule': instance.rule,
|
||||||
|
'rulePayload': instance.rulePayload,
|
||||||
|
'downloadSpeed': instance.downloadSpeed,
|
||||||
|
'uploadSpeed': instance.uploadSpeed,
|
||||||
};
|
};
|
||||||
|
|
||||||
_$LogImpl _$$LogImplFromJson(Map<String, dynamic> json) => _$LogImpl(
|
_$LogImpl _$$LogImplFromJson(Map<String, dynamic> json) => _$LogImpl(
|
||||||
logLevel: $enumDecodeNullable(_$LogLevelEnumMap, json['LogLevel']) ??
|
logLevel: $enumDecodeNullable(_$LogLevelEnumMap, json['LogLevel']) ??
|
||||||
LogLevel.app,
|
LogLevel.info,
|
||||||
payload: json['Payload'] as String? ?? "",
|
payload: json['Payload'] as String? ?? '',
|
||||||
dateTime: _logDateTime(json['dateTime']),
|
dateTime: _logDateTime(json['dateTime']),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -90,7 +127,6 @@ const _$LogLevelEnumMap = {
|
|||||||
LogLevel.warning: 'warning',
|
LogLevel.warning: 'warning',
|
||||||
LogLevel.error: 'error',
|
LogLevel.error: 'error',
|
||||||
LogLevel.silent: 'silent',
|
LogLevel.silent: 'silent',
|
||||||
LogLevel.app: 'app',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_$DAVImpl _$$DAVImplFromJson(Map<String, dynamic> json) => _$DAVImpl(
|
_$DAVImpl _$$DAVImplFromJson(Map<String, dynamic> json) => _$DAVImpl(
|
||||||
@@ -109,8 +145,8 @@ Map<String, dynamic> _$$DAVImplToJson(_$DAVImpl instance) => <String, dynamic>{
|
|||||||
|
|
||||||
_$VersionInfoImpl _$$VersionInfoImplFromJson(Map<String, dynamic> json) =>
|
_$VersionInfoImpl _$$VersionInfoImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$VersionInfoImpl(
|
_$VersionInfoImpl(
|
||||||
clashName: json['clashName'] as String? ?? "",
|
clashName: json['clashName'] as String? ?? '',
|
||||||
version: json['version'] as String? ?? "",
|
version: json['version'] as String? ?? '',
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$VersionInfoImplToJson(_$VersionInfoImpl instance) =>
|
Map<String, dynamic> _$$VersionInfoImplToJson(_$VersionInfoImpl instance) =>
|
||||||
@@ -141,7 +177,7 @@ _$GroupImpl _$$GroupImplFromJson(Map<String, dynamic> json) => _$GroupImpl(
|
|||||||
now: json['now'] as String?,
|
now: json['now'] as String?,
|
||||||
hidden: json['hidden'] as bool?,
|
hidden: json['hidden'] as bool?,
|
||||||
testUrl: json['testUrl'] as String?,
|
testUrl: json['testUrl'] as String?,
|
||||||
icon: json['icon'] as String? ?? "",
|
icon: json['icon'] as String? ?? '',
|
||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1824,8 +1824,8 @@ TextScale _$TextScaleFromJson(Map<String, dynamic> json) {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$TextScale {
|
mixin _$TextScale {
|
||||||
dynamic get enable => throw _privateConstructorUsedError;
|
bool get enable => throw _privateConstructorUsedError;
|
||||||
dynamic get scale => throw _privateConstructorUsedError;
|
double get scale => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this TextScale to a JSON map.
|
/// Serializes this TextScale to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@@ -1842,7 +1842,7 @@ abstract class $TextScaleCopyWith<$Res> {
|
|||||||
factory $TextScaleCopyWith(TextScale value, $Res Function(TextScale) then) =
|
factory $TextScaleCopyWith(TextScale value, $Res Function(TextScale) then) =
|
||||||
_$TextScaleCopyWithImpl<$Res, TextScale>;
|
_$TextScaleCopyWithImpl<$Res, TextScale>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({dynamic enable, dynamic scale});
|
$Res call({bool enable, double scale});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1860,18 +1860,18 @@ class _$TextScaleCopyWithImpl<$Res, $Val extends TextScale>
|
|||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? enable = freezed,
|
Object? enable = null,
|
||||||
Object? scale = freezed,
|
Object? scale = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
enable: freezed == enable
|
enable: null == enable
|
||||||
? _value.enable
|
? _value.enable
|
||||||
: enable // ignore: cast_nullable_to_non_nullable
|
: enable // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic,
|
as bool,
|
||||||
scale: freezed == scale
|
scale: null == scale
|
||||||
? _value.scale
|
? _value.scale
|
||||||
: scale // ignore: cast_nullable_to_non_nullable
|
: scale // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic,
|
as double,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1884,7 +1884,7 @@ abstract class _$$TextScaleImplCopyWith<$Res>
|
|||||||
__$$TextScaleImplCopyWithImpl<$Res>;
|
__$$TextScaleImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({dynamic enable, dynamic scale});
|
$Res call({bool enable, double scale});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1900,12 +1900,18 @@ class __$$TextScaleImplCopyWithImpl<$Res>
|
|||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? enable = freezed,
|
Object? enable = null,
|
||||||
Object? scale = freezed,
|
Object? scale = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$TextScaleImpl(
|
return _then(_$TextScaleImpl(
|
||||||
enable: freezed == enable ? _value.enable! : enable,
|
enable: null == enable
|
||||||
scale: freezed == scale ? _value.scale! : scale,
|
? _value.enable
|
||||||
|
: enable // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
scale: null == scale
|
||||||
|
? _value.scale
|
||||||
|
: scale // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1920,10 +1926,10 @@ class _$TextScaleImpl implements _TextScale {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final dynamic enable;
|
final bool enable;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final dynamic scale;
|
final double scale;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@@ -1935,16 +1941,13 @@ class _$TextScaleImpl implements _TextScale {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$TextScaleImpl &&
|
other is _$TextScaleImpl &&
|
||||||
const DeepCollectionEquality().equals(other.enable, enable) &&
|
(identical(other.enable, enable) || other.enable == enable) &&
|
||||||
const DeepCollectionEquality().equals(other.scale, scale));
|
(identical(other.scale, scale) || other.scale == scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(runtimeType, enable, scale);
|
||||||
runtimeType,
|
|
||||||
const DeepCollectionEquality().hash(enable),
|
|
||||||
const DeepCollectionEquality().hash(scale));
|
|
||||||
|
|
||||||
/// Create a copy of TextScale
|
/// Create a copy of TextScale
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -1963,16 +1966,16 @@ class _$TextScaleImpl implements _TextScale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class _TextScale implements TextScale {
|
abstract class _TextScale implements TextScale {
|
||||||
const factory _TextScale({final dynamic enable, final dynamic scale}) =
|
const factory _TextScale({final bool enable, final double scale}) =
|
||||||
_$TextScaleImpl;
|
_$TextScaleImpl;
|
||||||
|
|
||||||
factory _TextScale.fromJson(Map<String, dynamic> json) =
|
factory _TextScale.fromJson(Map<String, dynamic> json) =
|
||||||
_$TextScaleImpl.fromJson;
|
_$TextScaleImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
dynamic get enable;
|
bool get enable;
|
||||||
@override
|
@override
|
||||||
dynamic get scale;
|
double get scale;
|
||||||
|
|
||||||
/// Create a copy of TextScale
|
/// Create a copy of TextScale
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
|||||||
@@ -238,8 +238,8 @@ const _$ProxyCardTypeEnumMap = {
|
|||||||
|
|
||||||
_$TextScaleImpl _$$TextScaleImplFromJson(Map<String, dynamic> json) =>
|
_$TextScaleImpl _$$TextScaleImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$TextScaleImpl(
|
_$TextScaleImpl(
|
||||||
enable: json['enable'] ?? false,
|
enable: json['enable'] as bool? ?? false,
|
||||||
scale: json['scale'] ?? 1.0,
|
scale: (json['scale'] as num?)?.toDouble() ?? 1.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$TextScaleImplToJson(_$TextScaleImpl instance) =>
|
Map<String, dynamic> _$$TextScaleImplToJson(_$TextScaleImpl instance) =>
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ SetupParams _$SetupParamsFromJson(Map<String, dynamic> json) {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SetupParams {
|
mixin _$SetupParams {
|
||||||
@JsonKey(name: "config")
|
@JsonKey(name: 'config')
|
||||||
Map<String, dynamic> get config => throw _privateConstructorUsedError;
|
Map<String, dynamic> get config => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "selected-map")
|
@JsonKey(name: 'selected-map')
|
||||||
Map<String, String> get selectedMap => throw _privateConstructorUsedError;
|
Map<String, String> get selectedMap => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "test-url")
|
@JsonKey(name: 'test-url')
|
||||||
String get testUrl => throw _privateConstructorUsedError;
|
String get testUrl => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this SetupParams to a JSON map.
|
/// Serializes this SetupParams to a JSON map.
|
||||||
@@ -44,9 +44,9 @@ abstract class $SetupParamsCopyWith<$Res> {
|
|||||||
_$SetupParamsCopyWithImpl<$Res, SetupParams>;
|
_$SetupParamsCopyWithImpl<$Res, SetupParams>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "config") Map<String, dynamic> config,
|
{@JsonKey(name: 'config') Map<String, dynamic> config,
|
||||||
@JsonKey(name: "selected-map") Map<String, String> selectedMap,
|
@JsonKey(name: 'selected-map') Map<String, String> selectedMap,
|
||||||
@JsonKey(name: "test-url") String testUrl});
|
@JsonKey(name: 'test-url') String testUrl});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -94,9 +94,9 @@ abstract class _$$SetupParamsImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "config") Map<String, dynamic> config,
|
{@JsonKey(name: 'config') Map<String, dynamic> config,
|
||||||
@JsonKey(name: "selected-map") Map<String, String> selectedMap,
|
@JsonKey(name: 'selected-map') Map<String, String> selectedMap,
|
||||||
@JsonKey(name: "test-url") String testUrl});
|
@JsonKey(name: 'test-url') String testUrl});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -137,10 +137,10 @@ class __$$SetupParamsImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$SetupParamsImpl implements _SetupParams {
|
class _$SetupParamsImpl implements _SetupParams {
|
||||||
const _$SetupParamsImpl(
|
const _$SetupParamsImpl(
|
||||||
{@JsonKey(name: "config") required final Map<String, dynamic> config,
|
{@JsonKey(name: 'config') required final Map<String, dynamic> config,
|
||||||
@JsonKey(name: "selected-map")
|
@JsonKey(name: 'selected-map')
|
||||||
required final Map<String, String> selectedMap,
|
required final Map<String, String> selectedMap,
|
||||||
@JsonKey(name: "test-url") required this.testUrl})
|
@JsonKey(name: 'test-url') required this.testUrl})
|
||||||
: _config = config,
|
: _config = config,
|
||||||
_selectedMap = selectedMap;
|
_selectedMap = selectedMap;
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ class _$SetupParamsImpl implements _SetupParams {
|
|||||||
|
|
||||||
final Map<String, dynamic> _config;
|
final Map<String, dynamic> _config;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "config")
|
@JsonKey(name: 'config')
|
||||||
Map<String, dynamic> get config {
|
Map<String, dynamic> get config {
|
||||||
if (_config is EqualUnmodifiableMapView) return _config;
|
if (_config is EqualUnmodifiableMapView) return _config;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
@@ -158,7 +158,7 @@ class _$SetupParamsImpl implements _SetupParams {
|
|||||||
|
|
||||||
final Map<String, String> _selectedMap;
|
final Map<String, String> _selectedMap;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "selected-map")
|
@JsonKey(name: 'selected-map')
|
||||||
Map<String, String> get selectedMap {
|
Map<String, String> get selectedMap {
|
||||||
if (_selectedMap is EqualUnmodifiableMapView) return _selectedMap;
|
if (_selectedMap is EqualUnmodifiableMapView) return _selectedMap;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
@@ -166,7 +166,7 @@ class _$SetupParamsImpl implements _SetupParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "test-url")
|
@JsonKey(name: 'test-url')
|
||||||
final String testUrl;
|
final String testUrl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -211,23 +211,23 @@ class _$SetupParamsImpl implements _SetupParams {
|
|||||||
|
|
||||||
abstract class _SetupParams implements SetupParams {
|
abstract class _SetupParams implements SetupParams {
|
||||||
const factory _SetupParams(
|
const factory _SetupParams(
|
||||||
{@JsonKey(name: "config") required final Map<String, dynamic> config,
|
{@JsonKey(name: 'config') required final Map<String, dynamic> config,
|
||||||
@JsonKey(name: "selected-map")
|
@JsonKey(name: 'selected-map')
|
||||||
required final Map<String, String> selectedMap,
|
required final Map<String, String> selectedMap,
|
||||||
@JsonKey(name: "test-url") required final String testUrl}) =
|
@JsonKey(name: 'test-url') required final String testUrl}) =
|
||||||
_$SetupParamsImpl;
|
_$SetupParamsImpl;
|
||||||
|
|
||||||
factory _SetupParams.fromJson(Map<String, dynamic> json) =
|
factory _SetupParams.fromJson(Map<String, dynamic> json) =
|
||||||
_$SetupParamsImpl.fromJson;
|
_$SetupParamsImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "config")
|
@JsonKey(name: 'config')
|
||||||
Map<String, dynamic> get config;
|
Map<String, dynamic> get config;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "selected-map")
|
@JsonKey(name: 'selected-map')
|
||||||
Map<String, String> get selectedMap;
|
Map<String, String> get selectedMap;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "test-url")
|
@JsonKey(name: 'test-url')
|
||||||
String get testUrl;
|
String get testUrl;
|
||||||
|
|
||||||
/// Create a copy of SetupParams
|
/// Create a copy of SetupParams
|
||||||
@@ -637,13 +637,13 @@ CoreState _$CoreStateFromJson(Map<String, dynamic> json) {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$CoreState {
|
mixin _$CoreState {
|
||||||
@JsonKey(name: "vpn-props")
|
@JsonKey(name: 'vpn-props')
|
||||||
VpnProps get vpnProps => throw _privateConstructorUsedError;
|
VpnProps get vpnProps => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "only-statistics-proxy")
|
@JsonKey(name: 'only-statistics-proxy')
|
||||||
bool get onlyStatisticsProxy => throw _privateConstructorUsedError;
|
bool get onlyStatisticsProxy => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "current-profile-name")
|
@JsonKey(name: 'current-profile-name')
|
||||||
String get currentProfileName => throw _privateConstructorUsedError;
|
String get currentProfileName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "bypass-domain")
|
@JsonKey(name: 'bypass-domain')
|
||||||
List<String> get bypassDomain => throw _privateConstructorUsedError;
|
List<String> get bypassDomain => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this CoreState to a JSON map.
|
/// Serializes this CoreState to a JSON map.
|
||||||
@@ -662,10 +662,10 @@ abstract class $CoreStateCopyWith<$Res> {
|
|||||||
_$CoreStateCopyWithImpl<$Res, CoreState>;
|
_$CoreStateCopyWithImpl<$Res, CoreState>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "vpn-props") VpnProps vpnProps,
|
{@JsonKey(name: 'vpn-props') VpnProps vpnProps,
|
||||||
@JsonKey(name: "only-statistics-proxy") bool onlyStatisticsProxy,
|
@JsonKey(name: 'only-statistics-proxy') bool onlyStatisticsProxy,
|
||||||
@JsonKey(name: "current-profile-name") String currentProfileName,
|
@JsonKey(name: 'current-profile-name') String currentProfileName,
|
||||||
@JsonKey(name: "bypass-domain") List<String> bypassDomain});
|
@JsonKey(name: 'bypass-domain') List<String> bypassDomain});
|
||||||
|
|
||||||
$VpnPropsCopyWith<$Res> get vpnProps;
|
$VpnPropsCopyWith<$Res> get vpnProps;
|
||||||
}
|
}
|
||||||
@@ -730,10 +730,10 @@ abstract class _$$CoreStateImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "vpn-props") VpnProps vpnProps,
|
{@JsonKey(name: 'vpn-props') VpnProps vpnProps,
|
||||||
@JsonKey(name: "only-statistics-proxy") bool onlyStatisticsProxy,
|
@JsonKey(name: 'only-statistics-proxy') bool onlyStatisticsProxy,
|
||||||
@JsonKey(name: "current-profile-name") String currentProfileName,
|
@JsonKey(name: 'current-profile-name') String currentProfileName,
|
||||||
@JsonKey(name: "bypass-domain") List<String> bypassDomain});
|
@JsonKey(name: 'bypass-domain') List<String> bypassDomain});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$VpnPropsCopyWith<$Res> get vpnProps;
|
$VpnPropsCopyWith<$Res> get vpnProps;
|
||||||
@@ -782,10 +782,10 @@ class __$$CoreStateImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$CoreStateImpl implements _CoreState {
|
class _$CoreStateImpl implements _CoreState {
|
||||||
const _$CoreStateImpl(
|
const _$CoreStateImpl(
|
||||||
{@JsonKey(name: "vpn-props") required this.vpnProps,
|
{@JsonKey(name: 'vpn-props') required this.vpnProps,
|
||||||
@JsonKey(name: "only-statistics-proxy") required this.onlyStatisticsProxy,
|
@JsonKey(name: 'only-statistics-proxy') required this.onlyStatisticsProxy,
|
||||||
@JsonKey(name: "current-profile-name") required this.currentProfileName,
|
@JsonKey(name: 'current-profile-name') required this.currentProfileName,
|
||||||
@JsonKey(name: "bypass-domain")
|
@JsonKey(name: 'bypass-domain')
|
||||||
final List<String> bypassDomain = const []})
|
final List<String> bypassDomain = const []})
|
||||||
: _bypassDomain = bypassDomain;
|
: _bypassDomain = bypassDomain;
|
||||||
|
|
||||||
@@ -793,17 +793,17 @@ class _$CoreStateImpl implements _CoreState {
|
|||||||
_$$CoreStateImplFromJson(json);
|
_$$CoreStateImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "vpn-props")
|
@JsonKey(name: 'vpn-props')
|
||||||
final VpnProps vpnProps;
|
final VpnProps vpnProps;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "only-statistics-proxy")
|
@JsonKey(name: 'only-statistics-proxy')
|
||||||
final bool onlyStatisticsProxy;
|
final bool onlyStatisticsProxy;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "current-profile-name")
|
@JsonKey(name: 'current-profile-name')
|
||||||
final String currentProfileName;
|
final String currentProfileName;
|
||||||
final List<String> _bypassDomain;
|
final List<String> _bypassDomain;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "bypass-domain")
|
@JsonKey(name: 'bypass-domain')
|
||||||
List<String> get bypassDomain {
|
List<String> get bypassDomain {
|
||||||
if (_bypassDomain is EqualUnmodifiableListView) return _bypassDomain;
|
if (_bypassDomain is EqualUnmodifiableListView) return _bypassDomain;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
@@ -853,28 +853,28 @@ class _$CoreStateImpl implements _CoreState {
|
|||||||
|
|
||||||
abstract class _CoreState implements CoreState {
|
abstract class _CoreState implements CoreState {
|
||||||
const factory _CoreState(
|
const factory _CoreState(
|
||||||
{@JsonKey(name: "vpn-props") required final VpnProps vpnProps,
|
{@JsonKey(name: 'vpn-props') required final VpnProps vpnProps,
|
||||||
@JsonKey(name: "only-statistics-proxy")
|
@JsonKey(name: 'only-statistics-proxy')
|
||||||
required final bool onlyStatisticsProxy,
|
required final bool onlyStatisticsProxy,
|
||||||
@JsonKey(name: "current-profile-name")
|
@JsonKey(name: 'current-profile-name')
|
||||||
required final String currentProfileName,
|
required final String currentProfileName,
|
||||||
@JsonKey(name: "bypass-domain") final List<String> bypassDomain}) =
|
@JsonKey(name: 'bypass-domain') final List<String> bypassDomain}) =
|
||||||
_$CoreStateImpl;
|
_$CoreStateImpl;
|
||||||
|
|
||||||
factory _CoreState.fromJson(Map<String, dynamic> json) =
|
factory _CoreState.fromJson(Map<String, dynamic> json) =
|
||||||
_$CoreStateImpl.fromJson;
|
_$CoreStateImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "vpn-props")
|
@JsonKey(name: 'vpn-props')
|
||||||
VpnProps get vpnProps;
|
VpnProps get vpnProps;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "only-statistics-proxy")
|
@JsonKey(name: 'only-statistics-proxy')
|
||||||
bool get onlyStatisticsProxy;
|
bool get onlyStatisticsProxy;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "current-profile-name")
|
@JsonKey(name: 'current-profile-name')
|
||||||
String get currentProfileName;
|
String get currentProfileName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "bypass-domain")
|
@JsonKey(name: 'bypass-domain')
|
||||||
List<String> get bypassDomain;
|
List<String> get bypassDomain;
|
||||||
|
|
||||||
/// Create a copy of CoreState
|
/// Create a copy of CoreState
|
||||||
@@ -1278,7 +1278,7 @@ InitParams _$InitParamsFromJson(Map<String, dynamic> json) {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$InitParams {
|
mixin _$InitParams {
|
||||||
@JsonKey(name: "home-dir")
|
@JsonKey(name: 'home-dir')
|
||||||
String get homeDir => throw _privateConstructorUsedError;
|
String get homeDir => throw _privateConstructorUsedError;
|
||||||
int get version => throw _privateConstructorUsedError;
|
int get version => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@@ -1298,7 +1298,7 @@ abstract class $InitParamsCopyWith<$Res> {
|
|||||||
InitParams value, $Res Function(InitParams) then) =
|
InitParams value, $Res Function(InitParams) then) =
|
||||||
_$InitParamsCopyWithImpl<$Res, InitParams>;
|
_$InitParamsCopyWithImpl<$Res, InitParams>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({@JsonKey(name: "home-dir") String homeDir, int version});
|
$Res call({@JsonKey(name: 'home-dir') String homeDir, int version});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1340,7 +1340,7 @@ abstract class _$$InitParamsImplCopyWith<$Res>
|
|||||||
__$$InitParamsImplCopyWithImpl<$Res>;
|
__$$InitParamsImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({@JsonKey(name: "home-dir") String homeDir, int version});
|
$Res call({@JsonKey(name: 'home-dir') String homeDir, int version});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1376,14 +1376,14 @@ class __$$InitParamsImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$InitParamsImpl implements _InitParams {
|
class _$InitParamsImpl implements _InitParams {
|
||||||
const _$InitParamsImpl(
|
const _$InitParamsImpl(
|
||||||
{@JsonKey(name: "home-dir") required this.homeDir,
|
{@JsonKey(name: 'home-dir') required this.homeDir,
|
||||||
required this.version});
|
required this.version});
|
||||||
|
|
||||||
factory _$InitParamsImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$InitParamsImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$InitParamsImplFromJson(json);
|
_$$InitParamsImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "home-dir")
|
@JsonKey(name: 'home-dir')
|
||||||
final String homeDir;
|
final String homeDir;
|
||||||
@override
|
@override
|
||||||
final int version;
|
final int version;
|
||||||
@@ -1424,14 +1424,14 @@ class _$InitParamsImpl implements _InitParams {
|
|||||||
|
|
||||||
abstract class _InitParams implements InitParams {
|
abstract class _InitParams implements InitParams {
|
||||||
const factory _InitParams(
|
const factory _InitParams(
|
||||||
{@JsonKey(name: "home-dir") required final String homeDir,
|
{@JsonKey(name: 'home-dir') required final String homeDir,
|
||||||
required final int version}) = _$InitParamsImpl;
|
required final int version}) = _$InitParamsImpl;
|
||||||
|
|
||||||
factory _InitParams.fromJson(Map<String, dynamic> json) =
|
factory _InitParams.fromJson(Map<String, dynamic> json) =
|
||||||
_$InitParamsImpl.fromJson;
|
_$InitParamsImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "home-dir")
|
@JsonKey(name: 'home-dir')
|
||||||
String get homeDir;
|
String get homeDir;
|
||||||
@override
|
@override
|
||||||
int get version;
|
int get version;
|
||||||
@@ -1450,9 +1450,9 @@ ChangeProxyParams _$ChangeProxyParamsFromJson(Map<String, dynamic> json) {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$ChangeProxyParams {
|
mixin _$ChangeProxyParams {
|
||||||
@JsonKey(name: "group-name")
|
@JsonKey(name: 'group-name')
|
||||||
String get groupName => throw _privateConstructorUsedError;
|
String get groupName => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "proxy-name")
|
@JsonKey(name: 'proxy-name')
|
||||||
String get proxyName => throw _privateConstructorUsedError;
|
String get proxyName => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this ChangeProxyParams to a JSON map.
|
/// Serializes this ChangeProxyParams to a JSON map.
|
||||||
@@ -1472,8 +1472,8 @@ abstract class $ChangeProxyParamsCopyWith<$Res> {
|
|||||||
_$ChangeProxyParamsCopyWithImpl<$Res, ChangeProxyParams>;
|
_$ChangeProxyParamsCopyWithImpl<$Res, ChangeProxyParams>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "group-name") String groupName,
|
{@JsonKey(name: 'group-name') String groupName,
|
||||||
@JsonKey(name: "proxy-name") String proxyName});
|
@JsonKey(name: 'proxy-name') String proxyName});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1516,8 +1516,8 @@ abstract class _$$ChangeProxyParamsImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "group-name") String groupName,
|
{@JsonKey(name: 'group-name') String groupName,
|
||||||
@JsonKey(name: "proxy-name") String proxyName});
|
@JsonKey(name: 'proxy-name') String proxyName});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1553,17 +1553,17 @@ class __$$ChangeProxyParamsImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$ChangeProxyParamsImpl implements _ChangeProxyParams {
|
class _$ChangeProxyParamsImpl implements _ChangeProxyParams {
|
||||||
const _$ChangeProxyParamsImpl(
|
const _$ChangeProxyParamsImpl(
|
||||||
{@JsonKey(name: "group-name") required this.groupName,
|
{@JsonKey(name: 'group-name') required this.groupName,
|
||||||
@JsonKey(name: "proxy-name") required this.proxyName});
|
@JsonKey(name: 'proxy-name') required this.proxyName});
|
||||||
|
|
||||||
factory _$ChangeProxyParamsImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$ChangeProxyParamsImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$ChangeProxyParamsImplFromJson(json);
|
_$$ChangeProxyParamsImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "group-name")
|
@JsonKey(name: 'group-name')
|
||||||
final String groupName;
|
final String groupName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "proxy-name")
|
@JsonKey(name: 'proxy-name')
|
||||||
final String proxyName;
|
final String proxyName;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1605,18 +1605,18 @@ class _$ChangeProxyParamsImpl implements _ChangeProxyParams {
|
|||||||
|
|
||||||
abstract class _ChangeProxyParams implements ChangeProxyParams {
|
abstract class _ChangeProxyParams implements ChangeProxyParams {
|
||||||
const factory _ChangeProxyParams(
|
const factory _ChangeProxyParams(
|
||||||
{@JsonKey(name: "group-name") required final String groupName,
|
{@JsonKey(name: 'group-name') required final String groupName,
|
||||||
@JsonKey(name: "proxy-name") required final String proxyName}) =
|
@JsonKey(name: 'proxy-name') required final String proxyName}) =
|
||||||
_$ChangeProxyParamsImpl;
|
_$ChangeProxyParamsImpl;
|
||||||
|
|
||||||
factory _ChangeProxyParams.fromJson(Map<String, dynamic> json) =
|
factory _ChangeProxyParams.fromJson(Map<String, dynamic> json) =
|
||||||
_$ChangeProxyParamsImpl.fromJson;
|
_$ChangeProxyParamsImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "group-name")
|
@JsonKey(name: 'group-name')
|
||||||
String get groupName;
|
String get groupName;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "proxy-name")
|
@JsonKey(name: 'proxy-name')
|
||||||
String get proxyName;
|
String get proxyName;
|
||||||
|
|
||||||
/// Create a copy of ChangeProxyParams
|
/// Create a copy of ChangeProxyParams
|
||||||
@@ -1633,9 +1633,9 @@ UpdateGeoDataParams _$UpdateGeoDataParamsFromJson(Map<String, dynamic> json) {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$UpdateGeoDataParams {
|
mixin _$UpdateGeoDataParams {
|
||||||
@JsonKey(name: "geo-type")
|
@JsonKey(name: 'geo-type')
|
||||||
String get geoType => throw _privateConstructorUsedError;
|
String get geoType => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "geo-name")
|
@JsonKey(name: 'geo-name')
|
||||||
String get geoName => throw _privateConstructorUsedError;
|
String get geoName => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this UpdateGeoDataParams to a JSON map.
|
/// Serializes this UpdateGeoDataParams to a JSON map.
|
||||||
@@ -1655,8 +1655,8 @@ abstract class $UpdateGeoDataParamsCopyWith<$Res> {
|
|||||||
_$UpdateGeoDataParamsCopyWithImpl<$Res, UpdateGeoDataParams>;
|
_$UpdateGeoDataParamsCopyWithImpl<$Res, UpdateGeoDataParams>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "geo-type") String geoType,
|
{@JsonKey(name: 'geo-type') String geoType,
|
||||||
@JsonKey(name: "geo-name") String geoName});
|
@JsonKey(name: 'geo-name') String geoName});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1699,8 +1699,8 @@ abstract class _$$UpdateGeoDataParamsImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "geo-type") String geoType,
|
{@JsonKey(name: 'geo-type') String geoType,
|
||||||
@JsonKey(name: "geo-name") String geoName});
|
@JsonKey(name: 'geo-name') String geoName});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1736,17 +1736,17 @@ class __$$UpdateGeoDataParamsImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$UpdateGeoDataParamsImpl implements _UpdateGeoDataParams {
|
class _$UpdateGeoDataParamsImpl implements _UpdateGeoDataParams {
|
||||||
const _$UpdateGeoDataParamsImpl(
|
const _$UpdateGeoDataParamsImpl(
|
||||||
{@JsonKey(name: "geo-type") required this.geoType,
|
{@JsonKey(name: 'geo-type') required this.geoType,
|
||||||
@JsonKey(name: "geo-name") required this.geoName});
|
@JsonKey(name: 'geo-name') required this.geoName});
|
||||||
|
|
||||||
factory _$UpdateGeoDataParamsImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$UpdateGeoDataParamsImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$UpdateGeoDataParamsImplFromJson(json);
|
_$$UpdateGeoDataParamsImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "geo-type")
|
@JsonKey(name: 'geo-type')
|
||||||
final String geoType;
|
final String geoType;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "geo-name")
|
@JsonKey(name: 'geo-name')
|
||||||
final String geoName;
|
final String geoName;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1786,18 +1786,18 @@ class _$UpdateGeoDataParamsImpl implements _UpdateGeoDataParams {
|
|||||||
|
|
||||||
abstract class _UpdateGeoDataParams implements UpdateGeoDataParams {
|
abstract class _UpdateGeoDataParams implements UpdateGeoDataParams {
|
||||||
const factory _UpdateGeoDataParams(
|
const factory _UpdateGeoDataParams(
|
||||||
{@JsonKey(name: "geo-type") required final String geoType,
|
{@JsonKey(name: 'geo-type') required final String geoType,
|
||||||
@JsonKey(name: "geo-name") required final String geoName}) =
|
@JsonKey(name: 'geo-name') required final String geoName}) =
|
||||||
_$UpdateGeoDataParamsImpl;
|
_$UpdateGeoDataParamsImpl;
|
||||||
|
|
||||||
factory _UpdateGeoDataParams.fromJson(Map<String, dynamic> json) =
|
factory _UpdateGeoDataParams.fromJson(Map<String, dynamic> json) =
|
||||||
_$UpdateGeoDataParamsImpl.fromJson;
|
_$UpdateGeoDataParamsImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "geo-type")
|
@JsonKey(name: 'geo-type')
|
||||||
String get geoType;
|
String get geoType;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "geo-name")
|
@JsonKey(name: 'geo-name')
|
||||||
String get geoName;
|
String get geoName;
|
||||||
|
|
||||||
/// Create a copy of UpdateGeoDataParams
|
/// Create a copy of UpdateGeoDataParams
|
||||||
@@ -2489,13 +2489,13 @@ ProviderSubscriptionInfo _$ProviderSubscriptionInfoFromJson(
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$ProviderSubscriptionInfo {
|
mixin _$ProviderSubscriptionInfo {
|
||||||
@JsonKey(name: "UPLOAD")
|
@JsonKey(name: 'UPLOAD')
|
||||||
int get upload => throw _privateConstructorUsedError;
|
int get upload => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "DOWNLOAD")
|
@JsonKey(name: 'DOWNLOAD')
|
||||||
int get download => throw _privateConstructorUsedError;
|
int get download => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "TOTAL")
|
@JsonKey(name: 'TOTAL')
|
||||||
int get total => throw _privateConstructorUsedError;
|
int get total => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "EXPIRE")
|
@JsonKey(name: 'EXPIRE')
|
||||||
int get expire => throw _privateConstructorUsedError;
|
int get expire => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this ProviderSubscriptionInfo to a JSON map.
|
/// Serializes this ProviderSubscriptionInfo to a JSON map.
|
||||||
@@ -2515,10 +2515,10 @@ abstract class $ProviderSubscriptionInfoCopyWith<$Res> {
|
|||||||
_$ProviderSubscriptionInfoCopyWithImpl<$Res, ProviderSubscriptionInfo>;
|
_$ProviderSubscriptionInfoCopyWithImpl<$Res, ProviderSubscriptionInfo>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "UPLOAD") int upload,
|
{@JsonKey(name: 'UPLOAD') int upload,
|
||||||
@JsonKey(name: "DOWNLOAD") int download,
|
@JsonKey(name: 'DOWNLOAD') int download,
|
||||||
@JsonKey(name: "TOTAL") int total,
|
@JsonKey(name: 'TOTAL') int total,
|
||||||
@JsonKey(name: "EXPIRE") int expire});
|
@JsonKey(name: 'EXPIRE') int expire});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -2573,10 +2573,10 @@ abstract class _$$ProviderSubscriptionInfoImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{@JsonKey(name: "UPLOAD") int upload,
|
{@JsonKey(name: 'UPLOAD') int upload,
|
||||||
@JsonKey(name: "DOWNLOAD") int download,
|
@JsonKey(name: 'DOWNLOAD') int download,
|
||||||
@JsonKey(name: "TOTAL") int total,
|
@JsonKey(name: 'TOTAL') int total,
|
||||||
@JsonKey(name: "EXPIRE") int expire});
|
@JsonKey(name: 'EXPIRE') int expire});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -2624,25 +2624,25 @@ class __$$ProviderSubscriptionInfoImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$ProviderSubscriptionInfoImpl implements _ProviderSubscriptionInfo {
|
class _$ProviderSubscriptionInfoImpl implements _ProviderSubscriptionInfo {
|
||||||
const _$ProviderSubscriptionInfoImpl(
|
const _$ProviderSubscriptionInfoImpl(
|
||||||
{@JsonKey(name: "UPLOAD") this.upload = 0,
|
{@JsonKey(name: 'UPLOAD') this.upload = 0,
|
||||||
@JsonKey(name: "DOWNLOAD") this.download = 0,
|
@JsonKey(name: 'DOWNLOAD') this.download = 0,
|
||||||
@JsonKey(name: "TOTAL") this.total = 0,
|
@JsonKey(name: 'TOTAL') this.total = 0,
|
||||||
@JsonKey(name: "EXPIRE") this.expire = 0});
|
@JsonKey(name: 'EXPIRE') this.expire = 0});
|
||||||
|
|
||||||
factory _$ProviderSubscriptionInfoImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$ProviderSubscriptionInfoImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$ProviderSubscriptionInfoImplFromJson(json);
|
_$$ProviderSubscriptionInfoImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "UPLOAD")
|
@JsonKey(name: 'UPLOAD')
|
||||||
final int upload;
|
final int upload;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "DOWNLOAD")
|
@JsonKey(name: 'DOWNLOAD')
|
||||||
final int download;
|
final int download;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "TOTAL")
|
@JsonKey(name: 'TOTAL')
|
||||||
final int total;
|
final int total;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "EXPIRE")
|
@JsonKey(name: 'EXPIRE')
|
||||||
final int expire;
|
final int expire;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -2685,26 +2685,26 @@ class _$ProviderSubscriptionInfoImpl implements _ProviderSubscriptionInfo {
|
|||||||
|
|
||||||
abstract class _ProviderSubscriptionInfo implements ProviderSubscriptionInfo {
|
abstract class _ProviderSubscriptionInfo implements ProviderSubscriptionInfo {
|
||||||
const factory _ProviderSubscriptionInfo(
|
const factory _ProviderSubscriptionInfo(
|
||||||
{@JsonKey(name: "UPLOAD") final int upload,
|
{@JsonKey(name: 'UPLOAD') final int upload,
|
||||||
@JsonKey(name: "DOWNLOAD") final int download,
|
@JsonKey(name: 'DOWNLOAD') final int download,
|
||||||
@JsonKey(name: "TOTAL") final int total,
|
@JsonKey(name: 'TOTAL') final int total,
|
||||||
@JsonKey(name: "EXPIRE") final int expire}) =
|
@JsonKey(name: 'EXPIRE') final int expire}) =
|
||||||
_$ProviderSubscriptionInfoImpl;
|
_$ProviderSubscriptionInfoImpl;
|
||||||
|
|
||||||
factory _ProviderSubscriptionInfo.fromJson(Map<String, dynamic> json) =
|
factory _ProviderSubscriptionInfo.fromJson(Map<String, dynamic> json) =
|
||||||
_$ProviderSubscriptionInfoImpl.fromJson;
|
_$ProviderSubscriptionInfoImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "UPLOAD")
|
@JsonKey(name: 'UPLOAD')
|
||||||
int get upload;
|
int get upload;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "DOWNLOAD")
|
@JsonKey(name: 'DOWNLOAD')
|
||||||
int get download;
|
int get download;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "TOTAL")
|
@JsonKey(name: 'TOTAL')
|
||||||
int get total;
|
int get total;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "EXPIRE")
|
@JsonKey(name: 'EXPIRE')
|
||||||
int get expire;
|
int get expire;
|
||||||
|
|
||||||
/// Create a copy of ProviderSubscriptionInfo
|
/// Create a copy of ProviderSubscriptionInfo
|
||||||
@@ -2725,12 +2725,12 @@ mixin _$ExternalProvider {
|
|||||||
String get type => throw _privateConstructorUsedError;
|
String get type => throw _privateConstructorUsedError;
|
||||||
String? get path => throw _privateConstructorUsedError;
|
String? get path => throw _privateConstructorUsedError;
|
||||||
int get count => throw _privateConstructorUsedError;
|
int get count => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
SubscriptionInfo? get subscriptionInfo => throw _privateConstructorUsedError;
|
SubscriptionInfo? get subscriptionInfo => throw _privateConstructorUsedError;
|
||||||
bool get isUpdating => throw _privateConstructorUsedError;
|
bool get isUpdating => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "vehicle-type")
|
@JsonKey(name: 'vehicle-type')
|
||||||
String get vehicleType => throw _privateConstructorUsedError;
|
String get vehicleType => throw _privateConstructorUsedError;
|
||||||
@JsonKey(name: "update-at")
|
@JsonKey(name: 'update-at')
|
||||||
DateTime get updateAt => throw _privateConstructorUsedError;
|
DateTime get updateAt => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this ExternalProvider to a JSON map.
|
/// Serializes this ExternalProvider to a JSON map.
|
||||||
@@ -2754,11 +2754,11 @@ abstract class $ExternalProviderCopyWith<$Res> {
|
|||||||
String type,
|
String type,
|
||||||
String? path,
|
String? path,
|
||||||
int count,
|
int count,
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
SubscriptionInfo? subscriptionInfo,
|
SubscriptionInfo? subscriptionInfo,
|
||||||
bool isUpdating,
|
bool isUpdating,
|
||||||
@JsonKey(name: "vehicle-type") String vehicleType,
|
@JsonKey(name: 'vehicle-type') String vehicleType,
|
||||||
@JsonKey(name: "update-at") DateTime updateAt});
|
@JsonKey(name: 'update-at') DateTime updateAt});
|
||||||
|
|
||||||
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
|
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
|
||||||
}
|
}
|
||||||
@@ -2851,11 +2851,11 @@ abstract class _$$ExternalProviderImplCopyWith<$Res>
|
|||||||
String type,
|
String type,
|
||||||
String? path,
|
String? path,
|
||||||
int count,
|
int count,
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
SubscriptionInfo? subscriptionInfo,
|
SubscriptionInfo? subscriptionInfo,
|
||||||
bool isUpdating,
|
bool isUpdating,
|
||||||
@JsonKey(name: "vehicle-type") String vehicleType,
|
@JsonKey(name: 'vehicle-type') String vehicleType,
|
||||||
@JsonKey(name: "update-at") DateTime updateAt});
|
@JsonKey(name: 'update-at') DateTime updateAt});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
|
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
|
||||||
@@ -2928,11 +2928,11 @@ class _$ExternalProviderImpl implements _ExternalProvider {
|
|||||||
required this.type,
|
required this.type,
|
||||||
this.path,
|
this.path,
|
||||||
required this.count,
|
required this.count,
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
this.subscriptionInfo,
|
this.subscriptionInfo,
|
||||||
this.isUpdating = false,
|
this.isUpdating = false,
|
||||||
@JsonKey(name: "vehicle-type") required this.vehicleType,
|
@JsonKey(name: 'vehicle-type') required this.vehicleType,
|
||||||
@JsonKey(name: "update-at") required this.updateAt});
|
@JsonKey(name: 'update-at') required this.updateAt});
|
||||||
|
|
||||||
factory _$ExternalProviderImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$ExternalProviderImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$ExternalProviderImplFromJson(json);
|
_$$ExternalProviderImplFromJson(json);
|
||||||
@@ -2946,16 +2946,16 @@ class _$ExternalProviderImpl implements _ExternalProvider {
|
|||||||
@override
|
@override
|
||||||
final int count;
|
final int count;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
final SubscriptionInfo? subscriptionInfo;
|
final SubscriptionInfo? subscriptionInfo;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final bool isUpdating;
|
final bool isUpdating;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "vehicle-type")
|
@JsonKey(name: 'vehicle-type')
|
||||||
final String vehicleType;
|
final String vehicleType;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "update-at")
|
@JsonKey(name: 'update-at')
|
||||||
final DateTime updateAt;
|
final DateTime updateAt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -3010,11 +3010,11 @@ abstract class _ExternalProvider implements ExternalProvider {
|
|||||||
required final String type,
|
required final String type,
|
||||||
final String? path,
|
final String? path,
|
||||||
required final int count,
|
required final int count,
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
final SubscriptionInfo? subscriptionInfo,
|
final SubscriptionInfo? subscriptionInfo,
|
||||||
final bool isUpdating,
|
final bool isUpdating,
|
||||||
@JsonKey(name: "vehicle-type") required final String vehicleType,
|
@JsonKey(name: 'vehicle-type') required final String vehicleType,
|
||||||
@JsonKey(name: "update-at")
|
@JsonKey(name: 'update-at')
|
||||||
required final DateTime updateAt}) = _$ExternalProviderImpl;
|
required final DateTime updateAt}) = _$ExternalProviderImpl;
|
||||||
|
|
||||||
factory _ExternalProvider.fromJson(Map<String, dynamic> json) =
|
factory _ExternalProvider.fromJson(Map<String, dynamic> json) =
|
||||||
@@ -3029,15 +3029,15 @@ abstract class _ExternalProvider implements ExternalProvider {
|
|||||||
@override
|
@override
|
||||||
int get count;
|
int get count;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
@JsonKey(name: 'subscription-info', fromJson: subscriptionInfoFormCore)
|
||||||
SubscriptionInfo? get subscriptionInfo;
|
SubscriptionInfo? get subscriptionInfo;
|
||||||
@override
|
@override
|
||||||
bool get isUpdating;
|
bool get isUpdating;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "vehicle-type")
|
@JsonKey(name: 'vehicle-type')
|
||||||
String get vehicleType;
|
String get vehicleType;
|
||||||
@override
|
@override
|
||||||
@JsonKey(name: "update-at")
|
@JsonKey(name: 'update-at')
|
||||||
DateTime get updateAt;
|
DateTime get updateAt;
|
||||||
|
|
||||||
/// Create a copy of ExternalProvider
|
/// Create a copy of ExternalProvider
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ const _$LogLevelEnumMap = {
|
|||||||
LogLevel.warning: 'warning',
|
LogLevel.warning: 'warning',
|
||||||
LogLevel.error: 'error',
|
LogLevel.error: 'error',
|
||||||
LogLevel.silent: 'silent',
|
LogLevel.silent: 'silent',
|
||||||
LogLevel.app: 'app',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const _$ExternalControllerStatusEnumMap = {
|
const _$ExternalControllerStatusEnumMap = {
|
||||||
|
|||||||
@@ -492,7 +492,7 @@ class _$ProfileImpl implements _Profile {
|
|||||||
{required this.id,
|
{required this.id,
|
||||||
this.label,
|
this.label,
|
||||||
this.currentGroupName,
|
this.currentGroupName,
|
||||||
this.url = "",
|
this.url = '',
|
||||||
this.lastUpdateDate,
|
this.lastUpdateDate,
|
||||||
required this.autoUpdateDuration,
|
required this.autoUpdateDuration,
|
||||||
this.subscriptionInfo,
|
this.subscriptionInfo,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ _$ProfileImpl _$$ProfileImplFromJson(Map<String, dynamic> json) =>
|
|||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
label: json['label'] as String?,
|
label: json['label'] as String?,
|
||||||
currentGroupName: json['currentGroupName'] as String?,
|
currentGroupName: json['currentGroupName'] as String?,
|
||||||
url: json['url'] as String? ?? "",
|
url: json['url'] as String? ?? '',
|
||||||
lastUpdateDate: json['lastUpdateDate'] == null
|
lastUpdateDate: json['lastUpdateDate'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['lastUpdateDate'] as String),
|
: DateTime.parse(json['lastUpdateDate'] as String),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -531,7 +531,7 @@ abstract class _AppBarState implements AppBarState {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$AppBarSearchState {
|
mixin _$AppBarSearchState {
|
||||||
dynamic Function(String) get onSearch => throw _privateConstructorUsedError;
|
dynamic Function(String) get onSearch => throw _privateConstructorUsedError;
|
||||||
bool get isSearch => throw _privateConstructorUsedError;
|
String? get query => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Create a copy of AppBarSearchState
|
/// Create a copy of AppBarSearchState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -546,7 +546,7 @@ abstract class $AppBarSearchStateCopyWith<$Res> {
|
|||||||
AppBarSearchState value, $Res Function(AppBarSearchState) then) =
|
AppBarSearchState value, $Res Function(AppBarSearchState) then) =
|
||||||
_$AppBarSearchStateCopyWithImpl<$Res, AppBarSearchState>;
|
_$AppBarSearchStateCopyWithImpl<$Res, AppBarSearchState>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({dynamic Function(String) onSearch, bool isSearch});
|
$Res call({dynamic Function(String) onSearch, String? query});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -565,17 +565,17 @@ class _$AppBarSearchStateCopyWithImpl<$Res, $Val extends AppBarSearchState>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? onSearch = null,
|
Object? onSearch = null,
|
||||||
Object? isSearch = null,
|
Object? query = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
onSearch: null == onSearch
|
onSearch: null == onSearch
|
||||||
? _value.onSearch
|
? _value.onSearch
|
||||||
: onSearch // ignore: cast_nullable_to_non_nullable
|
: onSearch // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic Function(String),
|
as dynamic Function(String),
|
||||||
isSearch: null == isSearch
|
query: freezed == query
|
||||||
? _value.isSearch
|
? _value.query
|
||||||
: isSearch // ignore: cast_nullable_to_non_nullable
|
: query // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as String?,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -588,7 +588,7 @@ abstract class _$$AppBarSearchStateImplCopyWith<$Res>
|
|||||||
__$$AppBarSearchStateImplCopyWithImpl<$Res>;
|
__$$AppBarSearchStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({dynamic Function(String) onSearch, bool isSearch});
|
$Res call({dynamic Function(String) onSearch, String? query});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -605,17 +605,17 @@ class __$$AppBarSearchStateImplCopyWithImpl<$Res>
|
|||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? onSearch = null,
|
Object? onSearch = null,
|
||||||
Object? isSearch = null,
|
Object? query = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$AppBarSearchStateImpl(
|
return _then(_$AppBarSearchStateImpl(
|
||||||
onSearch: null == onSearch
|
onSearch: null == onSearch
|
||||||
? _value.onSearch
|
? _value.onSearch
|
||||||
: onSearch // ignore: cast_nullable_to_non_nullable
|
: onSearch // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic Function(String),
|
as dynamic Function(String),
|
||||||
isSearch: null == isSearch
|
query: freezed == query
|
||||||
? _value.isSearch
|
? _value.query
|
||||||
: isSearch // ignore: cast_nullable_to_non_nullable
|
: query // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as String?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -623,18 +623,17 @@ class __$$AppBarSearchStateImplCopyWithImpl<$Res>
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$AppBarSearchStateImpl implements _AppBarSearchState {
|
class _$AppBarSearchStateImpl implements _AppBarSearchState {
|
||||||
const _$AppBarSearchStateImpl(
|
const _$AppBarSearchStateImpl({required this.onSearch, this.query = null});
|
||||||
{required this.onSearch, this.isSearch = false});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final dynamic Function(String) onSearch;
|
final dynamic Function(String) onSearch;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final bool isSearch;
|
final String? query;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppBarSearchState(onSearch: $onSearch, isSearch: $isSearch)';
|
return 'AppBarSearchState(onSearch: $onSearch, query: $query)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -644,12 +643,11 @@ class _$AppBarSearchStateImpl implements _AppBarSearchState {
|
|||||||
other is _$AppBarSearchStateImpl &&
|
other is _$AppBarSearchStateImpl &&
|
||||||
(identical(other.onSearch, onSearch) ||
|
(identical(other.onSearch, onSearch) ||
|
||||||
other.onSearch == onSearch) &&
|
other.onSearch == onSearch) &&
|
||||||
(identical(other.isSearch, isSearch) ||
|
(identical(other.query, query) || other.query == query));
|
||||||
other.isSearch == isSearch));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, onSearch, isSearch);
|
int get hashCode => Object.hash(runtimeType, onSearch, query);
|
||||||
|
|
||||||
/// Create a copy of AppBarSearchState
|
/// Create a copy of AppBarSearchState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -664,12 +662,12 @@ class _$AppBarSearchStateImpl implements _AppBarSearchState {
|
|||||||
abstract class _AppBarSearchState implements AppBarSearchState {
|
abstract class _AppBarSearchState implements AppBarSearchState {
|
||||||
const factory _AppBarSearchState(
|
const factory _AppBarSearchState(
|
||||||
{required final dynamic Function(String) onSearch,
|
{required final dynamic Function(String) onSearch,
|
||||||
final bool isSearch}) = _$AppBarSearchStateImpl;
|
final String? query}) = _$AppBarSearchStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
dynamic Function(String) get onSearch;
|
dynamic Function(String) get onSearch;
|
||||||
@override
|
@override
|
||||||
bool get isSearch;
|
String? get query;
|
||||||
|
|
||||||
/// Create a copy of AppBarSearchState
|
/// Create a copy of AppBarSearchState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -681,8 +679,7 @@ abstract class _AppBarSearchState implements AppBarSearchState {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$AppBarEditState {
|
mixin _$AppBarEditState {
|
||||||
dynamic get editCount => throw _privateConstructorUsedError;
|
int get editCount => throw _privateConstructorUsedError;
|
||||||
bool get isEdit => throw _privateConstructorUsedError;
|
|
||||||
dynamic Function() get onExit => throw _privateConstructorUsedError;
|
dynamic Function() get onExit => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Create a copy of AppBarEditState
|
/// Create a copy of AppBarEditState
|
||||||
@@ -698,7 +695,7 @@ abstract class $AppBarEditStateCopyWith<$Res> {
|
|||||||
AppBarEditState value, $Res Function(AppBarEditState) then) =
|
AppBarEditState value, $Res Function(AppBarEditState) then) =
|
||||||
_$AppBarEditStateCopyWithImpl<$Res, AppBarEditState>;
|
_$AppBarEditStateCopyWithImpl<$Res, AppBarEditState>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({dynamic editCount, bool isEdit, dynamic Function() onExit});
|
$Res call({int editCount, dynamic Function() onExit});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -716,19 +713,14 @@ class _$AppBarEditStateCopyWithImpl<$Res, $Val extends AppBarEditState>
|
|||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? editCount = freezed,
|
Object? editCount = null,
|
||||||
Object? isEdit = null,
|
|
||||||
Object? onExit = null,
|
Object? onExit = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
editCount: freezed == editCount
|
editCount: null == editCount
|
||||||
? _value.editCount
|
? _value.editCount
|
||||||
: editCount // ignore: cast_nullable_to_non_nullable
|
: editCount // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic,
|
as int,
|
||||||
isEdit: null == isEdit
|
|
||||||
? _value.isEdit
|
|
||||||
: isEdit // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
onExit: null == onExit
|
onExit: null == onExit
|
||||||
? _value.onExit
|
? _value.onExit
|
||||||
: onExit // ignore: cast_nullable_to_non_nullable
|
: onExit // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -745,7 +737,7 @@ abstract class _$$AppBarEditStateImplCopyWith<$Res>
|
|||||||
__$$AppBarEditStateImplCopyWithImpl<$Res>;
|
__$$AppBarEditStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({dynamic editCount, bool isEdit, dynamic Function() onExit});
|
$Res call({int editCount, dynamic Function() onExit});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -761,16 +753,14 @@ class __$$AppBarEditStateImplCopyWithImpl<$Res>
|
|||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? editCount = freezed,
|
Object? editCount = null,
|
||||||
Object? isEdit = null,
|
|
||||||
Object? onExit = null,
|
Object? onExit = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$AppBarEditStateImpl(
|
return _then(_$AppBarEditStateImpl(
|
||||||
editCount: freezed == editCount ? _value.editCount! : editCount,
|
editCount: null == editCount
|
||||||
isEdit: null == isEdit
|
? _value.editCount
|
||||||
? _value.isEdit
|
: editCount // ignore: cast_nullable_to_non_nullable
|
||||||
: isEdit // ignore: cast_nullable_to_non_nullable
|
as int,
|
||||||
as bool,
|
|
||||||
onExit: null == onExit
|
onExit: null == onExit
|
||||||
? _value.onExit
|
? _value.onExit
|
||||||
: onExit // ignore: cast_nullable_to_non_nullable
|
: onExit // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -782,21 +772,17 @@ class __$$AppBarEditStateImplCopyWithImpl<$Res>
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$AppBarEditStateImpl implements _AppBarEditState {
|
class _$AppBarEditStateImpl implements _AppBarEditState {
|
||||||
const _$AppBarEditStateImpl(
|
const _$AppBarEditStateImpl({this.editCount = 0, required this.onExit});
|
||||||
{this.editCount = 0, this.isEdit = false, required this.onExit});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final dynamic editCount;
|
final int editCount;
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isEdit;
|
|
||||||
@override
|
@override
|
||||||
final dynamic Function() onExit;
|
final dynamic Function() onExit;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppBarEditState(editCount: $editCount, isEdit: $isEdit, onExit: $onExit)';
|
return 'AppBarEditState(editCount: $editCount, onExit: $onExit)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -804,14 +790,13 @@ class _$AppBarEditStateImpl implements _AppBarEditState {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$AppBarEditStateImpl &&
|
other is _$AppBarEditStateImpl &&
|
||||||
const DeepCollectionEquality().equals(other.editCount, editCount) &&
|
(identical(other.editCount, editCount) ||
|
||||||
(identical(other.isEdit, isEdit) || other.isEdit == isEdit) &&
|
other.editCount == editCount) &&
|
||||||
(identical(other.onExit, onExit) || other.onExit == onExit));
|
(identical(other.onExit, onExit) || other.onExit == onExit));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,
|
int get hashCode => Object.hash(runtimeType, editCount, onExit);
|
||||||
const DeepCollectionEquality().hash(editCount), isEdit, onExit);
|
|
||||||
|
|
||||||
/// Create a copy of AppBarEditState
|
/// Create a copy of AppBarEditState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -825,14 +810,11 @@ class _$AppBarEditStateImpl implements _AppBarEditState {
|
|||||||
|
|
||||||
abstract class _AppBarEditState implements AppBarEditState {
|
abstract class _AppBarEditState implements AppBarEditState {
|
||||||
const factory _AppBarEditState(
|
const factory _AppBarEditState(
|
||||||
{final dynamic editCount,
|
{final int editCount,
|
||||||
final bool isEdit,
|
|
||||||
required final dynamic Function() onExit}) = _$AppBarEditStateImpl;
|
required final dynamic Function() onExit}) = _$AppBarEditStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
dynamic get editCount;
|
int get editCount;
|
||||||
@override
|
|
||||||
bool get isEdit;
|
|
||||||
@override
|
@override
|
||||||
dynamic Function() get onExit;
|
dynamic Function() get onExit;
|
||||||
|
|
||||||
|
|||||||
@@ -29,17 +29,17 @@ class SubscriptionInfo with _$SubscriptionInfo {
|
|||||||
|
|
||||||
factory SubscriptionInfo.formHString(String? info) {
|
factory SubscriptionInfo.formHString(String? info) {
|
||||||
if (info == null) return const SubscriptionInfo();
|
if (info == null) return const SubscriptionInfo();
|
||||||
final list = info.split(";");
|
final list = info.split(';');
|
||||||
Map<String, int?> map = {};
|
Map<String, int?> map = {};
|
||||||
for (final i in list) {
|
for (final i in list) {
|
||||||
final keyValue = i.trim().split("=");
|
final keyValue = i.trim().split('=');
|
||||||
map[keyValue[0]] = int.tryParse(keyValue[1]);
|
map[keyValue[0]] = int.tryParse(keyValue[1]);
|
||||||
}
|
}
|
||||||
return SubscriptionInfo(
|
return SubscriptionInfo(
|
||||||
upload: map["upload"] ?? 0,
|
upload: map['upload'] ?? 0,
|
||||||
download: map["download"] ?? 0,
|
download: map['download'] ?? 0,
|
||||||
total: map["total"] ?? 0,
|
total: map['total'] ?? 0,
|
||||||
expire: map["expire"] ?? 0,
|
expire: map['expire'] ?? 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ class Profile with _$Profile {
|
|||||||
required String id,
|
required String id,
|
||||||
String? label,
|
String? label,
|
||||||
String? currentGroupName,
|
String? currentGroupName,
|
||||||
@Default("") String url,
|
@Default('') String url,
|
||||||
DateTime? lastUpdateDate,
|
DateTime? lastUpdateDate,
|
||||||
required Duration autoUpdateDuration,
|
required Duration autoUpdateDuration,
|
||||||
SubscriptionInfo? subscriptionInfo,
|
SubscriptionInfo? subscriptionInfo,
|
||||||
@@ -169,7 +169,7 @@ extension ProfileExtension on Profile {
|
|||||||
|
|
||||||
Future<Profile> update() async {
|
Future<Profile> update() async {
|
||||||
final response = await request.getFileResponseForUrl(url);
|
final response = await request.getFileResponseForUrl(url);
|
||||||
final disposition = response.headers.value("content-disposition");
|
final disposition = response.headers.value('content-disposition');
|
||||||
final userinfo = response.headers.value('subscription-userinfo');
|
final userinfo = response.headers.value('subscription-userinfo');
|
||||||
return await copyWith(
|
return await copyWith(
|
||||||
label: label ?? utils.getFileNameForDisposition(disposition) ?? id,
|
label: label ?? utils.getFileNameForDisposition(disposition) ?? id,
|
||||||
|
|||||||
@@ -88,28 +88,14 @@ class TrayState with _$TrayState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class HomeState with _$HomeState {
|
class NavigationState with _$NavigationState {
|
||||||
const factory HomeState({
|
const factory NavigationState({
|
||||||
required PageLabel pageLabel,
|
required PageLabel pageLabel,
|
||||||
required List<NavigationItem> navigationItems,
|
required List<NavigationItem> navigationItems,
|
||||||
required ViewMode viewMode,
|
required ViewMode viewMode,
|
||||||
required String? locale,
|
required String? locale,
|
||||||
}) = _HomeState;
|
required int currentIndex,
|
||||||
}
|
}) = _NavigationState;
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ProxiesSelectorState with _$ProxiesSelectorState {
|
|
||||||
const factory ProxiesSelectorState({
|
|
||||||
required List<String> groupNames,
|
|
||||||
required String? currentGroupName,
|
|
||||||
}) = _ProxiesSelectorState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class GroupNamesState with _$GroupNamesState {
|
|
||||||
const factory GroupNamesState({
|
|
||||||
required List<String> groupNames,
|
|
||||||
}) = _GroupNamesState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@@ -127,16 +113,27 @@ class NavigationItemsState with _$NavigationItemsState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ProxiesListSelectorState with _$ProxiesListSelectorState {
|
class ProxiesListState with _$ProxiesListState {
|
||||||
const factory ProxiesListSelectorState({
|
const factory ProxiesListState({
|
||||||
required List<String> groupNames,
|
required List<Group> groups,
|
||||||
required Set<String> currentUnfoldSet,
|
required Set<String> currentUnfoldSet,
|
||||||
required ProxiesSortType proxiesSortType,
|
required ProxiesSortType proxiesSortType,
|
||||||
required ProxyCardType proxyCardType,
|
required ProxyCardType proxyCardType,
|
||||||
required num sortNum,
|
required num sortNum,
|
||||||
required int columns,
|
required int columns,
|
||||||
required String query,
|
}) = _ProxiesListState;
|
||||||
}) = _ProxiesListSelectorState;
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class ProxiesTabState with _$ProxiesTabState {
|
||||||
|
const factory ProxiesTabState({
|
||||||
|
required List<Group> groups,
|
||||||
|
required String? currentGroupName,
|
||||||
|
required ProxiesSortType proxiesSortType,
|
||||||
|
required ProxyCardType proxyCardType,
|
||||||
|
required num sortNum,
|
||||||
|
required int columns,
|
||||||
|
}) = _ProxiesTabState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
|||||||
@@ -32,15 +32,14 @@ class AppBarState with _$AppBarState {
|
|||||||
class AppBarSearchState with _$AppBarSearchState {
|
class AppBarSearchState with _$AppBarSearchState {
|
||||||
const factory AppBarSearchState({
|
const factory AppBarSearchState({
|
||||||
required Function(String) onSearch,
|
required Function(String) onSearch,
|
||||||
@Default(false) bool isSearch,
|
@Default(null) String? query,
|
||||||
}) = _AppBarSearchState;
|
}) = _AppBarSearchState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class AppBarEditState with _$AppBarEditState {
|
class AppBarEditState with _$AppBarEditState {
|
||||||
const factory AppBarEditState({
|
const factory AppBarEditState({
|
||||||
@Default(0) editCount,
|
@Default(0) int editCount,
|
||||||
@Default(false) bool isEdit,
|
|
||||||
required Function() onExit,
|
required Function() onExit,
|
||||||
}) = _AppBarEditState;
|
}) = _AppBarEditState;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,11 +107,11 @@ class _EditorPageState extends ConsumerState<EditorPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleSearch() {
|
void _handleSearch() {
|
||||||
_findController.findMode();
|
_findController.findMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleImport() async {
|
Future<void> _handleImport() async {
|
||||||
final option = await globalState.showCommonDialog<ImportOption>(
|
final option = await globalState.showCommonDialog<ImportOption>(
|
||||||
child: _ImportOptionsDialog(),
|
child: _ImportOptionsDialog(),
|
||||||
);
|
);
|
||||||
@@ -129,8 +129,8 @@ class _EditorPageState extends ConsumerState<EditorPage> {
|
|||||||
}
|
}
|
||||||
final url = await globalState.showCommonDialog(
|
final url = await globalState.showCommonDialog(
|
||||||
child: InputDialog(
|
child: InputDialog(
|
||||||
title: "导入",
|
title: '导入',
|
||||||
value: "",
|
value: '',
|
||||||
labelText: appLocalizations.url,
|
labelText: appLocalizations.url,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
@@ -292,7 +292,7 @@ class _EditorPageState extends ConsumerState<EditorPage> {
|
|||||||
mode: langYaml,
|
mode: langYaml,
|
||||||
),
|
),
|
||||||
if (widget.languages.contains(Language.javaScript))
|
if (widget.languages.contains(Language.javaScript))
|
||||||
"javascript": CodeHighlightThemeMode(
|
'javascript': CodeHighlightThemeMode(
|
||||||
mode: langJavascript,
|
mode: langJavascript,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -433,7 +433,7 @@ class FindPanel extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildFindInput(BuildContext context, CodeFindValue value) {
|
Stack _buildFindInput(BuildContext context, CodeFindValue value) {
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
@@ -550,7 +550,7 @@ class ContextMenuControllerImpl implements SelectionToolbarController {
|
|||||||
OverlayEntry? _overlayEntry;
|
OverlayEntry? _overlayEntry;
|
||||||
bool _isFirstRender = true;
|
bool _isFirstRender = true;
|
||||||
|
|
||||||
_removeOverLayEntry() {
|
void _removeOverLayEntry() {
|
||||||
_overlayEntry?.remove();
|
_overlayEntry?.remove();
|
||||||
_overlayEntry = null;
|
_overlayEntry = null;
|
||||||
_isFirstRender = true;
|
_isFirstRender = true;
|
||||||
@@ -689,7 +689,7 @@ class _ImportOptionsDialog extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ImportOptionsDialogState extends State<_ImportOptionsDialog> {
|
class _ImportOptionsDialogState extends State<_ImportOptionsDialog> {
|
||||||
_handleOnTab(ImportOption value) {
|
void _handleOnTab(ImportOption value) {
|
||||||
Navigator.of(context).pop(value);
|
Navigator.of(context).pop(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
|
||||||
import 'package:fl_clash/providers/providers.dart';
|
import 'package:fl_clash/providers/providers.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:fl_clash/widgets/widgets.dart';
|
import 'package:fl_clash/widgets/widgets.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
@@ -18,43 +16,96 @@ class HomePage extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return HomeBackScope(
|
return HomeBackScope(
|
||||||
child: Consumer(
|
child: Material(
|
||||||
builder: (_, ref, child) {
|
color: context.colorScheme.surface,
|
||||||
final state = ref.watch(homeStateProvider);
|
child: Consumer(
|
||||||
final viewMode = state.viewMode;
|
builder: (context, ref, __) {
|
||||||
final navigationItems = state.navigationItems;
|
final state = ref.watch(navigationStateProvider);
|
||||||
final pageLabel = state.pageLabel;
|
final isMobile = state.viewMode == ViewMode.mobile;
|
||||||
final index = navigationItems.lastIndexWhere(
|
final navigationItems = state.navigationItems;
|
||||||
(element) => element.label == pageLabel,
|
final pageView = _HomePageView(pageBuilder: (_, index) {
|
||||||
);
|
final navigationItem = state.navigationItems[index];
|
||||||
final currentIndex = index == -1 ? 0 : index;
|
final navigationView = navigationItem.builder(context);
|
||||||
final navigationBar = CommonNavigationBar(
|
final view = isMobile
|
||||||
viewMode: viewMode,
|
? navigationView
|
||||||
navigationItems: navigationItems,
|
: KeepScope(
|
||||||
currentIndex: currentIndex,
|
keep: navigationItem.keep,
|
||||||
);
|
child: Navigator(
|
||||||
final bottomNavigationBar =
|
onGenerateRoute: (_) {
|
||||||
viewMode == ViewMode.mobile ? navigationBar : null;
|
return CommonRoute(
|
||||||
final sideNavigationBar =
|
builder: (_) => navigationView,
|
||||||
viewMode != ViewMode.mobile ? navigationBar : null;
|
);
|
||||||
return CommonScaffold(
|
},
|
||||||
key: globalState.homeScaffoldKey,
|
),
|
||||||
title: Intl.message(
|
);
|
||||||
pageLabel.name,
|
return view;
|
||||||
),
|
});
|
||||||
sideNavigationBar: sideNavigationBar,
|
final currentIndex = state.currentIndex;
|
||||||
body: child!,
|
final bottomNavigationBar = NavigationBarTheme(
|
||||||
bottomNavigationBar: bottomNavigationBar,
|
data: _NavigationBarDefaultsM3(context),
|
||||||
);
|
child: NavigationBar(
|
||||||
},
|
destinations: navigationItems
|
||||||
child: _HomePageView(),
|
.map(
|
||||||
|
(e) => NavigationDestination(
|
||||||
|
icon: e.icon,
|
||||||
|
label: Intl.message(e.label.name),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
onDestinationSelected: (index) {
|
||||||
|
globalState.appController.toPage(
|
||||||
|
navigationItems[index].label,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
selectedIndex: currentIndex,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (isMobile) {
|
||||||
|
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
|
value: globalState.appState.systemUiOverlayStyle.copyWith(
|
||||||
|
systemNavigationBarColor:
|
||||||
|
context.colorScheme.surfaceContainer,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: MediaQuery.removePadding(
|
||||||
|
removeTop: false,
|
||||||
|
removeBottom: true,
|
||||||
|
removeLeft: true,
|
||||||
|
removeRight: true,
|
||||||
|
context: context,
|
||||||
|
child: pageView,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MediaQuery.removePadding(
|
||||||
|
removeTop: true,
|
||||||
|
removeBottom: false,
|
||||||
|
removeLeft: true,
|
||||||
|
removeRight: true,
|
||||||
|
context: context,
|
||||||
|
child: bottomNavigationBar,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return pageView;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomePageView extends ConsumerStatefulWidget {
|
class _HomePageView extends ConsumerStatefulWidget {
|
||||||
const _HomePageView();
|
final IndexedWidgetBuilder pageBuilder;
|
||||||
|
|
||||||
|
const _HomePageView({
|
||||||
|
required this.pageBuilder,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState createState() => _HomePageViewState();
|
ConsumerState createState() => _HomePageViewState();
|
||||||
@@ -64,18 +115,17 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
|
|||||||
late PageController _pageController;
|
late PageController _pageController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_pageController = PageController(
|
_pageController = PageController(
|
||||||
initialPage: _pageIndex,
|
initialPage: _pageIndex,
|
||||||
keepPage: true,
|
|
||||||
);
|
);
|
||||||
ref.listenManual(currentPageLabelProvider, (prev, next) {
|
ref.listenManual(currentPageLabelProvider, (prev, next) {
|
||||||
if (prev != next) {
|
if (prev != next) {
|
||||||
_toPage(next);
|
_toPage(next);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ref.listenManual(currentNavigationsStateProvider, (prev, next) {
|
ref.listenManual(currentNavigationItemsStateProvider, (prev, next) {
|
||||||
if (prev?.value.length != next.value.length) {
|
if (prev?.value.length != next.value.length) {
|
||||||
_updatePageController();
|
_updatePageController();
|
||||||
}
|
}
|
||||||
@@ -83,17 +133,18 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int get _pageIndex {
|
int get _pageIndex {
|
||||||
final navigationItems = ref.read(currentNavigationsStateProvider).value;
|
final navigationItems = ref.read(currentNavigationItemsStateProvider).value;
|
||||||
return navigationItems.indexWhere(
|
return navigationItems.indexWhere(
|
||||||
(item) => item.label == globalState.appState.pageLabel,
|
(item) => item.label == globalState.appState.pageLabel,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_toPage(PageLabel pageLabel, [bool ignoreAnimateTo = false]) async {
|
Future<void> _toPage(PageLabel pageLabel,
|
||||||
|
[bool ignoreAnimateTo = false]) async {
|
||||||
if (!mounted) {
|
if (!mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final navigationItems = ref.read(currentNavigationsStateProvider).value;
|
final navigationItems = ref.read(currentNavigationItemsStateProvider).value;
|
||||||
final index = navigationItems.indexWhere((item) => item.label == pageLabel);
|
final index = navigationItems.indexWhere((item) => item.label == pageLabel);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
return;
|
return;
|
||||||
@@ -111,7 +162,7 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updatePageController() {
|
void _updatePageController() {
|
||||||
final pageLabel = globalState.appState.pageLabel;
|
final pageLabel = globalState.appState.pageLabel;
|
||||||
_toPage(pageLabel, true);
|
_toPage(pageLabel, true);
|
||||||
}
|
}
|
||||||
@@ -124,138 +175,19 @@ class _HomePageViewState extends ConsumerState<_HomePageView> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final navigationItems = ref.watch(currentNavigationsStateProvider).value;
|
final itemCount = ref.watch(currentNavigationItemsStateProvider
|
||||||
|
.select((state) => state.value.length));
|
||||||
return PageView.builder(
|
return PageView.builder(
|
||||||
controller: _pageController,
|
controller: _pageController,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemCount: navigationItems.length,
|
itemCount: itemCount,
|
||||||
// onPageChanged: (index) {
|
itemBuilder: (context, index) {
|
||||||
// debouncer.call(DebounceTag.pageChange, () {
|
return widget.pageBuilder(context, index);
|
||||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
// if (_pageIndex != index) {
|
|
||||||
// final pageLabel = navigationItems[index].label;
|
|
||||||
// _toPage(pageLabel, true);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
itemBuilder: (_, index) {
|
|
||||||
final navigationItem = navigationItems[index];
|
|
||||||
return KeepScope(
|
|
||||||
keep: navigationItem.keep,
|
|
||||||
key: Key(navigationItem.label.name),
|
|
||||||
child: navigationItem.view,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CommonNavigationBar extends ConsumerWidget {
|
|
||||||
final ViewMode viewMode;
|
|
||||||
final List<NavigationItem> navigationItems;
|
|
||||||
final int currentIndex;
|
|
||||||
|
|
||||||
const CommonNavigationBar({
|
|
||||||
super.key,
|
|
||||||
required this.viewMode,
|
|
||||||
required this.navigationItems,
|
|
||||||
required this.currentIndex,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, ref) {
|
|
||||||
if (viewMode == ViewMode.mobile) {
|
|
||||||
return NavigationBarTheme(
|
|
||||||
data: _NavigationBarDefaultsM3(context),
|
|
||||||
child: NavigationBar(
|
|
||||||
destinations: navigationItems
|
|
||||||
.map(
|
|
||||||
(e) => NavigationDestination(
|
|
||||||
icon: e.icon,
|
|
||||||
label: Intl.message(e.label.name),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
onDestinationSelected: (index) {
|
|
||||||
globalState.appController.toPage(navigationItems[index].label);
|
|
||||||
},
|
|
||||||
selectedIndex: currentIndex,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
final showLabel = ref.watch(appSettingProvider).showLabel;
|
|
||||||
return Material(
|
|
||||||
color: context.colorScheme.surfaceContainer,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: ScrollConfiguration(
|
|
||||||
behavior: HiddenBarScrollBehavior(),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: IntrinsicHeight(
|
|
||||||
child: NavigationRail(
|
|
||||||
backgroundColor: context.colorScheme.surfaceContainer,
|
|
||||||
selectedIconTheme: IconThemeData(
|
|
||||||
color: context.colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
unselectedIconTheme: IconThemeData(
|
|
||||||
color: context.colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
selectedLabelTextStyle:
|
|
||||||
context.textTheme.labelLarge!.copyWith(
|
|
||||||
color: context.colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
unselectedLabelTextStyle:
|
|
||||||
context.textTheme.labelLarge!.copyWith(
|
|
||||||
color: context.colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
destinations: navigationItems
|
|
||||||
.map(
|
|
||||||
(e) => NavigationRailDestination(
|
|
||||||
icon: e.icon,
|
|
||||||
label: Text(
|
|
||||||
Intl.message(e.label.name),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
onDestinationSelected: (index) {
|
|
||||||
globalState.appController
|
|
||||||
.toPage(navigationItems[index].label);
|
|
||||||
},
|
|
||||||
extended: false,
|
|
||||||
selectedIndex: currentIndex,
|
|
||||||
labelType: showLabel
|
|
||||||
? NavigationRailLabelType.all
|
|
||||||
: NavigationRailLabelType.none,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
ref.read(appSettingProvider.notifier).updateState(
|
|
||||||
(state) => state.copyWith(
|
|
||||||
showLabel: !state.showLabel,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.menu),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _NavigationBarDefaultsM3 extends NavigationBarThemeData {
|
class _NavigationBarDefaultsM3 extends NavigationBarThemeData {
|
||||||
_NavigationBarDefaultsM3(this.context)
|
_NavigationBarDefaultsM3(this.context)
|
||||||
: super(
|
: super(
|
||||||
@@ -319,7 +251,7 @@ class HomeBackScope extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (Platform.isAndroid) {
|
if (system.isAndroid) {
|
||||||
return CommonPopScope(
|
return CommonPopScope(
|
||||||
onPop: () async {
|
onPop: () async {
|
||||||
final canPop = Navigator.canPop(context);
|
final canPop = Navigator.canPop(context);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:fl_clash/common/color.dart';
|
import 'package:fl_clash/common/color.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:fl_clash/widgets/activate_box.dart';
|
import 'package:fl_clash/widgets/activate_box.dart';
|
||||||
@@ -29,7 +30,7 @@ class _ScanPageState extends State<ScanPage> with WidgetsBindingObserver {
|
|||||||
unawaited(controller.start());
|
unawaited(controller.start());
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleBarcode(BarcodeCapture barcodeCapture) {
|
void _handleBarcode(BarcodeCapture barcodeCapture) {
|
||||||
final barcode = barcodeCapture.barcodes.first;
|
final barcode = barcodeCapture.barcodes.first;
|
||||||
if (barcode.type == BarcodeType.url) {
|
if (barcode.type == BarcodeType.url) {
|
||||||
Navigator.pop<String>(
|
Navigator.pop<String>(
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:fl_clash/common/app_localizations.dart';
|
import 'package:fl_clash/common/app_localizations.dart';
|
||||||
|
import 'package:fl_clash/common/system.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@@ -15,18 +15,18 @@ class App {
|
|||||||
Function()? onExit;
|
Function()? onExit;
|
||||||
|
|
||||||
App._internal() {
|
App._internal() {
|
||||||
methodChannel = const MethodChannel("app");
|
methodChannel = const MethodChannel('app');
|
||||||
methodChannel.setMethodCallHandler((call) async {
|
methodChannel.setMethodCallHandler((call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "exit":
|
case 'exit':
|
||||||
if (onExit != null) {
|
if (onExit != null) {
|
||||||
await onExit!();
|
await onExit!();
|
||||||
}
|
}
|
||||||
case "getText":
|
case 'getText':
|
||||||
try {
|
try {
|
||||||
return Intl.message(call.arguments as String);
|
return Intl.message(call.arguments as String);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw MissingPluginException();
|
throw MissingPluginException();
|
||||||
@@ -40,12 +40,12 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> moveTaskToBack() async {
|
Future<bool?> moveTaskToBack() async {
|
||||||
return await methodChannel.invokeMethod<bool>("moveTaskToBack");
|
return await methodChannel.invokeMethod<bool>('moveTaskToBack');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Package>> getPackages() async {
|
Future<List<Package>> getPackages() async {
|
||||||
final packagesString =
|
final packagesString =
|
||||||
await methodChannel.invokeMethod<String>("getPackages");
|
await methodChannel.invokeMethod<String>('getPackages');
|
||||||
return Isolate.run<List<Package>>(() {
|
return Isolate.run<List<Package>>(() {
|
||||||
final List<dynamic> packagesRaw =
|
final List<dynamic> packagesRaw =
|
||||||
packagesString != null ? json.decode(packagesString) : [];
|
packagesString != null ? json.decode(packagesString) : [];
|
||||||
@@ -55,7 +55,7 @@ class App {
|
|||||||
|
|
||||||
Future<List<String>> getChinaPackageNames() async {
|
Future<List<String>> getChinaPackageNames() async {
|
||||||
final packageNamesString =
|
final packageNamesString =
|
||||||
await methodChannel.invokeMethod<String>("getChinaPackageNames");
|
await methodChannel.invokeMethod<String>('getChinaPackageNames');
|
||||||
return Isolate.run<List<String>>(() {
|
return Isolate.run<List<String>>(() {
|
||||||
final List<dynamic> packageNamesRaw =
|
final List<dynamic> packageNamesRaw =
|
||||||
packageNamesString != null ? json.decode(packageNamesString) : [];
|
packageNamesString != null ? json.decode(packageNamesString) : [];
|
||||||
@@ -64,15 +64,15 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> openFile(String path) async {
|
Future<bool> openFile(String path) async {
|
||||||
return await methodChannel.invokeMethod<bool>("openFile", {
|
return await methodChannel.invokeMethod<bool>('openFile', {
|
||||||
"path": path,
|
'path': path,
|
||||||
}) ??
|
}) ??
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ImageProvider?> getPackageIcon(String packageName) async {
|
Future<ImageProvider?> getPackageIcon(String packageName) async {
|
||||||
final base64 = await methodChannel.invokeMethod<String>("getPackageIcon", {
|
final base64 = await methodChannel.invokeMethod<String>('getPackageIcon', {
|
||||||
"packageName": packageName,
|
'packageName': packageName,
|
||||||
});
|
});
|
||||||
if (base64 == null) {
|
if (base64 == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -81,23 +81,23 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> tip(String? message) async {
|
Future<bool?> tip(String? message) async {
|
||||||
return await methodChannel.invokeMethod<bool>("tip", {
|
return await methodChannel.invokeMethod<bool>('tip', {
|
||||||
"message": "$message",
|
'message': '$message',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> initShortcuts() async {
|
Future<bool?> initShortcuts() async {
|
||||||
return await methodChannel.invokeMethod<bool>(
|
return await methodChannel.invokeMethod<bool>(
|
||||||
"initShortcuts",
|
'initShortcuts',
|
||||||
appLocalizations.toggle,
|
appLocalizations.toggle,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> updateExcludeFromRecents(bool value) async {
|
Future<bool?> updateExcludeFromRecents(bool value) async {
|
||||||
return await methodChannel.invokeMethod<bool>("updateExcludeFromRecents", {
|
return await methodChannel.invokeMethod<bool>('updateExcludeFromRecents', {
|
||||||
"value": value,
|
'value': value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final app = Platform.isAndroid ? App() : null;
|
final app = system.isAndroid ? App() : null;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
|
import 'package:fl_clash/common/system.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ class Service {
|
|||||||
ReceivePort? receiver;
|
ReceivePort? receiver;
|
||||||
|
|
||||||
Service._internal() {
|
Service._internal() {
|
||||||
methodChannel = const MethodChannel("service");
|
methodChannel = const MethodChannel('service');
|
||||||
}
|
}
|
||||||
|
|
||||||
factory Service() {
|
factory Service() {
|
||||||
@@ -22,23 +23,24 @@ class Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> init() async {
|
Future<bool?> init() async {
|
||||||
return await methodChannel.invokeMethod<bool>("init");
|
return await methodChannel.invokeMethod<bool>('init');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> destroy() async {
|
Future<bool?> destroy() async {
|
||||||
return await methodChannel.invokeMethod<bool>("destroy");
|
return await methodChannel.invokeMethod<bool>('destroy');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> startVpn() async {
|
Future<bool?> startVpn() async {
|
||||||
final options = await clashLib?.getAndroidVpnOptions();
|
final options = await clashLib?.getAndroidVpnOptions();
|
||||||
return await methodChannel.invokeMethod<bool>("startVpn", {
|
return await methodChannel.invokeMethod<bool>('startVpn', {
|
||||||
'data': json.encode(options),
|
'data': json.encode(options),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> stopVpn() async {
|
Future<bool?> stopVpn() async {
|
||||||
return await methodChannel.invokeMethod<bool>("stopVpn");
|
return await methodChannel.invokeMethod<bool>('stopVpn');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Service? get service => Platform.isAndroid && !globalState.isService ? Service() : null;
|
Service? get service =>
|
||||||
|
system.isAndroid && !globalState.isService ? Service() : null;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
|
import 'package:fl_clash/common/system.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
@@ -9,13 +9,10 @@ abstract mixin class TileListener {
|
|||||||
|
|
||||||
void onStop() {}
|
void onStop() {}
|
||||||
|
|
||||||
void onDetached(){
|
void onDetached() {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Tile {
|
class Tile {
|
||||||
|
|
||||||
final MethodChannel _channel = const MethodChannel('tile');
|
final MethodChannel _channel = const MethodChannel('tile');
|
||||||
|
|
||||||
Tile._() {
|
Tile._() {
|
||||||
@@ -29,13 +26,13 @@ class Tile {
|
|||||||
Future<void> _methodCallHandler(MethodCall call) async {
|
Future<void> _methodCallHandler(MethodCall call) async {
|
||||||
for (final TileListener listener in _listeners) {
|
for (final TileListener listener in _listeners) {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "start":
|
case 'start':
|
||||||
listener.onStart();
|
listener.onStart();
|
||||||
break;
|
break;
|
||||||
case "stop":
|
case 'stop':
|
||||||
listener.onStop();
|
listener.onStop();
|
||||||
break;
|
break;
|
||||||
case "detached":
|
case 'detached':
|
||||||
listener.onDetached();
|
listener.onDetached();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -55,4 +52,4 @@ class Tile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final tile = Platform.isAndroid ? Tile.instance : null;
|
final tile = system.isAndroid ? Tile.instance : null;
|
||||||
|
|||||||
@@ -17,22 +17,22 @@ class Vpn {
|
|||||||
FutureOr<String> Function()? handleGetStartForegroundParams;
|
FutureOr<String> Function()? handleGetStartForegroundParams;
|
||||||
|
|
||||||
Vpn._internal() {
|
Vpn._internal() {
|
||||||
methodChannel = const MethodChannel("vpn");
|
methodChannel = const MethodChannel('vpn');
|
||||||
methodChannel.setMethodCallHandler((call) async {
|
methodChannel.setMethodCallHandler((call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "gc":
|
case 'gc':
|
||||||
clashCore.requestGc();
|
clashCore.requestGc();
|
||||||
case "getStartForegroundParams":
|
case 'getStartForegroundParams':
|
||||||
if (handleGetStartForegroundParams != null) {
|
if (handleGetStartForegroundParams != null) {
|
||||||
return await handleGetStartForegroundParams!();
|
return await handleGetStartForegroundParams!();
|
||||||
}
|
}
|
||||||
return "";
|
return '';
|
||||||
case "status":
|
case 'status':
|
||||||
return clashLibHandler?.getRunTime() != null;
|
return clashLibHandler?.getRunTime() != null;
|
||||||
default:
|
default:
|
||||||
for (final VpnListener listener in _listeners) {
|
for (final VpnListener listener in _listeners) {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "dnsChanged":
|
case 'dnsChanged':
|
||||||
final dns = call.arguments as String;
|
final dns = call.arguments as String;
|
||||||
listener.onDnsChanged(dns);
|
listener.onDnsChanged(dns);
|
||||||
}
|
}
|
||||||
@@ -49,13 +49,13 @@ class Vpn {
|
|||||||
final ObserverList<VpnListener> _listeners = ObserverList<VpnListener>();
|
final ObserverList<VpnListener> _listeners = ObserverList<VpnListener>();
|
||||||
|
|
||||||
Future<bool?> start(AndroidVpnOptions options) async {
|
Future<bool?> start(AndroidVpnOptions options) async {
|
||||||
return await methodChannel.invokeMethod<bool>("start", {
|
return await methodChannel.invokeMethod<bool>('start', {
|
||||||
'data': json.encode(options),
|
'data': json.encode(options),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> stop() async {
|
Future<bool?> stop() async {
|
||||||
return await methodChannel.invokeMethod<bool>("stop");
|
return await methodChannel.invokeMethod<bool>('stop');
|
||||||
}
|
}
|
||||||
|
|
||||||
void addListener(VpnListener listener) {
|
void addListener(VpnListener listener) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:fl_clash/common/common.dart';
|
|||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ class Logs extends _$Logs with AutoDisposeNotifierMixin {
|
|||||||
return globalState.appState.logs;
|
return globalState.appState.logs;
|
||||||
}
|
}
|
||||||
|
|
||||||
addLog(Log value) {
|
void addLog(Log value) {
|
||||||
state = state.copyWith()..add(value);
|
state = state.copyWith()..add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ class Logs extends _$Logs with AutoDisposeNotifierMixin {
|
|||||||
@riverpod
|
@riverpod
|
||||||
class Requests extends _$Requests with AutoDisposeNotifierMixin {
|
class Requests extends _$Requests with AutoDisposeNotifierMixin {
|
||||||
@override
|
@override
|
||||||
FixedList<Connection> build() {
|
FixedList<TrackerInfo> build() {
|
||||||
return globalState.appState.requests;
|
return globalState.appState.requests;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ class Requests extends _$Requests with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
addRequest(Connection value) {
|
void addRequest(TrackerInfo value) {
|
||||||
state = state.copyWith()..add(value);
|
state = state.copyWith()..add(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ class Providers extends _$Providers with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setProvider(ExternalProvider? provider) {
|
void setProvider(ExternalProvider? provider) {
|
||||||
if (provider == null) return;
|
if (provider == null) return;
|
||||||
final index = state.indexWhere((item) => item.name == provider.name);
|
final index = state.indexWhere((item) => item.name == provider.name);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
@@ -99,9 +99,10 @@ class Packages extends _$Packages with AutoDisposeNotifierMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
class AppBrightness extends _$AppBrightness with AutoDisposeNotifierMixin {
|
class SystemBrightness extends _$SystemBrightness
|
||||||
|
with AutoDisposeNotifierMixin {
|
||||||
@override
|
@override
|
||||||
Brightness? build() {
|
Brightness build() {
|
||||||
return globalState.appState.brightness;
|
return globalState.appState.brightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +113,7 @@ class AppBrightness extends _$AppBrightness with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(Brightness? value) {
|
void setState(Brightness value) {
|
||||||
state = value;
|
state = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,11 +132,11 @@ class Traffics extends _$Traffics with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
addTraffic(Traffic value) {
|
void addTraffic(Traffic value) {
|
||||||
state = state.copyWith()..add(value);
|
state = state.copyWith()..add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
void clear() {
|
||||||
state = state.copyWith()..clear();
|
state = state.copyWith()..clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,7 +282,7 @@ class SortNum extends _$SortNum with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
add() => state++;
|
int add() => state++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
@@ -298,7 +299,7 @@ class CheckIpNum extends _$CheckIpNum with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
add() => state++;
|
int add() => state++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
@@ -316,6 +317,21 @@ class BackBlock extends _$BackBlock with AutoDisposeNotifierMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
class Loading extends _$Loading with AutoDisposeNotifierMixin {
|
||||||
|
@override
|
||||||
|
bool build() {
|
||||||
|
return globalState.appState.loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
onUpdate(value) {
|
||||||
|
globalState.appState = globalState.appState.copyWith(
|
||||||
|
loading: value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
class Version extends _$Version with AutoDisposeNotifierMixin {
|
class Version extends _$Version with AutoDisposeNotifierMixin {
|
||||||
@override
|
@override
|
||||||
@@ -360,7 +376,7 @@ class DelayDataSource extends _$DelayDataSource with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setDelay(Delay delay) {
|
void setDelay(Delay delay) {
|
||||||
if (state[delay.url]?[delay.name] != delay.value) {
|
if (state[delay.url]?[delay.name] != delay.value) {
|
||||||
final DelayMap newDelayMap = Map.from(state);
|
final DelayMap newDelayMap = Map.from(state);
|
||||||
if (newDelayMap[delay.url] == null) {
|
if (newDelayMap[delay.url] == null) {
|
||||||
@@ -373,16 +389,17 @@ class DelayDataSource extends _$DelayDataSource with AutoDisposeNotifierMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
class ProxiesQuery extends _$ProxiesQuery with AutoDisposeNotifierMixin {
|
class SystemUiOverlayStyleState extends _$SystemUiOverlayStyleState
|
||||||
|
with AutoDisposeNotifierMixin {
|
||||||
@override
|
@override
|
||||||
String build() {
|
SystemUiOverlayStyle build() {
|
||||||
return globalState.appState.proxiesQuery;
|
return globalState.appState.systemUiOverlayStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
onUpdate(value) {
|
onUpdate(value) {
|
||||||
globalState.appState = globalState.appState.copyWith(
|
globalState.appState = globalState.appState.copyWith(
|
||||||
proxiesQuery: value,
|
systemUiOverlayStyle: value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class AppSetting extends _$AppSetting with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(AppSettingProps Function(AppSettingProps state) builder) {
|
void updateState(AppSettingProps Function(AppSettingProps state) builder) {
|
||||||
state = builder(state);
|
state = builder(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ class WindowSetting extends _$WindowSetting with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(WindowProps Function(WindowProps state) builder) {
|
void updateState(WindowProps Function(WindowProps state) builder) {
|
||||||
state = builder(state);
|
state = builder(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ class VpnSetting extends _$VpnSetting with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(VpnProps Function(VpnProps state) builder) {
|
void updateState(VpnProps Function(VpnProps state) builder) {
|
||||||
state = builder(state);
|
state = builder(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ class NetworkSetting extends _$NetworkSetting with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(NetworkProps Function(NetworkProps state) builder) {
|
void updateState(NetworkProps Function(NetworkProps state) builder) {
|
||||||
state = builder(state);
|
state = builder(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ class ThemeSetting extends _$ThemeSetting with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(ThemeProps Function(ThemeProps state) builder) {
|
void updateState(ThemeProps Function(ThemeProps state) builder) {
|
||||||
state = builder(state);
|
state = builder(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setProfile(Profile profile) {
|
void setProfile(Profile profile) {
|
||||||
final List<Profile> profilesTemp = List.from(state);
|
final List<Profile> profilesTemp = List.from(state);
|
||||||
final index =
|
final index =
|
||||||
profilesTemp.indexWhere((element) => element.id == profile.id);
|
profilesTemp.indexWhere((element) => element.id == profile.id);
|
||||||
@@ -141,7 +141,8 @@ class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
|
|||||||
state = profilesTemp;
|
state = profilesTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateProfile(String profileId, Profile Function(Profile profile) builder) {
|
void updateProfile(
|
||||||
|
String profileId, Profile Function(Profile profile) builder) {
|
||||||
final List<Profile> profilesTemp = List.from(state);
|
final List<Profile> profilesTemp = List.from(state);
|
||||||
final index = profilesTemp.indexWhere((element) => element.id == profileId);
|
final index = profilesTemp.indexWhere((element) => element.id == profileId);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
@@ -150,7 +151,7 @@ class Profiles extends _$Profiles with AutoDisposeNotifierMixin {
|
|||||||
state = profilesTemp;
|
state = profilesTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteProfileById(String id) {
|
void deleteProfileById(String id) {
|
||||||
state = state.where((element) => element.id != id).toList();
|
state = state.where((element) => element.id != id).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +186,7 @@ class AppDAVSetting extends _$AppDAVSetting with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(DAV? Function(DAV? state) builder) {
|
void updateState(DAV? Function(DAV? state) builder) {
|
||||||
state = builder(state);
|
state = builder(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +236,7 @@ class ProxiesStyleSetting extends _$ProxiesStyleSetting
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(ProxiesStyle Function(ProxiesStyle state) builder) {
|
void updateState(ProxiesStyle Function(ProxiesStyle state) builder) {
|
||||||
state = builder(state);
|
state = builder(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,7 +255,7 @@ class ScriptState extends _$ScriptState with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setScript(Script script) {
|
void setScript(Script script) {
|
||||||
final list = List<Script>.from(state.scripts);
|
final list = List<Script>.from(state.scripts);
|
||||||
final index = list.indexWhere((item) => item.id == script.id);
|
final index = list.indexWhere((item) => item.id == script.id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
@@ -267,13 +268,13 @@ class ScriptState extends _$ScriptState with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
setId(String id) {
|
void setId(String id) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
currentId: state.currentId != id ? id : null,
|
currentId: state.currentId != id ? id : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
del(String id) {
|
void del(String id) {
|
||||||
final list = List<Script>.from(state.scripts);
|
final list = List<Script>.from(state.scripts);
|
||||||
final index = list.indexWhere((item) => item.label == id);
|
final index = list.indexWhere((item) => item.label == id);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
@@ -286,7 +287,7 @@ class ScriptState extends _$ScriptState with AutoDisposeNotifierMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
isExits(String label) {
|
bool isExits(String label) {
|
||||||
return state.scripts.indexWhere((item) => item.label == label) != -1;
|
return state.scripts.indexWhere((item) => item.label == label) != -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,7 +300,7 @@ class PatchClashConfig extends _$PatchClashConfig
|
|||||||
return globalState.config.patchClashConfig;
|
return globalState.config.patchClashConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState(ClashConfig? Function(ClashConfig state) builder) {
|
void updateState(ClashConfig? Function(ClashConfig state) builder) {
|
||||||
final newState = builder(state);
|
final newState = builder(state);
|
||||||
if (newState == null) {
|
if (newState == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user