Fix windows tray issues
Support setting bypassDomain Update flutter version Fix android service issues Fix macos dock exit button issues Add route address setting Optimize provider view
This commit is contained in:
@@ -15,6 +15,7 @@ import androidx.core.graphics.drawable.toBitmap
|
|||||||
import com.follow.clash.TempActivity
|
import com.follow.clash.TempActivity
|
||||||
import com.follow.clash.models.CIDR
|
import com.follow.clash.models.CIDR
|
||||||
import com.follow.clash.models.Metadata
|
import com.follow.clash.models.Metadata
|
||||||
|
import com.follow.clash.models.VpnOptions
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -42,6 +43,40 @@ fun Metadata.getProtocol(): Int? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun VpnOptions.getIpv4RouteAddress(): List<CIDR> {
|
||||||
|
return routeAddress.filter {
|
||||||
|
it.isIpv4()
|
||||||
|
}.map {
|
||||||
|
it.toCIDR()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VpnOptions.getIpv6RouteAddress(): List<CIDR> {
|
||||||
|
return routeAddress.filter {
|
||||||
|
it.isIpv6()
|
||||||
|
}.map {
|
||||||
|
it.toCIDR()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.isIpv4(): Boolean {
|
||||||
|
val parts = split("/")
|
||||||
|
if (parts.size != 2) {
|
||||||
|
throw IllegalArgumentException("Invalid CIDR format")
|
||||||
|
}
|
||||||
|
val address = InetAddress.getByName(parts[0])
|
||||||
|
return address.address.size == 4
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.isIpv6(): Boolean {
|
||||||
|
val parts = split("/")
|
||||||
|
if (parts.size != 2) {
|
||||||
|
throw IllegalArgumentException("Invalid CIDR format")
|
||||||
|
}
|
||||||
|
val address = InetAddress.getByName(parts[0])
|
||||||
|
return address.address.size == 16
|
||||||
|
}
|
||||||
|
|
||||||
fun String.toCIDR(): CIDR {
|
fun String.toCIDR(): CIDR {
|
||||||
val parts = split("/")
|
val parts = split("/")
|
||||||
if (parts.size != 2) {
|
if (parts.size != 2) {
|
||||||
@@ -79,7 +114,7 @@ fun InetAddress.asSocketAddressText(port: Int): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.wrapAction(action: String):String{
|
fun Context.wrapAction(action: String): String {
|
||||||
return "${this.packageName}.action.$action"
|
return "${this.packageName}.action.$action"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ package com.follow.clash.models
|
|||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
|
|
||||||
enum class AccessControlMode {
|
enum class AccessControlMode {
|
||||||
acceptSelected,
|
acceptSelected, rejectSelected,
|
||||||
rejectSelected,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class AccessControl(
|
data class AccessControl(
|
||||||
@@ -22,6 +21,7 @@ data class VpnOptions(
|
|||||||
val allowBypass: Boolean,
|
val allowBypass: Boolean,
|
||||||
val systemProxy: Boolean,
|
val systemProxy: Boolean,
|
||||||
val bypassDomain: List<String>,
|
val bypassDomain: List<String>,
|
||||||
|
val routeAddress: List<String>,
|
||||||
val ipv4Address: String,
|
val ipv4Address: String,
|
||||||
val ipv6Address: String,
|
val ipv6Address: String,
|
||||||
val dnsServerAddress: String,
|
val dnsServerAddress: String,
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import com.follow.clash.GlobalState
|
|||||||
import com.follow.clash.MainActivity
|
import com.follow.clash.MainActivity
|
||||||
import com.follow.clash.extensions.getActionPendingIntent
|
import com.follow.clash.extensions.getActionPendingIntent
|
||||||
import com.follow.clash.models.VpnOptions
|
import com.follow.clash.models.VpnOptions
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
class FlClashService : Service(), BaseServiceInterface {
|
class FlClashService : Service(), BaseServiceInterface {
|
||||||
@@ -69,7 +72,7 @@ class FlClashService : Service(), BaseServiceInterface {
|
|||||||
addAction(
|
addAction(
|
||||||
0,
|
0,
|
||||||
GlobalState.getText("stop"),
|
GlobalState.getText("stop"),
|
||||||
getActionPendingIntent("CHANGE")
|
getActionPendingIntent("STOP")
|
||||||
)
|
)
|
||||||
setOngoing(true)
|
setOngoing(true)
|
||||||
setShowWhen(false)
|
setShowWhen(false)
|
||||||
@@ -89,21 +92,23 @@ class FlClashService : Service(), BaseServiceInterface {
|
|||||||
|
|
||||||
@SuppressLint("ForegroundServiceType", "WrongConstant")
|
@SuppressLint("ForegroundServiceType", "WrongConstant")
|
||||||
override fun startForeground(title: String, content: String) {
|
override fun startForeground(title: String, content: String) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
val manager = getSystemService(NotificationManager::class.java)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
var channel = manager?.getNotificationChannel(CHANNEL)
|
val manager = getSystemService(NotificationManager::class.java)
|
||||||
if (channel == null) {
|
var channel = manager?.getNotificationChannel(CHANNEL)
|
||||||
channel =
|
if (channel == null) {
|
||||||
NotificationChannel(CHANNEL, "FlClash", NotificationManager.IMPORTANCE_LOW)
|
channel =
|
||||||
manager?.createNotificationChannel(channel)
|
NotificationChannel(CHANNEL, "FlClash", NotificationManager.IMPORTANCE_LOW)
|
||||||
|
manager?.createNotificationChannel(channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val notification =
|
||||||
|
notificationBuilder.setContentTitle(title).setContentText(content).build()
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
startForeground(notificationId, notification, FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
|
||||||
|
} else {
|
||||||
|
startForeground(notificationId, notification)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
val notification =
|
|
||||||
notificationBuilder.setContentTitle(title).setContentText(content).build()
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
||||||
startForeground(notificationId, notification, FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
|
|
||||||
} else {
|
|
||||||
startForeground(notificationId, notification)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,20 +15,21 @@ import android.os.Build
|
|||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.RemoteException
|
import android.os.RemoteException
|
||||||
|
import android.util.Log
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import com.follow.clash.BaseServiceInterface
|
import com.follow.clash.BaseServiceInterface
|
||||||
import com.follow.clash.GlobalState
|
import com.follow.clash.GlobalState
|
||||||
import com.follow.clash.MainActivity
|
import com.follow.clash.MainActivity
|
||||||
import com.follow.clash.R
|
import com.follow.clash.R
|
||||||
import com.follow.clash.TempActivity
|
|
||||||
import com.follow.clash.extensions.getActionPendingIntent
|
import com.follow.clash.extensions.getActionPendingIntent
|
||||||
|
import com.follow.clash.extensions.getIpv4RouteAddress
|
||||||
|
import com.follow.clash.extensions.getIpv6RouteAddress
|
||||||
import com.follow.clash.extensions.toCIDR
|
import com.follow.clash.extensions.toCIDR
|
||||||
import com.follow.clash.models.AccessControlMode
|
import com.follow.clash.models.AccessControlMode
|
||||||
import com.follow.clash.models.VpnOptions
|
import com.follow.clash.models.VpnOptions
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
|
|
||||||
|
|
||||||
class FlClashVpnService : VpnService(), BaseServiceInterface {
|
class FlClashVpnService : VpnService(), BaseServiceInterface {
|
||||||
@@ -42,12 +43,28 @@ class FlClashVpnService : VpnService(), BaseServiceInterface {
|
|||||||
if (options.ipv4Address.isNotEmpty()) {
|
if (options.ipv4Address.isNotEmpty()) {
|
||||||
val cidr = options.ipv4Address.toCIDR()
|
val cidr = options.ipv4Address.toCIDR()
|
||||||
addAddress(cidr.address, cidr.prefixLength)
|
addAddress(cidr.address, cidr.prefixLength)
|
||||||
addRoute("0.0.0.0", 0)
|
val routeAddress = options.getIpv4RouteAddress()
|
||||||
|
if (routeAddress.isNotEmpty()) {
|
||||||
|
routeAddress.forEach { i ->
|
||||||
|
Log.d("addRoute4", "address: ${i.address} prefixLength:${i.prefixLength}")
|
||||||
|
addRoute(i.address, i.prefixLength)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addRoute("0.0.0.0", 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (options.ipv6Address.isNotEmpty()) {
|
if (options.ipv6Address.isNotEmpty()) {
|
||||||
val cidr = options.ipv6Address.toCIDR()
|
val cidr = options.ipv6Address.toCIDR()
|
||||||
addAddress(cidr.address, cidr.prefixLength)
|
addAddress(cidr.address, cidr.prefixLength)
|
||||||
addRoute("::", 0)
|
val routeAddress = options.getIpv6RouteAddress()
|
||||||
|
if (routeAddress.isNotEmpty()) {
|
||||||
|
routeAddress.forEach { i ->
|
||||||
|
Log.d("addRoute6", "address: ${i.address} prefixLength:${i.prefixLength}")
|
||||||
|
addRoute(i.address, i.prefixLength)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addRoute("::", 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
addDnsServer(options.dnsServerAddress)
|
addDnsServer(options.dnsServerAddress)
|
||||||
setMtu(9000)
|
setMtu(9000)
|
||||||
|
|||||||
Submodule core/Clash.Meta updated: 317fd5ece0...148f1a2445
175
core/common.go
175
core/common.go
@@ -66,12 +66,13 @@ type ProcessMapItem struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ExternalProvider struct {
|
type ExternalProvider struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
VehicleType string `json:"vehicle-type"`
|
VehicleType string `json:"vehicle-type"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
UpdateAt time.Time `json:"update-at"`
|
UpdateAt time.Time `json:"update-at"`
|
||||||
|
SubscriptionInfo *provider.SubscriptionInfo `json:"subscription-info"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExternalProviders []ExternalProvider
|
type ExternalProviders []ExternalProvider
|
||||||
@@ -198,12 +199,13 @@ func toExternalProvider(p cp.Provider) (*ExternalProvider, error) {
|
|||||||
case *provider.ProxySetProvider:
|
case *provider.ProxySetProvider:
|
||||||
psp := p.(*provider.ProxySetProvider)
|
psp := p.(*provider.ProxySetProvider)
|
||||||
return &ExternalProvider{
|
return &ExternalProvider{
|
||||||
Name: psp.Name(),
|
Name: psp.Name(),
|
||||||
Type: psp.Type().String(),
|
Type: psp.Type().String(),
|
||||||
VehicleType: psp.VehicleType().String(),
|
VehicleType: psp.VehicleType().String(),
|
||||||
Count: psp.Count(),
|
Count: psp.Count(),
|
||||||
Path: psp.Vehicle().Path(),
|
UpdateAt: psp.UpdatedAt(),
|
||||||
UpdateAt: psp.UpdatedAt(),
|
Path: psp.Vehicle().Path(),
|
||||||
|
SubscriptionInfo: psp.GetSubscriptionInfo(),
|
||||||
}, nil
|
}, nil
|
||||||
case *rp.RuleSetProvider:
|
case *rp.RuleSetProvider:
|
||||||
rsp := p.(*rp.RuleSetProvider)
|
rsp := p.(*rp.RuleSetProvider)
|
||||||
@@ -212,8 +214,8 @@ func toExternalProvider(p cp.Provider) (*ExternalProvider, error) {
|
|||||||
Type: rsp.Type().String(),
|
Type: rsp.Type().String(),
|
||||||
VehicleType: rsp.VehicleType().String(),
|
VehicleType: rsp.VehicleType().String(),
|
||||||
Count: rsp.Count(),
|
Count: rsp.Count(),
|
||||||
Path: rsp.Vehicle().Path(),
|
|
||||||
UpdateAt: rsp.UpdatedAt(),
|
UpdateAt: rsp.UpdatedAt(),
|
||||||
|
Path: rsp.Vehicle().Path(),
|
||||||
}, nil
|
}, nil
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("not external provider")
|
return nil, errors.New("not external provider")
|
||||||
@@ -247,152 +249,6 @@ func decorationConfig(profileId string, cfg config.RawConfig) *config.RawConfig
|
|||||||
return prof
|
return prof
|
||||||
}
|
}
|
||||||
|
|
||||||
//func Reduce[T any, U any](s []T, initVal U, f func(U, T) U) U {
|
|
||||||
// for _, v := range s {
|
|
||||||
// initVal = f(initVal, v)
|
|
||||||
// }
|
|
||||||
// return initVal
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func Map[T, U any](slice []T, fn func(T) U) []U {
|
|
||||||
// result := make([]U, len(slice))
|
|
||||||
// for i, v := range slice {
|
|
||||||
// result[i] = fn(v)
|
|
||||||
// }
|
|
||||||
// return result
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func replaceFromMap(s string, m map[string]string) string {
|
|
||||||
// for k, v := range m {
|
|
||||||
// s = strings.ReplaceAll(s, k, v)
|
|
||||||
// }
|
|
||||||
// return s
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//func removeDuplicateFromSlice[T any](slice []T) []T {
|
|
||||||
// result := make([]T, 0)
|
|
||||||
// seen := make(map[any]struct{})
|
|
||||||
// for _, value := range slice {
|
|
||||||
// if _, ok := seen[value]; !ok {
|
|
||||||
// result = append(result, value)
|
|
||||||
// seen[value] = struct{}{}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return result
|
|
||||||
//}
|
|
||||||
|
|
||||||
//func generateProxyGroupAndRule(proxyGroup *[]map[string]any, rule *[]string) {
|
|
||||||
// var replacements = map[string]string{}
|
|
||||||
// var selectArr []map[string]any
|
|
||||||
// var urlTestArr []map[string]any
|
|
||||||
// var fallbackArr []map[string]any
|
|
||||||
// for _, group := range *proxyGroup {
|
|
||||||
// switch group["type"] {
|
|
||||||
// case "select":
|
|
||||||
// selectArr = append(selectArr, group)
|
|
||||||
// replacements[group["name"].(string)] = "Proxy"
|
|
||||||
// break
|
|
||||||
// case "url-test":
|
|
||||||
// urlTestArr = append(urlTestArr, group)
|
|
||||||
// replacements[group["name"].(string)] = "Auto"
|
|
||||||
// break
|
|
||||||
// case "fallback":
|
|
||||||
// fallbackArr = append(fallbackArr, group)
|
|
||||||
// replacements[group["name"].(string)] = "Fallback"
|
|
||||||
// break
|
|
||||||
// default:
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ProxyProxies := Reduce(selectArr, []string{}, func(res []string, cur map[string]any) []string {
|
|
||||||
// if cur["proxies"] == nil {
|
|
||||||
// return res
|
|
||||||
// }
|
|
||||||
// for _, proxyName := range cur["proxies"].([]interface{}) {
|
|
||||||
// if str, ok := proxyName.(string); ok {
|
|
||||||
// str = replaceFromMap(str, replacements)
|
|
||||||
// if str != "Proxy" {
|
|
||||||
// res = append(res, str)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return res
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// ProxyProxies = removeDuplicateFromSlice(ProxyProxies)
|
|
||||||
//
|
|
||||||
// AutoProxies := Reduce(urlTestArr, []string{}, func(res []string, cur map[string]any) []string {
|
|
||||||
// if cur["proxies"] == nil {
|
|
||||||
// return res
|
|
||||||
// }
|
|
||||||
// for _, proxyName := range cur["proxies"].([]interface{}) {
|
|
||||||
// if str, ok := proxyName.(string); ok {
|
|
||||||
// str = replaceFromMap(str, replacements)
|
|
||||||
// if str != "Auto" {
|
|
||||||
// res = append(res, str)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return res
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// AutoProxies = removeDuplicateFromSlice(AutoProxies)
|
|
||||||
//
|
|
||||||
// FallbackProxies := Reduce(fallbackArr, []string{}, func(res []string, cur map[string]any) []string {
|
|
||||||
// if cur["proxies"] == nil {
|
|
||||||
// return res
|
|
||||||
// }
|
|
||||||
// for _, proxyName := range cur["proxies"].([]interface{}) {
|
|
||||||
// if str, ok := proxyName.(string); ok {
|
|
||||||
// str = replaceFromMap(str, replacements)
|
|
||||||
// if str != "Fallback" {
|
|
||||||
// res = append(res, str)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return res
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// FallbackProxies = removeDuplicateFromSlice(FallbackProxies)
|
|
||||||
//
|
|
||||||
// var computedProxyGroup []map[string]any
|
|
||||||
//
|
|
||||||
// if len(ProxyProxies) > 0 {
|
|
||||||
// computedProxyGroup = append(computedProxyGroup,
|
|
||||||
// map[string]any{
|
|
||||||
// "name": "Proxy",
|
|
||||||
// "type": "select",
|
|
||||||
// "proxies": ProxyProxies,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if len(AutoProxies) > 0 {
|
|
||||||
// computedProxyGroup = append(computedProxyGroup,
|
|
||||||
// map[string]any{
|
|
||||||
// "name": "Auto",
|
|
||||||
// "type": "url-test",
|
|
||||||
// "proxies": AutoProxies,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if len(FallbackProxies) > 0 {
|
|
||||||
// computedProxyGroup = append(computedProxyGroup,
|
|
||||||
// map[string]any{
|
|
||||||
// "name": "Fallback",
|
|
||||||
// "type": "fallback",
|
|
||||||
// "proxies": FallbackProxies,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// computedRule := Map(*rule, func(value string) string {
|
|
||||||
// return replaceFromMap(value, replacements)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// *proxyGroup = computedProxyGroup
|
|
||||||
// *rule = computedRule
|
|
||||||
//}
|
|
||||||
|
|
||||||
func genHosts(hosts, patchHosts map[string]any) {
|
func genHosts(hosts, patchHosts map[string]any) {
|
||||||
for k, v := range patchHosts {
|
for k, v := range patchHosts {
|
||||||
hosts[k] = v
|
hosts[k] = v
|
||||||
@@ -582,6 +438,5 @@ func applyConfig() error {
|
|||||||
patchSelectGroup()
|
patchSelectGroup()
|
||||||
}
|
}
|
||||||
updateListeners(cfg.General, cfg.Listeners)
|
updateListeners(cfg.General, cfg.Listeners)
|
||||||
externalProviders = getExternalProvidersRaw()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
492
core/hub.go
492
core/hub.go
@@ -1,493 +1 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stdlib.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
bridge "core/dart-bridge"
|
|
||||||
"core/state"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"github.com/metacubex/mihomo/common/utils"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"sort"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/adapter"
|
|
||||||
"github.com/metacubex/mihomo/adapter/outboundgroup"
|
|
||||||
"github.com/metacubex/mihomo/adapter/provider"
|
|
||||||
"github.com/metacubex/mihomo/component/updater"
|
|
||||||
"github.com/metacubex/mihomo/config"
|
|
||||||
"github.com/metacubex/mihomo/constant"
|
|
||||||
cp "github.com/metacubex/mihomo/constant/provider"
|
|
||||||
"github.com/metacubex/mihomo/hub/executor"
|
|
||||||
"github.com/metacubex/mihomo/log"
|
|
||||||
"github.com/metacubex/mihomo/tunnel"
|
|
||||||
"github.com/metacubex/mihomo/tunnel/statistic"
|
|
||||||
)
|
|
||||||
|
|
||||||
var configParams = ConfigExtendedParams{}
|
|
||||||
|
|
||||||
var externalProviders = map[string]cp.Provider{}
|
|
||||||
|
|
||||||
var isInit = false
|
|
||||||
|
|
||||||
//export start
|
|
||||||
func start() {
|
|
||||||
runLock.Lock()
|
|
||||||
defer runLock.Unlock()
|
|
||||||
isRunning = true
|
|
||||||
}
|
|
||||||
|
|
||||||
//export stop
|
|
||||||
func stop() {
|
|
||||||
runLock.Lock()
|
|
||||||
go func() {
|
|
||||||
defer runLock.Unlock()
|
|
||||||
isRunning = false
|
|
||||||
stopListeners()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export initClash
|
|
||||||
func initClash(homeDirStr *C.char) bool {
|
|
||||||
if !isInit {
|
|
||||||
constant.SetHomeDir(C.GoString(homeDirStr))
|
|
||||||
isInit = true
|
|
||||||
}
|
|
||||||
return isInit
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getIsInit
|
|
||||||
func getIsInit() bool {
|
|
||||||
return isInit
|
|
||||||
}
|
|
||||||
|
|
||||||
//export restartClash
|
|
||||||
func restartClash() bool {
|
|
||||||
execPath, _ := os.Executable()
|
|
||||||
go restartExecutable(execPath)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
//export shutdownClash
|
|
||||||
func shutdownClash() bool {
|
|
||||||
stopListeners()
|
|
||||||
executor.Shutdown()
|
|
||||||
runtime.GC()
|
|
||||||
isInit = false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
//export forceGc
|
|
||||||
func forceGc() {
|
|
||||||
go func() {
|
|
||||||
log.Infoln("[APP] request force GC")
|
|
||||||
runtime.GC()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export validateConfig
|
|
||||||
func validateConfig(s *C.char, port C.longlong) {
|
|
||||||
i := int64(port)
|
|
||||||
bytes := []byte(C.GoString(s))
|
|
||||||
go func() {
|
|
||||||
_, err := config.UnmarshalRawConfig(bytes)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bridge.SendToPort(i, "")
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
var updateLock sync.Mutex
|
|
||||||
|
|
||||||
//export updateConfig
|
|
||||||
func updateConfig(s *C.char, port C.longlong) {
|
|
||||||
i := int64(port)
|
|
||||||
paramsString := C.GoString(s)
|
|
||||||
go func() {
|
|
||||||
updateLock.Lock()
|
|
||||||
defer updateLock.Unlock()
|
|
||||||
var params = &GenerateConfigParams{}
|
|
||||||
err := json.Unmarshal([]byte(paramsString), params)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
configParams = params.Params
|
|
||||||
prof := decorationConfig(params.ProfileId, params.Config)
|
|
||||||
state.CurrentRawConfig = prof
|
|
||||||
err = applyConfig()
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bridge.SendToPort(i, "")
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export clearEffect
|
|
||||||
func clearEffect(s *C.char) {
|
|
||||||
id := C.GoString(s)
|
|
||||||
go func() {
|
|
||||||
_ = removeFile(getProfilePath(id))
|
|
||||||
_ = removeFile(getProfileProvidersPath(id))
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getProxies
|
|
||||||
func getProxies() *C.char {
|
|
||||||
data, err := json.Marshal(tunnel.ProxiesWithProviders())
|
|
||||||
if err != nil {
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export changeProxy
|
|
||||||
func changeProxy(s *C.char) {
|
|
||||||
paramsString := C.GoString(s)
|
|
||||||
var params = &ChangeProxyParams{}
|
|
||||||
err := json.Unmarshal([]byte(paramsString), params)
|
|
||||||
if err != nil {
|
|
||||||
log.Infoln("Unmarshal ChangeProxyParams %v", err)
|
|
||||||
}
|
|
||||||
groupName := *params.GroupName
|
|
||||||
proxyName := *params.ProxyName
|
|
||||||
proxies := tunnel.ProxiesWithProviders()
|
|
||||||
group, ok := proxies[groupName]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
adapterProxy := group.(*adapter.Proxy)
|
|
||||||
selector, ok := adapterProxy.ProxyAdapter.(outboundgroup.SelectAble)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if proxyName == "" {
|
|
||||||
selector.ForceSet(proxyName)
|
|
||||||
} else {
|
|
||||||
err = selector.Set(proxyName)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
log.Infoln("[SelectAble] %s selected %s", groupName, proxyName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getTraffic
|
|
||||||
func getTraffic() *C.char {
|
|
||||||
up, down := statistic.DefaultManager.Current(state.CurrentState.OnlyProxy)
|
|
||||||
traffic := map[string]int64{
|
|
||||||
"up": up,
|
|
||||||
"down": down,
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(traffic)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error:", err)
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getTotalTraffic
|
|
||||||
func getTotalTraffic() *C.char {
|
|
||||||
up, down := statistic.DefaultManager.Total(state.CurrentState.OnlyProxy)
|
|
||||||
traffic := map[string]int64{
|
|
||||||
"up": up,
|
|
||||||
"down": down,
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(traffic)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error:", err)
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export resetTraffic
|
|
||||||
func resetTraffic() {
|
|
||||||
statistic.DefaultManager.ResetStatistic()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export asyncTestDelay
|
|
||||||
func asyncTestDelay(s *C.char, port C.longlong) {
|
|
||||||
i := int64(port)
|
|
||||||
paramsString := C.GoString(s)
|
|
||||||
b.Go(paramsString, func() (bool, error) {
|
|
||||||
var params = &TestDelayParams{}
|
|
||||||
err := json.Unmarshal([]byte(paramsString), params)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, "")
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedStatus, err := utils.NewUnsignedRanges[uint16]("")
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, "")
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*time.Duration(params.Timeout))
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
proxies := tunnel.ProxiesWithProviders()
|
|
||||||
proxy := proxies[params.ProxyName]
|
|
||||||
|
|
||||||
delayData := &Delay{
|
|
||||||
Name: params.ProxyName,
|
|
||||||
}
|
|
||||||
|
|
||||||
if proxy == nil {
|
|
||||||
delayData.Value = -1
|
|
||||||
data, _ := json.Marshal(delayData)
|
|
||||||
bridge.SendToPort(i, string(data))
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
delay, err := proxy.URLTest(ctx, constant.DefaultTestURL, expectedStatus)
|
|
||||||
if err != nil || delay == 0 {
|
|
||||||
delayData.Value = -1
|
|
||||||
data, _ := json.Marshal(delayData)
|
|
||||||
bridge.SendToPort(i, string(data))
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
delayData.Value = int32(delay)
|
|
||||||
data, _ := json.Marshal(delayData)
|
|
||||||
bridge.SendToPort(i, string(data))
|
|
||||||
return false, nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getVersionInfo
|
|
||||||
func getVersionInfo() *C.char {
|
|
||||||
versionInfo := map[string]string{
|
|
||||||
"clashName": constant.Name,
|
|
||||||
"version": "1.18.5",
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(versionInfo)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error:", err)
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getConnections
|
|
||||||
func getConnections() *C.char {
|
|
||||||
snapshot := statistic.DefaultManager.Snapshot()
|
|
||||||
data, err := json.Marshal(snapshot)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Error:", err)
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export closeConnections
|
|
||||||
func closeConnections() {
|
|
||||||
statistic.DefaultManager.Range(func(c statistic.Tracker) bool {
|
|
||||||
err := c.Close()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
//export closeConnection
|
|
||||||
func closeConnection(id *C.char) {
|
|
||||||
connectionId := C.GoString(id)
|
|
||||||
c := statistic.DefaultManager.Get(connectionId)
|
|
||||||
if c == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_ = c.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getProviders
|
|
||||||
func getProviders() *C.char {
|
|
||||||
data, err := json.Marshal(tunnel.Providers())
|
|
||||||
var msg *C.char
|
|
||||||
if err != nil {
|
|
||||||
msg = C.CString("")
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
msg = C.CString(string(data))
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getProvider
|
|
||||||
func getProvider(name *C.char) *C.char {
|
|
||||||
providerName := C.GoString(name)
|
|
||||||
providers := tunnel.Providers()
|
|
||||||
data, err := json.Marshal(providers[providerName])
|
|
||||||
if err != nil {
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getExternalProviders
|
|
||||||
func getExternalProviders() *C.char {
|
|
||||||
eps := make([]ExternalProvider, 0)
|
|
||||||
for _, p := range externalProviders {
|
|
||||||
externalProvider, err := toExternalProvider(p)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
eps = append(eps, *externalProvider)
|
|
||||||
}
|
|
||||||
sort.Sort(ExternalProviders(eps))
|
|
||||||
data, err := json.Marshal(eps)
|
|
||||||
if err != nil {
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export getExternalProvider
|
|
||||||
func getExternalProvider(name *C.char) *C.char {
|
|
||||||
externalProviderName := C.GoString(name)
|
|
||||||
externalProvider, exist := externalProviders[externalProviderName]
|
|
||||||
if !exist {
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
e, err := toExternalProvider(externalProvider)
|
|
||||||
if err != nil {
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(e)
|
|
||||||
if err != nil {
|
|
||||||
return C.CString("")
|
|
||||||
}
|
|
||||||
return C.CString(string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export updateGeoData
|
|
||||||
func updateGeoData(geoType *C.char, geoName *C.char, port C.longlong) {
|
|
||||||
i := int64(port)
|
|
||||||
geoTypeString := C.GoString(geoType)
|
|
||||||
geoNameString := C.GoString(geoName)
|
|
||||||
go func() {
|
|
||||||
path := constant.Path.Resolve(geoNameString)
|
|
||||||
switch geoTypeString {
|
|
||||||
case "MMDB":
|
|
||||||
err := updater.UpdateMMDBWithPath(path)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "ASN":
|
|
||||||
err := updater.UpdateASNWithPath(path)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "GeoIp":
|
|
||||||
err := updater.UpdateGeoIpWithPath(path)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "GeoSite":
|
|
||||||
err := updater.UpdateGeoSiteWithPath(path)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bridge.SendToPort(i, "")
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export updateExternalProvider
|
|
||||||
func updateExternalProvider(providerName *C.char, port C.longlong) {
|
|
||||||
i := int64(port)
|
|
||||||
providerNameString := C.GoString(providerName)
|
|
||||||
go func() {
|
|
||||||
externalProvider, exist := externalProviders[providerNameString]
|
|
||||||
if !exist {
|
|
||||||
bridge.SendToPort(i, "external provider is not exist")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err := externalProvider.Update()
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bridge.SendToPort(i, "")
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export sideLoadExternalProvider
|
|
||||||
func sideLoadExternalProvider(providerName *C.char, data *C.char, port C.longlong) {
|
|
||||||
i := int64(port)
|
|
||||||
bytes := []byte(C.GoString(data))
|
|
||||||
providerNameString := C.GoString(providerName)
|
|
||||||
go func() {
|
|
||||||
externalProvider, exist := externalProviders[providerNameString]
|
|
||||||
if !exist {
|
|
||||||
bridge.SendToPort(i, "external provider is not exist")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err := sideUpdateExternalProvider(externalProvider, bytes)
|
|
||||||
if err != nil {
|
|
||||||
bridge.SendToPort(i, err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bridge.SendToPort(i, "")
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export initNativeApiBridge
|
|
||||||
func initNativeApiBridge(api unsafe.Pointer) {
|
|
||||||
bridge.InitDartApi(api)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export initMessage
|
|
||||||
func initMessage(port C.longlong) {
|
|
||||||
i := int64(port)
|
|
||||||
Port = i
|
|
||||||
}
|
|
||||||
|
|
||||||
//export freeCString
|
|
||||||
func freeCString(s *C.char) {
|
|
||||||
C.free(unsafe.Pointer(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
provider.HealthcheckHook = func(name string, delay uint16) {
|
|
||||||
delayData := &Delay{
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
if delay == 0 {
|
|
||||||
delayData.Value = -1
|
|
||||||
} else {
|
|
||||||
delayData.Value = int32(delay)
|
|
||||||
}
|
|
||||||
SendMessage(Message{
|
|
||||||
Type: DelayMessage,
|
|
||||||
Data: delayData,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
statistic.DefaultRequestNotify = func(c statistic.Tracker) {
|
|
||||||
SendMessage(Message{
|
|
||||||
Type: RequestMessage,
|
|
||||||
Data: c,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
executor.DefaultProviderLoadedHook = func(providerName string) {
|
|
||||||
SendMessage(Message{
|
|
||||||
Type: LoadedMessage,
|
|
||||||
Data: providerName,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
475
core/lib.go
Normal file
475
core/lib.go
Normal file
@@ -0,0 +1,475 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
bridge "core/dart-bridge"
|
||||||
|
"core/state"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/metacubex/mihomo/common/utils"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/adapter"
|
||||||
|
"github.com/metacubex/mihomo/adapter/outboundgroup"
|
||||||
|
"github.com/metacubex/mihomo/adapter/provider"
|
||||||
|
"github.com/metacubex/mihomo/component/updater"
|
||||||
|
"github.com/metacubex/mihomo/config"
|
||||||
|
"github.com/metacubex/mihomo/constant"
|
||||||
|
cp "github.com/metacubex/mihomo/constant/provider"
|
||||||
|
"github.com/metacubex/mihomo/hub/executor"
|
||||||
|
"github.com/metacubex/mihomo/log"
|
||||||
|
"github.com/metacubex/mihomo/tunnel"
|
||||||
|
"github.com/metacubex/mihomo/tunnel/statistic"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configParams = ConfigExtendedParams{}
|
||||||
|
|
||||||
|
var externalProviders = map[string]cp.Provider{}
|
||||||
|
|
||||||
|
var isInit = false
|
||||||
|
|
||||||
|
//export start
|
||||||
|
func start() {
|
||||||
|
runLock.Lock()
|
||||||
|
defer runLock.Unlock()
|
||||||
|
isRunning = true
|
||||||
|
}
|
||||||
|
|
||||||
|
//export stop
|
||||||
|
func stop() {
|
||||||
|
runLock.Lock()
|
||||||
|
go func() {
|
||||||
|
defer runLock.Unlock()
|
||||||
|
isRunning = false
|
||||||
|
stopListeners()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export initClash
|
||||||
|
func initClash(homeDirStr *C.char) bool {
|
||||||
|
if !isInit {
|
||||||
|
constant.SetHomeDir(C.GoString(homeDirStr))
|
||||||
|
isInit = true
|
||||||
|
}
|
||||||
|
return isInit
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getIsInit
|
||||||
|
func getIsInit() bool {
|
||||||
|
return isInit
|
||||||
|
}
|
||||||
|
|
||||||
|
//export restartClash
|
||||||
|
func restartClash() bool {
|
||||||
|
execPath, _ := os.Executable()
|
||||||
|
go restartExecutable(execPath)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//export shutdownClash
|
||||||
|
func shutdownClash() bool {
|
||||||
|
stopListeners()
|
||||||
|
executor.Shutdown()
|
||||||
|
runtime.GC()
|
||||||
|
isInit = false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//export forceGc
|
||||||
|
func forceGc() {
|
||||||
|
go func() {
|
||||||
|
log.Infoln("[APP] request force GC")
|
||||||
|
runtime.GC()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export validateConfig
|
||||||
|
func validateConfig(s *C.char, port C.longlong) {
|
||||||
|
i := int64(port)
|
||||||
|
bytes := []byte(C.GoString(s))
|
||||||
|
go func() {
|
||||||
|
_, err := config.UnmarshalRawConfig(bytes)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bridge.SendToPort(i, "")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateLock sync.Mutex
|
||||||
|
|
||||||
|
//export updateConfig
|
||||||
|
func updateConfig(s *C.char, port C.longlong) {
|
||||||
|
i := int64(port)
|
||||||
|
paramsString := C.GoString(s)
|
||||||
|
go func() {
|
||||||
|
updateLock.Lock()
|
||||||
|
defer updateLock.Unlock()
|
||||||
|
var params = &GenerateConfigParams{}
|
||||||
|
err := json.Unmarshal([]byte(paramsString), params)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
configParams = params.Params
|
||||||
|
prof := decorationConfig(params.ProfileId, params.Config)
|
||||||
|
state.CurrentRawConfig = prof
|
||||||
|
err = applyConfig()
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bridge.SendToPort(i, "")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export clearEffect
|
||||||
|
func clearEffect(s *C.char) {
|
||||||
|
id := C.GoString(s)
|
||||||
|
go func() {
|
||||||
|
_ = removeFile(getProfilePath(id))
|
||||||
|
_ = removeFile(getProfileProvidersPath(id))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getProxies
|
||||||
|
func getProxies() *C.char {
|
||||||
|
data, err := json.Marshal(tunnel.ProxiesWithProviders())
|
||||||
|
if err != nil {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
return C.CString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export changeProxy
|
||||||
|
func changeProxy(s *C.char) {
|
||||||
|
paramsString := C.GoString(s)
|
||||||
|
var params = &ChangeProxyParams{}
|
||||||
|
err := json.Unmarshal([]byte(paramsString), params)
|
||||||
|
if err != nil {
|
||||||
|
log.Infoln("Unmarshal ChangeProxyParams %v", err)
|
||||||
|
}
|
||||||
|
groupName := *params.GroupName
|
||||||
|
proxyName := *params.ProxyName
|
||||||
|
proxies := tunnel.ProxiesWithProviders()
|
||||||
|
group, ok := proxies[groupName]
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
adapterProxy := group.(*adapter.Proxy)
|
||||||
|
selector, ok := adapterProxy.ProxyAdapter.(outboundgroup.SelectAble)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if proxyName == "" {
|
||||||
|
selector.ForceSet(proxyName)
|
||||||
|
} else {
|
||||||
|
err = selector.Set(proxyName)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
log.Infoln("[SelectAble] %s selected %s", groupName, proxyName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getTraffic
|
||||||
|
func getTraffic() *C.char {
|
||||||
|
up, down := statistic.DefaultManager.Current(state.CurrentState.OnlyProxy)
|
||||||
|
traffic := map[string]int64{
|
||||||
|
"up": up,
|
||||||
|
"down": down,
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(traffic)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
return C.CString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getTotalTraffic
|
||||||
|
func getTotalTraffic() *C.char {
|
||||||
|
up, down := statistic.DefaultManager.Total(state.CurrentState.OnlyProxy)
|
||||||
|
traffic := map[string]int64{
|
||||||
|
"up": up,
|
||||||
|
"down": down,
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(traffic)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
return C.CString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export resetTraffic
|
||||||
|
func resetTraffic() {
|
||||||
|
statistic.DefaultManager.ResetStatistic()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export asyncTestDelay
|
||||||
|
func asyncTestDelay(s *C.char, port C.longlong) {
|
||||||
|
i := int64(port)
|
||||||
|
paramsString := C.GoString(s)
|
||||||
|
b.Go(paramsString, func() (bool, error) {
|
||||||
|
var params = &TestDelayParams{}
|
||||||
|
err := json.Unmarshal([]byte(paramsString), params)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, "")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedStatus, err := utils.NewUnsignedRanges[uint16]("")
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, "")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*time.Duration(params.Timeout))
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
proxies := tunnel.ProxiesWithProviders()
|
||||||
|
proxy := proxies[params.ProxyName]
|
||||||
|
|
||||||
|
delayData := &Delay{
|
||||||
|
Name: params.ProxyName,
|
||||||
|
}
|
||||||
|
|
||||||
|
if proxy == nil {
|
||||||
|
delayData.Value = -1
|
||||||
|
data, _ := json.Marshal(delayData)
|
||||||
|
bridge.SendToPort(i, string(data))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
delay, err := proxy.URLTest(ctx, constant.DefaultTestURL, expectedStatus)
|
||||||
|
if err != nil || delay == 0 {
|
||||||
|
delayData.Value = -1
|
||||||
|
data, _ := json.Marshal(delayData)
|
||||||
|
bridge.SendToPort(i, string(data))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
delayData.Value = int32(delay)
|
||||||
|
data, _ := json.Marshal(delayData)
|
||||||
|
bridge.SendToPort(i, string(data))
|
||||||
|
return false, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getVersionInfo
|
||||||
|
func getVersionInfo() *C.char {
|
||||||
|
versionInfo := map[string]string{
|
||||||
|
"clashName": constant.Name,
|
||||||
|
"version": "1.18.5",
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(versionInfo)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
return C.CString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getConnections
|
||||||
|
func getConnections() *C.char {
|
||||||
|
snapshot := statistic.DefaultManager.Snapshot()
|
||||||
|
data, err := json.Marshal(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
return C.CString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export closeConnections
|
||||||
|
func closeConnections() {
|
||||||
|
statistic.DefaultManager.Range(func(c statistic.Tracker) bool {
|
||||||
|
err := c.Close()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//export closeConnection
|
||||||
|
func closeConnection(id *C.char) {
|
||||||
|
connectionId := C.GoString(id)
|
||||||
|
c := statistic.DefaultManager.Get(connectionId)
|
||||||
|
if c == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_ = c.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getExternalProviders
|
||||||
|
func getExternalProviders() *C.char {
|
||||||
|
runLock.Lock()
|
||||||
|
defer runLock.Unlock()
|
||||||
|
externalProviders = getExternalProvidersRaw()
|
||||||
|
eps := make([]ExternalProvider, 0)
|
||||||
|
for _, p := range externalProviders {
|
||||||
|
externalProvider, err := toExternalProvider(p)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
eps = append(eps, *externalProvider)
|
||||||
|
}
|
||||||
|
sort.Sort(ExternalProviders(eps))
|
||||||
|
data, err := json.Marshal(eps)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
return C.CString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getExternalProvider
|
||||||
|
func getExternalProvider(name *C.char) *C.char {
|
||||||
|
runLock.Lock()
|
||||||
|
defer runLock.Unlock()
|
||||||
|
externalProviderName := C.GoString(name)
|
||||||
|
externalProvider, exist := externalProviders[externalProviderName]
|
||||||
|
if !exist {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
e, err := toExternalProvider(externalProvider)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(e)
|
||||||
|
if err != nil {
|
||||||
|
return C.CString("")
|
||||||
|
}
|
||||||
|
return C.CString(string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export updateGeoData
|
||||||
|
func updateGeoData(geoType *C.char, geoName *C.char, port C.longlong) {
|
||||||
|
i := int64(port)
|
||||||
|
geoTypeString := C.GoString(geoType)
|
||||||
|
geoNameString := C.GoString(geoName)
|
||||||
|
go func() {
|
||||||
|
path := constant.Path.Resolve(geoNameString)
|
||||||
|
switch geoTypeString {
|
||||||
|
case "MMDB":
|
||||||
|
err := updater.UpdateMMDBWithPath(path)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "ASN":
|
||||||
|
err := updater.UpdateASNWithPath(path)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "GeoIp":
|
||||||
|
err := updater.UpdateGeoIpWithPath(path)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "GeoSite":
|
||||||
|
err := updater.UpdateGeoSiteWithPath(path)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bridge.SendToPort(i, "")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export updateExternalProvider
|
||||||
|
func updateExternalProvider(providerName *C.char, port C.longlong) {
|
||||||
|
i := int64(port)
|
||||||
|
providerNameString := C.GoString(providerName)
|
||||||
|
go func() {
|
||||||
|
externalProvider, exist := externalProviders[providerNameString]
|
||||||
|
if !exist {
|
||||||
|
bridge.SendToPort(i, "external provider is not exist")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := externalProvider.Update()
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bridge.SendToPort(i, "")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export sideLoadExternalProvider
|
||||||
|
func sideLoadExternalProvider(providerName *C.char, data *C.char, port C.longlong) {
|
||||||
|
i := int64(port)
|
||||||
|
bytes := []byte(C.GoString(data))
|
||||||
|
providerNameString := C.GoString(providerName)
|
||||||
|
go func() {
|
||||||
|
externalProvider, exist := externalProviders[providerNameString]
|
||||||
|
if !exist {
|
||||||
|
bridge.SendToPort(i, "external provider is not exist")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := sideUpdateExternalProvider(externalProvider, bytes)
|
||||||
|
if err != nil {
|
||||||
|
bridge.SendToPort(i, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bridge.SendToPort(i, "")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export initNativeApiBridge
|
||||||
|
func initNativeApiBridge(api unsafe.Pointer) {
|
||||||
|
bridge.InitDartApi(api)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export initMessage
|
||||||
|
func initMessage(port C.longlong) {
|
||||||
|
i := int64(port)
|
||||||
|
Port = i
|
||||||
|
}
|
||||||
|
|
||||||
|
//export freeCString
|
||||||
|
func freeCString(s *C.char) {
|
||||||
|
C.free(unsafe.Pointer(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
provider.HealthcheckHook = func(name string, delay uint16) {
|
||||||
|
delayData := &Delay{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
if delay == 0 {
|
||||||
|
delayData.Value = -1
|
||||||
|
} else {
|
||||||
|
delayData.Value = int32(delay)
|
||||||
|
}
|
||||||
|
SendMessage(Message{
|
||||||
|
Type: DelayMessage,
|
||||||
|
Data: delayData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
statistic.DefaultRequestNotify = func(c statistic.Tracker) {
|
||||||
|
SendMessage(Message{
|
||||||
|
Type: RequestMessage,
|
||||||
|
Data: c,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
executor.DefaultProviderLoadedHook = func(providerName string) {
|
||||||
|
SendMessage(Message{
|
||||||
|
Type: LoadedMessage,
|
||||||
|
Data: providerName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ func getAndroidVpnOptions() *C.char {
|
|||||||
AccessControl: state.CurrentState.AccessControl,
|
AccessControl: state.CurrentState.AccessControl,
|
||||||
SystemProxy: state.CurrentState.SystemProxy,
|
SystemProxy: state.CurrentState.SystemProxy,
|
||||||
AllowBypass: state.CurrentState.AllowBypass,
|
AllowBypass: state.CurrentState.AllowBypass,
|
||||||
|
RouteAddress: state.CurrentState.RouteAddress,
|
||||||
BypassDomain: state.CurrentState.BypassDomain,
|
BypassDomain: state.CurrentState.BypassDomain,
|
||||||
DnsServerAddress: state.GetDnsServerAddress(),
|
DnsServerAddress: state.GetDnsServerAddress(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type AndroidVpnOptions struct {
|
|||||||
AllowBypass bool `json:"allowBypass"`
|
AllowBypass bool `json:"allowBypass"`
|
||||||
SystemProxy bool `json:"systemProxy"`
|
SystemProxy bool `json:"systemProxy"`
|
||||||
BypassDomain []string `json:"bypassDomain"`
|
BypassDomain []string `json:"bypassDomain"`
|
||||||
|
RouteAddress []string `json:"routeAddress"`
|
||||||
Ipv4Address string `json:"ipv4Address"`
|
Ipv4Address string `json:"ipv4Address"`
|
||||||
Ipv6Address string `json:"ipv6Address"`
|
Ipv6Address string `json:"ipv6Address"`
|
||||||
DnsServerAddress string `json:"dnsServerAddress"`
|
DnsServerAddress string `json:"dnsServerAddress"`
|
||||||
@@ -32,6 +33,7 @@ type AndroidVpnRawOptions struct {
|
|||||||
AccessControl *AccessControl `json:"accessControl"`
|
AccessControl *AccessControl `json:"accessControl"`
|
||||||
AllowBypass bool `json:"allowBypass"`
|
AllowBypass bool `json:"allowBypass"`
|
||||||
SystemProxy bool `json:"systemProxy"`
|
SystemProxy bool `json:"systemProxy"`
|
||||||
|
RouteAddress []string `json:"routeAddress"`
|
||||||
Ipv6 bool `json:"ipv6"`
|
Ipv6 bool `json:"ipv6"`
|
||||||
BypassDomain []string `json:"bypassDomain"`
|
BypassDomain []string `json:"bypassDomain"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ runAppWithPreferences(
|
|||||||
Widget child, {
|
Widget child, {
|
||||||
required AppState appState,
|
required AppState appState,
|
||||||
required Config config,
|
required Config config,
|
||||||
|
required AppFlowingState appFlowingState,
|
||||||
required ClashConfig clashConfig,
|
required ClashConfig clashConfig,
|
||||||
}) {
|
}) {
|
||||||
runApp(MultiProvider(
|
runApp(MultiProvider(
|
||||||
@@ -30,7 +31,7 @@ runAppWithPreferences(
|
|||||||
create: (_) => config,
|
create: (_) => config,
|
||||||
),
|
),
|
||||||
ChangeNotifierProvider<AppFlowingState>(
|
ChangeNotifierProvider<AppFlowingState>(
|
||||||
create: (_) => AppFlowingState(),
|
create: (_) => appFlowingState,
|
||||||
),
|
),
|
||||||
ChangeNotifierProxyProvider2<Config, ClashConfig, AppState>(
|
ChangeNotifierProxyProvider2<Config, ClashConfig, AppState>(
|
||||||
create: (_) => appState,
|
create: (_) => appState,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ 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/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
|
|
||||||
import 'generated/clash_ffi.dart';
|
import 'generated/clash_ffi.dart';
|
||||||
|
|
||||||
class ClashCore {
|
class ClashCore {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@ extension ColorSchemeExtension on ColorScheme {
|
|||||||
ColorScheme toPrueBlack(bool isPrueBlack) => isPrueBlack
|
ColorScheme toPrueBlack(bool isPrueBlack) => isPrueBlack
|
||||||
? copyWith(
|
? copyWith(
|
||||||
surface: Colors.black,
|
surface: Colors.black,
|
||||||
background: Colors.black,
|
|
||||||
surfaceContainer: surfaceContainer.darken(0.05),
|
surfaceContainer: surfaceContainer.darken(0.05),
|
||||||
)
|
)
|
||||||
: this;
|
: this;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:app_links/app_links.dart';
|
import 'package:app_links/app_links.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
typedef InstallConfigCallBack = void Function(String url);
|
typedef InstallConfigCallBack = void Function(String url);
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ class LinkManager {
|
|||||||
initAppLinksListen(installConfigCallBack) async {
|
initAppLinksListen(installConfigCallBack) async {
|
||||||
debugPrint("initAppLinksListen");
|
debugPrint("initAppLinksListen");
|
||||||
destroy();
|
destroy();
|
||||||
subscription = _appLinks.allUriLinkStream.listen(
|
subscription = _appLinks.uriLinkStream.listen(
|
||||||
(uri) {
|
(uri) {
|
||||||
debugPrint('onAppLink: $uri');
|
debugPrint('onAppLink: $uri');
|
||||||
if (uri.host == 'install-config') {
|
if (uri.host == 'install-config') {
|
||||||
@@ -31,8 +31,7 @@ class LinkManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
destroy(){
|
|
||||||
if (subscription != null) {
|
if (subscription != null) {
|
||||||
subscription?.cancel();
|
subscription?.cancel();
|
||||||
subscription = null;
|
subscription = null;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/models/config.dart';
|
import 'package:fl_clash/models/config.dart';
|
||||||
@@ -7,9 +6,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
import 'package:windows_single_instance/windows_single_instance.dart';
|
import 'package:windows_single_instance/windows_single_instance.dart';
|
||||||
|
|
||||||
import 'protocol.dart';
|
|
||||||
import 'system.dart';
|
|
||||||
|
|
||||||
class Window {
|
class Window {
|
||||||
init(WindowProps props, int version) async {
|
init(WindowProps props, int version) async {
|
||||||
if (Platform.isWindows) {
|
if (Platform.isWindows) {
|
||||||
|
|||||||
@@ -9,15 +9,13 @@ import 'package:fl_clash/common/archive.dart';
|
|||||||
import 'package:fl_clash/enum/enum.dart';
|
import 'package:fl_clash/enum/enum.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:intl/intl.dart';
|
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tray_manager/tray_manager.dart';
|
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import 'clash/core.dart';
|
import 'clash/core.dart';
|
||||||
import 'models/models.dart';
|
|
||||||
import 'common/common.dart';
|
import 'common/common.dart';
|
||||||
|
import 'models/models.dart';
|
||||||
|
|
||||||
class AppController {
|
class AppController {
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
@@ -116,6 +114,10 @@ class AppController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateProviders() {
|
||||||
|
globalState.updateProviders(appState);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> updateProfile(Profile profile) async {
|
Future<void> updateProfile(Profile profile) async {
|
||||||
final newProfile = await profile.update();
|
final newProfile = await profile.update();
|
||||||
config.setProfile(
|
config.setProfile(
|
||||||
@@ -530,8 +532,8 @@ class AppController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateSystemProxy() {
|
updateSystemProxy() {
|
||||||
config.desktopProps = config.desktopProps.copyWith(
|
config.networkProps = config.networkProps.copyWith(
|
||||||
systemProxy: !config.desktopProps.systemProxy,
|
systemProxy: !config.networkProps.systemProxy,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,121 +601,14 @@ class AppController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _updateSystemTray({
|
|
||||||
required Brightness? brightness,
|
|
||||||
bool force = false,
|
|
||||||
}) async {
|
|
||||||
if (Platform.isLinux || force) {
|
|
||||||
await trayManager.destroy();
|
|
||||||
}
|
|
||||||
await trayManager.setIcon(
|
|
||||||
other.getTrayIconPath(
|
|
||||||
brightness: brightness ??
|
|
||||||
WidgetsBinding.instance.platformDispatcher.platformBrightness,
|
|
||||||
),
|
|
||||||
isTemplate: true,
|
|
||||||
);
|
|
||||||
if (!Platform.isLinux) {
|
|
||||||
await trayManager.setToolTip(
|
|
||||||
appName,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTray([bool focus = false]) async {
|
updateTray([bool focus = false]) async {
|
||||||
if (!Platform.isLinux) {
|
globalState.updateTray(
|
||||||
await _updateSystemTray(
|
appState: appState,
|
||||||
brightness: appState.brightness,
|
appFlowingState: appFlowingState,
|
||||||
force: focus,
|
config: config,
|
||||||
);
|
clashConfig: clashConfig,
|
||||||
}
|
focus: focus,
|
||||||
List<MenuItem> menuItems = [];
|
|
||||||
final showMenuItem = MenuItem(
|
|
||||||
label: appLocalizations.show,
|
|
||||||
onClick: (_) {
|
|
||||||
window?.show();
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
menuItems.add(showMenuItem);
|
|
||||||
final startMenuItem = MenuItem.checkbox(
|
|
||||||
label: appFlowingState.isStart
|
|
||||||
? appLocalizations.stop
|
|
||||||
: appLocalizations.start,
|
|
||||||
onClick: (_) async {
|
|
||||||
globalState.appController.updateStart();
|
|
||||||
},
|
|
||||||
checked: false,
|
|
||||||
);
|
|
||||||
menuItems.add(startMenuItem);
|
|
||||||
menuItems.add(MenuItem.separator());
|
|
||||||
for (final mode in Mode.values) {
|
|
||||||
menuItems.add(
|
|
||||||
MenuItem.checkbox(
|
|
||||||
label: Intl.message(mode.name),
|
|
||||||
onClick: (_) {
|
|
||||||
globalState.appController.clashConfig.mode = mode;
|
|
||||||
},
|
|
||||||
checked: mode == clashConfig.mode,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
menuItems.add(MenuItem.separator());
|
|
||||||
if (appFlowingState.isStart) {
|
|
||||||
menuItems.add(
|
|
||||||
MenuItem.checkbox(
|
|
||||||
label: appLocalizations.tun,
|
|
||||||
onClick: (_) {
|
|
||||||
globalState.appController.updateTun();
|
|
||||||
},
|
|
||||||
checked: clashConfig.tun.enable,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
menuItems.add(
|
|
||||||
MenuItem.checkbox(
|
|
||||||
label: appLocalizations.systemProxy,
|
|
||||||
onClick: (_) {
|
|
||||||
globalState.appController.updateSystemProxy();
|
|
||||||
},
|
|
||||||
checked: config.desktopProps.systemProxy,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
menuItems.add(MenuItem.separator());
|
|
||||||
}
|
|
||||||
final autoStartMenuItem = MenuItem.checkbox(
|
|
||||||
label: appLocalizations.autoLaunch,
|
|
||||||
onClick: (_) async {
|
|
||||||
globalState.appController.updateAutoLaunch();
|
|
||||||
},
|
|
||||||
checked: config.appSetting.autoLaunch,
|
|
||||||
);
|
|
||||||
menuItems.add(autoStartMenuItem);
|
|
||||||
|
|
||||||
if(Platform.isWindows){
|
|
||||||
final adminAutoStartMenuItem = MenuItem.checkbox(
|
|
||||||
label: appLocalizations.adminAutoLaunch,
|
|
||||||
onClick: (_) async {
|
|
||||||
globalState.appController.updateAdminAutoLaunch();
|
|
||||||
},
|
|
||||||
checked: config.appSetting.adminAutoLaunch,
|
|
||||||
);
|
|
||||||
menuItems.add(adminAutoStartMenuItem);
|
|
||||||
}
|
|
||||||
menuItems.add(MenuItem.separator());
|
|
||||||
final exitMenuItem = MenuItem(
|
|
||||||
label: appLocalizations.exit,
|
|
||||||
onClick: (_) async {
|
|
||||||
await globalState.appController.handleExit();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
menuItems.add(exitMenuItem);
|
|
||||||
final menu = Menu(items: menuItems);
|
|
||||||
await trayManager.setContextMenu(menu);
|
|
||||||
if (Platform.isLinux) {
|
|
||||||
await _updateSystemTray(
|
|
||||||
brightness: appState.brightness,
|
|
||||||
force: focus,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
recoveryData(
|
recoveryData(
|
||||||
|
|||||||
@@ -173,3 +173,8 @@ enum FontFamily {
|
|||||||
|
|
||||||
const FontFamily([this.value]);
|
const FontFamily([this.value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum RouteMode {
|
||||||
|
bypassPrivate,
|
||||||
|
config,
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class _ConfigFragmentState extends State<ConfigFragment> {
|
|||||||
title: appLocalizations.network,
|
title: appLocalizations.network,
|
||||||
isScaffold: true,
|
isScaffold: true,
|
||||||
isBlur: false,
|
isBlur: false,
|
||||||
|
extendPageWidth: 360,
|
||||||
widget: const NetworkListView(),
|
widget: const NetworkListView(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ import 'package:fl_clash/models/models.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:intl/intl.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class VPNSwitch extends StatelessWidget {
|
class VPNItem extends StatelessWidget {
|
||||||
const VPNSwitch({super.key});
|
const VPNItem({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -39,8 +40,8 @@ class TUNItem extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Selector<Config, bool>(
|
return Selector<ClashConfig, bool>(
|
||||||
selector: (_, config) => config.vpnProps.enable,
|
selector: (_, clashConfig) => clashConfig.tun.enable,
|
||||||
builder: (_, enable, __) {
|
builder: (_, enable, __) {
|
||||||
return ListItem.switchItem(
|
return ListItem.switchItem(
|
||||||
title: Text(appLocalizations.tun),
|
title: Text(appLocalizations.tun),
|
||||||
@@ -60,8 +61,8 @@ class TUNItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AllowBypassSwitch extends StatelessWidget {
|
class AllowBypassItem extends StatelessWidget {
|
||||||
const AllowBypassSwitch({super.key});
|
const AllowBypassItem({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -87,8 +88,8 @@ class AllowBypassSwitch extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SystemProxySwitch extends StatelessWidget {
|
class VpnSystemProxyItem extends StatelessWidget {
|
||||||
const SystemProxySwitch({super.key});
|
const VpnSystemProxyItem({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -114,8 +115,35 @@ class SystemProxySwitch extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Ipv6Switch extends StatelessWidget {
|
class SystemProxyItem extends StatelessWidget {
|
||||||
const Ipv6Switch({super.key});
|
const SystemProxyItem({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Selector<Config, bool>(
|
||||||
|
selector: (_, config) => config.networkProps.systemProxy,
|
||||||
|
builder: (_, systemProxy, __) {
|
||||||
|
return ListItem.switchItem(
|
||||||
|
title: Text(appLocalizations.systemProxy),
|
||||||
|
subtitle: Text(appLocalizations.systemProxyDesc),
|
||||||
|
delegate: SwitchDelegate(
|
||||||
|
value: systemProxy,
|
||||||
|
onChanged: (bool value) async {
|
||||||
|
final config = globalState.appController.config;
|
||||||
|
final networkProps = config.networkProps;
|
||||||
|
config.networkProps = networkProps.copyWith(
|
||||||
|
systemProxy: value,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Ipv6Item extends StatelessWidget {
|
||||||
|
const Ipv6Item({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -176,6 +204,36 @@ class TunStackItem extends StatelessWidget {
|
|||||||
class BypassDomainItem extends StatelessWidget {
|
class BypassDomainItem extends StatelessWidget {
|
||||||
const BypassDomainItem({super.key});
|
const BypassDomainItem({super.key});
|
||||||
|
|
||||||
|
_initActions(BuildContext context) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
|
final commonScaffoldState =
|
||||||
|
context.findAncestorStateOfType<CommonScaffoldState>();
|
||||||
|
commonScaffoldState?.actions = [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
globalState.showMessage(
|
||||||
|
title: appLocalizations.reset,
|
||||||
|
message: TextSpan(
|
||||||
|
text: appLocalizations.resetTip,
|
||||||
|
),
|
||||||
|
onTab: () {
|
||||||
|
final config = globalState.appController.config;
|
||||||
|
config.networkProps = config.networkProps.copyWith(
|
||||||
|
bypassDomain: defaultBypassDomain,
|
||||||
|
);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
tooltip: appLocalizations.reset,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.replay,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListItem.open(
|
return ListItem.open(
|
||||||
@@ -183,19 +241,20 @@ class BypassDomainItem extends StatelessWidget {
|
|||||||
subtitle: Text(appLocalizations.bypassDomainDesc),
|
subtitle: Text(appLocalizations.bypassDomainDesc),
|
||||||
delegate: OpenDelegate(
|
delegate: OpenDelegate(
|
||||||
isBlur: false,
|
isBlur: false,
|
||||||
|
isScaffold: true,
|
||||||
title: appLocalizations.bypassDomain,
|
title: appLocalizations.bypassDomain,
|
||||||
widget: Selector<Config, List<String>>(
|
widget: Selector<Config, List<String>>(
|
||||||
selector: (_, config) => config.vpnProps.bypassDomain,
|
selector: (_, config) => config.networkProps.bypassDomain,
|
||||||
shouldRebuild: (prev, next) =>
|
shouldRebuild: (prev, next) => !stringListEquality.equals(prev, next),
|
||||||
!stringListEquality.equals(prev, next),
|
builder: (context, bypassDomain, __) {
|
||||||
builder: (_, bypassDomain, __) {
|
_initActions(context);
|
||||||
return ListPage(
|
return ListPage(
|
||||||
title: appLocalizations.bypassDomain,
|
title: appLocalizations.bypassDomain,
|
||||||
items: bypassDomain,
|
items: bypassDomain,
|
||||||
titleBuilder: (item) => Text(item),
|
titleBuilder: (item) => Text(item),
|
||||||
onChange: (items){
|
onChange: (items) {
|
||||||
final config = globalState.appController.config;
|
final config = globalState.appController.config;
|
||||||
config.vpnProps = config.vpnProps.copyWith(
|
config.networkProps = config.networkProps.copyWith(
|
||||||
bypassDomain: List.from(items),
|
bypassDomain: List.from(items),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -208,22 +267,108 @@ class BypassDomainItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RouteModeItem extends StatelessWidget {
|
||||||
|
const RouteModeItem({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Selector<ClashConfig, RouteMode>(
|
||||||
|
selector: (_, clashConfig) => clashConfig.routeMode,
|
||||||
|
builder: (_, value, __) {
|
||||||
|
return ListItem<RouteMode>.options(
|
||||||
|
title: Text(appLocalizations.routeMode),
|
||||||
|
subtitle: Text(Intl.message("routeMode_${value.name}")),
|
||||||
|
delegate: OptionsDelegate<RouteMode>(
|
||||||
|
title: appLocalizations.routeMode,
|
||||||
|
options: RouteMode.values,
|
||||||
|
onChanged: (RouteMode? value) {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final appController = globalState.appController;
|
||||||
|
appController.clashConfig.routeMode = value;
|
||||||
|
},
|
||||||
|
textBuilder: (routeMode) => Intl.message(
|
||||||
|
"routeMode_${routeMode.name}",
|
||||||
|
),
|
||||||
|
value: value,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RouteAddressItem extends StatelessWidget {
|
||||||
|
const RouteAddressItem({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Selector<ClashConfig, bool>(
|
||||||
|
selector: (_, clashConfig) => clashConfig.routeMode == RouteMode.config,
|
||||||
|
builder: (_, value, child) {
|
||||||
|
if (value) {
|
||||||
|
return child!;
|
||||||
|
}
|
||||||
|
return Container();
|
||||||
|
},
|
||||||
|
child: ListItem.open(
|
||||||
|
title: Text(appLocalizations.routeAddress),
|
||||||
|
subtitle: Text(appLocalizations.routeAddressDesc),
|
||||||
|
delegate: OpenDelegate(
|
||||||
|
isBlur: false,
|
||||||
|
isScaffold: true,
|
||||||
|
title: appLocalizations.routeAddress,
|
||||||
|
widget: Selector<ClashConfig, List<String>>(
|
||||||
|
selector: (_, clashConfig) => clashConfig.includeRouteAddress,
|
||||||
|
shouldRebuild: (prev, next) =>
|
||||||
|
!stringListEquality.equals(prev, next),
|
||||||
|
builder: (context, routeAddress, __) {
|
||||||
|
return ListPage(
|
||||||
|
title: appLocalizations.routeAddress,
|
||||||
|
items: routeAddress,
|
||||||
|
titleBuilder: (item) => Text(item),
|
||||||
|
onChange: (items) {
|
||||||
|
final clashConfig = globalState.appController.clashConfig;
|
||||||
|
clashConfig.includeRouteAddress =
|
||||||
|
Set<String>.from(items).toList();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
extendPageWidth: 360,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final networkItems = [
|
final networkItems = [
|
||||||
Platform.isAndroid ? const VPNSwitch() : const TUNItem(),
|
if (Platform.isAndroid) const VPNItem(),
|
||||||
if (Platform.isAndroid)
|
if (Platform.isAndroid)
|
||||||
...generateSection(
|
...generateSection(
|
||||||
title: "VPN",
|
title: "VPN",
|
||||||
items: [
|
items: [
|
||||||
const SystemProxySwitch(),
|
const SystemProxyItem(),
|
||||||
const AllowBypassSwitch(),
|
const AllowBypassItem(),
|
||||||
const Ipv6Switch(),
|
const Ipv6Item(),
|
||||||
const BypassDomainItem(),
|
],
|
||||||
|
),
|
||||||
|
if (system.isDesktop)
|
||||||
|
...generateSection(
|
||||||
|
title: appLocalizations.system,
|
||||||
|
items: [
|
||||||
|
SystemProxyItem(),
|
||||||
|
BypassDomainItem(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
...generateSection(
|
...generateSection(
|
||||||
title: appLocalizations.options,
|
title: appLocalizations.options,
|
||||||
items: [
|
items: [
|
||||||
|
if (system.isDesktop) const TUNItem(),
|
||||||
const TunStackItem(),
|
const TunStackItem(),
|
||||||
|
const RouteModeItem(),
|
||||||
|
const RouteAddressItem(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
import 'package:fl_clash/fragments/dashboard/intranet_ip.dart';
|
import 'package:fl_clash/fragments/dashboard/intranet_ip.dart';
|
||||||
import 'package:fl_clash/fragments/dashboard/status_switch.dart';
|
import 'package:fl_clash/fragments/dashboard/status_button.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:fl_clash/widgets/widgets.dart';
|
import 'package:fl_clash/widgets/widgets.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'network_detection.dart';
|
import 'network_detection.dart';
|
||||||
|
import 'network_speed.dart';
|
||||||
import 'outbound_mode.dart';
|
import 'outbound_mode.dart';
|
||||||
import 'start_button.dart';
|
import 'start_button.dart';
|
||||||
import 'network_speed.dart';
|
|
||||||
import 'traffic_usage.dart';
|
import 'traffic_usage.dart';
|
||||||
|
|
||||||
class DashboardFragment extends StatefulWidget {
|
class DashboardFragment extends StatefulWidget {
|
||||||
@@ -22,7 +24,7 @@ class DashboardFragment extends StatefulWidget {
|
|||||||
|
|
||||||
class _DashboardFragmentState extends State<DashboardFragment> {
|
class _DashboardFragmentState extends State<DashboardFragment> {
|
||||||
_initFab(bool isCurrent) {
|
_initFab(bool isCurrent) {
|
||||||
if(!isCurrent){
|
if (!isCurrent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
@@ -66,13 +68,14 @@ class _DashboardFragmentState extends State<DashboardFragment> {
|
|||||||
// child: const VPNSwitch(),
|
// child: const VPNSwitch(),
|
||||||
// ),
|
// ),
|
||||||
if (system.isDesktop) ...[
|
if (system.isDesktop) ...[
|
||||||
|
if (Platform.isWindows)
|
||||||
|
GridItem(
|
||||||
|
crossAxisCellCount: switchCount,
|
||||||
|
child: const TUNButton(),
|
||||||
|
),
|
||||||
GridItem(
|
GridItem(
|
||||||
crossAxisCellCount: switchCount,
|
crossAxisCellCount: switchCount,
|
||||||
child: const TUNSwitch(),
|
child: const SystemProxyButton(),
|
||||||
),
|
|
||||||
GridItem(
|
|
||||||
crossAxisCellCount: switchCount,
|
|
||||||
child: const ProxySwitch(),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const GridItem(
|
const GridItem(
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
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:fl_clash/widgets/widgets.dart';
|
import 'package:fl_clash/widgets/widgets.dart';
|
||||||
@@ -14,14 +16,14 @@ class IntranetIP extends StatefulWidget {
|
|||||||
|
|
||||||
class _IntranetIPState extends State<IntranetIP> {
|
class _IntranetIPState extends State<IntranetIP> {
|
||||||
final ipNotifier = ValueNotifier<String?>("");
|
final ipNotifier = ValueNotifier<String?>("");
|
||||||
|
late StreamSubscription subscription;
|
||||||
|
|
||||||
Future<String> getNetworkType() async {
|
Future<String> getNetworkType() async {
|
||||||
try {
|
try {
|
||||||
List<NetworkInterface> interfaces = await NetworkInterface.list(
|
final interfaces = await NetworkInterface.list(
|
||||||
includeLoopback: false,
|
includeLoopback: false,
|
||||||
type: InternetAddressType.any,
|
type: InternetAddressType.any,
|
||||||
);
|
);
|
||||||
|
|
||||||
for (var interface in interfaces) {
|
for (var interface in interfaces) {
|
||||||
if (interface.name.toLowerCase().contains('wlan') ||
|
if (interface.name.toLowerCase().contains('wlan') ||
|
||||||
interface.name.toLowerCase().contains('wi-fi')) {
|
interface.name.toLowerCase().contains('wi-fi')) {
|
||||||
@@ -33,7 +35,6 @@ class _IntranetIPState extends State<IntranetIP> {
|
|||||||
return 'Mobile Data';
|
return 'Mobile Data';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Unknown';
|
return 'Unknown';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return 'Error';
|
return 'Error';
|
||||||
@@ -41,6 +42,7 @@ class _IntranetIPState extends State<IntranetIP> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLocalIpAddress() async {
|
Future<String?> getLocalIpAddress() async {
|
||||||
|
await Future.delayed(animateDuration);
|
||||||
List<NetworkInterface> interfaces = await NetworkInterface.list(
|
List<NetworkInterface> interfaces = await NetworkInterface.list(
|
||||||
includeLoopback: false,
|
includeLoopback: false,
|
||||||
)
|
)
|
||||||
@@ -66,15 +68,14 @@ class _IntranetIPState extends State<IntranetIP> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
ipNotifier.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
subscription = Connectivity().onConnectivityChanged.listen((_) async {
|
||||||
|
ipNotifier.value = null;
|
||||||
|
debugPrint("[App] Connection change");
|
||||||
|
ipNotifier.value = await getLocalIpAddress() ?? "";
|
||||||
|
});
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
ipNotifier.value = await getLocalIpAddress() ?? "";
|
ipNotifier.value = await getLocalIpAddress() ?? "";
|
||||||
});
|
});
|
||||||
@@ -104,7 +105,9 @@ class _IntranetIPState extends State<IntranetIP> {
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
child: TooltipText(
|
child: TooltipText(
|
||||||
text: Text(
|
text: Text(
|
||||||
value.isNotEmpty ? value : appLocalizations.noNetwork,
|
value.isNotEmpty
|
||||||
|
? value
|
||||||
|
: appLocalizations.noNetwork,
|
||||||
style: context
|
style: context
|
||||||
.textTheme.titleLarge?.toSoftBold.toMinus,
|
.textTheme.titleLarge?.toSoftBold.toMinus,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
@@ -127,4 +130,11 @@ class _IntranetIPState extends State<IntranetIP> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
subscription.cancel();
|
||||||
|
ipNotifier.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,33 @@
|
|||||||
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: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:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
// class VPNSwitch extends StatelessWidget {
|
import '../config/network.dart';
|
||||||
// const VPNSwitch({super.key});
|
|
||||||
//
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// return SwitchContainer(
|
|
||||||
// info: const Info(
|
|
||||||
// label: "VPN",
|
|
||||||
// iconData: Icons.stacked_line_chart,
|
|
||||||
// ),
|
|
||||||
// child: Selector<Config, bool>(
|
|
||||||
// selector: (_, config) => config.vpnProps.enable,
|
|
||||||
// builder: (_, enable, __) {
|
|
||||||
// return Switch(
|
|
||||||
// materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
|
||||||
// value: enable,
|
|
||||||
// onChanged: (value) {
|
|
||||||
// final config = globalState.appController.config;
|
|
||||||
// config.vpnProps = config.vpnProps.copyWith(
|
|
||||||
// enable: value,
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
class TUNSwitch extends StatelessWidget {
|
class TUNButton extends StatelessWidget {
|
||||||
const TUNSwitch({super.key});
|
const TUNButton({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SwitchContainer(
|
return ButtonContainer(
|
||||||
|
onPressed: () {
|
||||||
|
showSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (_) {
|
||||||
|
return generateListView(generateSection(
|
||||||
|
items: [
|
||||||
|
if (system.isDesktop) const TUNItem(),
|
||||||
|
const TunStackItem(),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
},
|
||||||
|
title: appLocalizations.tun,
|
||||||
|
);
|
||||||
|
},
|
||||||
info: Info(
|
info: Info(
|
||||||
label: appLocalizations.tun,
|
label: appLocalizations.tun,
|
||||||
iconData: Icons.stacked_line_chart,
|
iconData: Icons.stacked_line_chart,
|
||||||
@@ -64,18 +52,34 @@ class TUNSwitch extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProxySwitch extends StatelessWidget {
|
class SystemProxyButton extends StatelessWidget {
|
||||||
const ProxySwitch({super.key});
|
const SystemProxyButton({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SwitchContainer(
|
return ButtonContainer(
|
||||||
|
onPressed: () {
|
||||||
|
showSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (_) {
|
||||||
|
return generateListView(
|
||||||
|
generateSection(
|
||||||
|
items: [
|
||||||
|
SystemProxyItem(),
|
||||||
|
BypassDomainItem(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
title: appLocalizations.systemProxy,
|
||||||
|
);
|
||||||
|
},
|
||||||
info: Info(
|
info: Info(
|
||||||
label: appLocalizations.systemProxy,
|
label: appLocalizations.systemProxy,
|
||||||
iconData: Icons.shuffle,
|
iconData: Icons.shuffle,
|
||||||
),
|
),
|
||||||
child: Selector<Config, bool>(
|
child: Selector<Config, bool>(
|
||||||
selector: (_, config) => config.desktopProps.systemProxy,
|
selector: (_, config) => config.networkProps.systemProxy,
|
||||||
builder: (_, systemProxy, __) {
|
builder: (_, systemProxy, __) {
|
||||||
return LocaleBuilder(
|
return LocaleBuilder(
|
||||||
builder: (_) => Switch(
|
builder: (_) => Switch(
|
||||||
@@ -83,8 +87,8 @@ class ProxySwitch extends StatelessWidget {
|
|||||||
value: systemProxy,
|
value: systemProxy,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
final config = globalState.appController.config;
|
final config = globalState.appController.config;
|
||||||
config.desktopProps =
|
config.networkProps =
|
||||||
config.desktopProps.copyWith(systemProxy: value);
|
config.networkProps.copyWith(systemProxy: value);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -94,20 +98,22 @@ class ProxySwitch extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SwitchContainer extends StatelessWidget {
|
class ButtonContainer extends StatelessWidget {
|
||||||
final Info info;
|
final Info info;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
final VoidCallback onPressed;
|
||||||
|
|
||||||
const SwitchContainer({
|
const ButtonContainer({
|
||||||
super.key,
|
super.key,
|
||||||
required this.info,
|
required this.info,
|
||||||
required this.child,
|
required this.child,
|
||||||
|
required this.onPressed,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return CommonCard(
|
return CommonCard(
|
||||||
onPressed: () {},
|
onPressed: onPressed,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
|
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/fragments/profiles/edit_profile.dart';
|
import 'package:fl_clash/fragments/profiles/edit_profile.dart';
|
||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:fl_clash/common/common.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';
|
||||||
@@ -127,8 +127,8 @@ class _ProfilesFragmentState extends State<ProfilesFragment> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ActiveBuilder(
|
return ActiveBuilder(
|
||||||
label: "profiles",
|
label: "profiles",
|
||||||
builder: (isCurrent,child){
|
builder: (isCurrent, child) {
|
||||||
if(isCurrent){
|
if (isCurrent) {
|
||||||
_initScaffold();
|
_initScaffold();
|
||||||
}
|
}
|
||||||
return child!;
|
return child!;
|
||||||
@@ -246,44 +246,16 @@ class ProfileItem extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _buildUserInfo(BuildContext context, UserInfo userInfo) {
|
|
||||||
final use = userInfo.upload + userInfo.download;
|
|
||||||
final total = userInfo.total;
|
|
||||||
if (total == 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
final useShow = TrafficValue(value: use).show;
|
|
||||||
final totalShow = TrafficValue(value: total).show;
|
|
||||||
final progress = total == 0 ? 0.0 : use / total;
|
|
||||||
final expireShow = userInfo.expire == 0
|
|
||||||
? appLocalizations.infiniteTime
|
|
||||||
: DateTime.fromMillisecondsSinceEpoch(userInfo.expire * 1000).show;
|
|
||||||
return [
|
|
||||||
LinearProgressIndicator(
|
|
||||||
minHeight: 6,
|
|
||||||
value: progress,
|
|
||||||
backgroundColor: context.colorScheme.primary.toSoft(),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 8,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"$useShow / $totalShow · $expireShow",
|
|
||||||
style: context.textTheme.labelMedium?.toLight,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 4,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> _buildUrlProfileInfo(BuildContext context) {
|
List<Widget> _buildUrlProfileInfo(BuildContext context) {
|
||||||
final userInfo = profile.userInfo;
|
final subscriptionInfo = profile.subscriptionInfo;
|
||||||
return [
|
return [
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
if (userInfo != null) ..._buildUserInfo(context, userInfo),
|
if (subscriptionInfo != null)
|
||||||
|
SubscriptionInfoView(
|
||||||
|
subscriptionInfo: subscriptionInfo,
|
||||||
|
),
|
||||||
Text(
|
Text(
|
||||||
profile.lastUpdateDate?.lastUpdateTimeDesc ?? "",
|
profile.lastUpdateDate?.lastUpdateTimeDesc ?? "",
|
||||||
style: context.textTheme.labelMedium?.toLight,
|
style: context.textTheme.labelMedium?.toLight,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class _ProxiesListFragmentState extends State<ProxiesListFragment> {
|
|||||||
}
|
}
|
||||||
_headerStateNotifier.value = _headerStateNotifier.value.copyWith(
|
_headerStateNotifier.value = _headerStateNotifier.value.copyWith(
|
||||||
currentIndex: currentIndex,
|
currentIndex: currentIndex,
|
||||||
offset: headerOffset,
|
offset: max(headerOffset, 0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,6 +299,9 @@ class _ProxiesListFragmentState extends State<ProxiesListFragment> {
|
|||||||
headerState.currentIndex > state.groupNames.length - 1
|
headerState.currentIndex > state.groupNames.length - 1
|
||||||
? 0
|
? 0
|
||||||
: headerState.currentIndex;
|
: headerState.currentIndex;
|
||||||
|
if (index < 0) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
@@ -417,9 +420,9 @@ class _ListHeaderState extends State<ListHeader>
|
|||||||
final iconMapEntryList =
|
final iconMapEntryList =
|
||||||
config.proxiesStyle.iconMap.entries.toList();
|
config.proxiesStyle.iconMap.entries.toList();
|
||||||
final index = iconMapEntryList.indexWhere((item) {
|
final index = iconMapEntryList.indexWhere((item) {
|
||||||
try{
|
try {
|
||||||
return RegExp(item.key).hasMatch(groupName);
|
return RegExp(item.key).hasMatch(groupName);
|
||||||
}catch(_){
|
} catch (_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -468,7 +471,7 @@ class _ListHeaderState extends State<ListHeader>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return CommonCard(
|
return CommonCard(
|
||||||
key: widget.key,
|
key: widget.key,
|
||||||
radius: 24,
|
radius: 18,
|
||||||
type: CommonCardType.filled,
|
type: CommonCardType.filled,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class _ProvidersState extends State<Providers> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addPostFrameCallback(
|
WidgetsBinding.instance.addPostFrameCallback(
|
||||||
(_) {
|
(_) {
|
||||||
|
globalState.appController.updateProviders();
|
||||||
final commonScaffoldState =
|
final commonScaffoldState =
|
||||||
context.findAncestorStateOfType<CommonScaffoldState>();
|
context.findAncestorStateOfType<CommonScaffoldState>();
|
||||||
commonScaffoldState?.actions = [
|
commonScaffoldState?.actions = [
|
||||||
@@ -132,8 +133,8 @@ class ProviderItem extends StatelessWidget {
|
|||||||
final platformFile = await picker.pickerFile();
|
final platformFile = await picker.pickerFile();
|
||||||
final appState = globalState.appController.appState;
|
final appState = globalState.appController.appState;
|
||||||
final bytes = platformFile?.bytes;
|
final bytes = platformFile?.bytes;
|
||||||
if (bytes == null) return;
|
if (bytes == null || provider.path == null) return;
|
||||||
final file = await File(provider.path).create(recursive: true);
|
final file = await File(provider.path!).create(recursive: true);
|
||||||
await file.writeAsBytes(bytes);
|
await file.writeAsBytes(bytes);
|
||||||
final providerName = provider.name;
|
final providerName = provider.name;
|
||||||
var message = await clashCore.sideLoadExternalProvider(
|
var message = await clashCore.sideLoadExternalProvider(
|
||||||
@@ -150,8 +151,7 @@ class ProviderItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _buildProviderDesc() {
|
String _buildProviderDesc() {
|
||||||
final baseInfo =
|
final baseInfo = provider.updateAt.lastUpdateTimeDesc;
|
||||||
"${provider.type}(${provider.vehicleType}) · ${provider.updateAt.lastUpdateTimeDesc}";
|
|
||||||
final count = provider.count;
|
final count = provider.count;
|
||||||
return switch (count == 0) {
|
return switch (count == 0) {
|
||||||
true => baseInfo,
|
true => baseInfo,
|
||||||
@@ -176,10 +176,13 @@ class ProviderItem extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
_buildProviderDesc(),
|
_buildProviderDesc(),
|
||||||
),
|
),
|
||||||
Text(
|
const SizedBox(
|
||||||
provider.path,
|
height: 4,
|
||||||
style: context.textTheme.bodyMedium?.toLight,
|
|
||||||
),
|
),
|
||||||
|
if (provider.subscriptionInfo != null)
|
||||||
|
SubscriptionInfoView(
|
||||||
|
subscriptionInfo: provider.subscriptionInfo,
|
||||||
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
@@ -200,6 +203,9 @@ class ProviderItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
trailing: SizedBox(
|
trailing: SizedBox(
|
||||||
|
|||||||
@@ -168,6 +168,7 @@
|
|||||||
"ipv6Desc": "When turned on it will be able to receive IPv6 traffic",
|
"ipv6Desc": "When turned on it will be able to receive IPv6 traffic",
|
||||||
"app": "App",
|
"app": "App",
|
||||||
"general": "General",
|
"general": "General",
|
||||||
|
"vpnSystemProxyDesc": "Attach HTTP proxy to VpnService",
|
||||||
"systemProxyDesc": "Attach HTTP proxy to VpnService",
|
"systemProxyDesc": "Attach HTTP proxy to VpnService",
|
||||||
"unifiedDelay": "Unified delay",
|
"unifiedDelay": "Unified delay",
|
||||||
"unifiedDelayDesc": "Remove extra delays such as handshaking",
|
"unifiedDelayDesc": "Remove extra delays such as handshaking",
|
||||||
@@ -323,5 +324,11 @@
|
|||||||
"adminAutoLaunchDesc": "Boot up by using admin mode",
|
"adminAutoLaunchDesc": "Boot up by using admin mode",
|
||||||
"fontFamily": "FontFamily",
|
"fontFamily": "FontFamily",
|
||||||
"systemFont": "System font",
|
"systemFont": "System font",
|
||||||
"toggle": "Toggle"
|
"toggle": "Toggle",
|
||||||
|
"system": "System",
|
||||||
|
"routeMode": "Route mode",
|
||||||
|
"routeMode_bypassPrivate": "Bypass private route address",
|
||||||
|
"routeMode_config": "Use config",
|
||||||
|
"routeAddress": "Route address",
|
||||||
|
"routeAddressDesc": "Config listen route address"
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,8 @@
|
|||||||
"ipv6Desc": "开启后将可以接收IPv6流量",
|
"ipv6Desc": "开启后将可以接收IPv6流量",
|
||||||
"app": "应用",
|
"app": "应用",
|
||||||
"general": "基础",
|
"general": "基础",
|
||||||
"systemProxyDesc": "为VpnService附加HTTP代理",
|
"vpnSystemProxyDesc": "为VpnService附加HTTP代理",
|
||||||
|
"systemProxyDesc": "设置系统代理",
|
||||||
"unifiedDelay": "统一延迟",
|
"unifiedDelay": "统一延迟",
|
||||||
"unifiedDelayDesc": "去除握手等额外延迟",
|
"unifiedDelayDesc": "去除握手等额外延迟",
|
||||||
"tcpConcurrent": "TCP并发",
|
"tcpConcurrent": "TCP并发",
|
||||||
@@ -323,5 +324,11 @@
|
|||||||
"adminAutoLaunchDesc": "使用管理员模式开机自启动",
|
"adminAutoLaunchDesc": "使用管理员模式开机自启动",
|
||||||
"fontFamily": "字体",
|
"fontFamily": "字体",
|
||||||
"systemFont": "系统字体",
|
"systemFont": "系统字体",
|
||||||
"toggle": "切换"
|
"toggle": "切换",
|
||||||
}
|
"system": "系统",
|
||||||
|
"routeMode": "路由模式",
|
||||||
|
"routeMode_bypassPrivate": "绕过私有路由地址",
|
||||||
|
"routeMode_config": "使用配置",
|
||||||
|
"routeAddress": "路由地址",
|
||||||
|
"routeAddressDesc": "配置监听路由地址"
|
||||||
|
}
|
||||||
|
|||||||
@@ -398,6 +398,13 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"respectRules": MessageLookupByLibrary.simpleMessage("Respect rules"),
|
"respectRules": MessageLookupByLibrary.simpleMessage("Respect rules"),
|
||||||
"respectRulesDesc": MessageLookupByLibrary.simpleMessage(
|
"respectRulesDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"DNS connection following rules, need to configure proxy-server-nameserver"),
|
"DNS connection following rules, need to configure proxy-server-nameserver"),
|
||||||
|
"routeAddress": MessageLookupByLibrary.simpleMessage("Route address"),
|
||||||
|
"routeAddressDesc":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Config listen route address"),
|
||||||
|
"routeMode": MessageLookupByLibrary.simpleMessage("Route mode"),
|
||||||
|
"routeMode_bypassPrivate": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Bypass private route address"),
|
||||||
|
"routeMode_config": MessageLookupByLibrary.simpleMessage("Use config"),
|
||||||
"rule": MessageLookupByLibrary.simpleMessage("Rule"),
|
"rule": MessageLookupByLibrary.simpleMessage("Rule"),
|
||||||
"ruleProviders": MessageLookupByLibrary.simpleMessage("Rule providers"),
|
"ruleProviders": MessageLookupByLibrary.simpleMessage("Rule providers"),
|
||||||
"save": MessageLookupByLibrary.simpleMessage("Save"),
|
"save": MessageLookupByLibrary.simpleMessage("Save"),
|
||||||
@@ -426,6 +433,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"style": MessageLookupByLibrary.simpleMessage("Style"),
|
"style": MessageLookupByLibrary.simpleMessage("Style"),
|
||||||
"submit": MessageLookupByLibrary.simpleMessage("Submit"),
|
"submit": MessageLookupByLibrary.simpleMessage("Submit"),
|
||||||
"sync": MessageLookupByLibrary.simpleMessage("Sync"),
|
"sync": MessageLookupByLibrary.simpleMessage("Sync"),
|
||||||
|
"system": MessageLookupByLibrary.simpleMessage("System"),
|
||||||
"systemFont": MessageLookupByLibrary.simpleMessage("System font"),
|
"systemFont": MessageLookupByLibrary.simpleMessage("System font"),
|
||||||
"systemProxy": MessageLookupByLibrary.simpleMessage("System proxy"),
|
"systemProxy": MessageLookupByLibrary.simpleMessage("System proxy"),
|
||||||
"systemProxyDesc": MessageLookupByLibrary.simpleMessage(
|
"systemProxyDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
@@ -475,6 +483,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
MessageLookupByLibrary.simpleMessage("Modify VPN related settings"),
|
MessageLookupByLibrary.simpleMessage("Modify VPN related settings"),
|
||||||
"vpnEnableDesc": MessageLookupByLibrary.simpleMessage(
|
"vpnEnableDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"Auto routes all system traffic through VpnService"),
|
"Auto routes all system traffic through VpnService"),
|
||||||
|
"vpnSystemProxyDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Attach HTTP proxy to VpnService"),
|
||||||
"vpnTip": MessageLookupByLibrary.simpleMessage(
|
"vpnTip": MessageLookupByLibrary.simpleMessage(
|
||||||
"Changes take effect after restarting the VPN"),
|
"Changes take effect after restarting the VPN"),
|
||||||
"webDAVConfiguration":
|
"webDAVConfiguration":
|
||||||
|
|||||||
@@ -314,6 +314,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"respectRules": MessageLookupByLibrary.simpleMessage("遵守规则"),
|
"respectRules": MessageLookupByLibrary.simpleMessage("遵守规则"),
|
||||||
"respectRulesDesc": MessageLookupByLibrary.simpleMessage(
|
"respectRulesDesc": MessageLookupByLibrary.simpleMessage(
|
||||||
"DNS连接跟随rules,需配置proxy-server-nameserver"),
|
"DNS连接跟随rules,需配置proxy-server-nameserver"),
|
||||||
|
"routeAddress": MessageLookupByLibrary.simpleMessage("路由地址"),
|
||||||
|
"routeAddressDesc": MessageLookupByLibrary.simpleMessage("配置监听路由地址"),
|
||||||
|
"routeMode": MessageLookupByLibrary.simpleMessage("路由模式"),
|
||||||
|
"routeMode_bypassPrivate":
|
||||||
|
MessageLookupByLibrary.simpleMessage("绕过私有路由地址"),
|
||||||
|
"routeMode_config": MessageLookupByLibrary.simpleMessage("使用配置"),
|
||||||
"rule": MessageLookupByLibrary.simpleMessage("规则"),
|
"rule": MessageLookupByLibrary.simpleMessage("规则"),
|
||||||
"ruleProviders": MessageLookupByLibrary.simpleMessage("规则提供者"),
|
"ruleProviders": MessageLookupByLibrary.simpleMessage("规则提供者"),
|
||||||
"save": MessageLookupByLibrary.simpleMessage("保存"),
|
"save": MessageLookupByLibrary.simpleMessage("保存"),
|
||||||
@@ -340,10 +346,10 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"style": MessageLookupByLibrary.simpleMessage("风格"),
|
"style": MessageLookupByLibrary.simpleMessage("风格"),
|
||||||
"submit": MessageLookupByLibrary.simpleMessage("提交"),
|
"submit": MessageLookupByLibrary.simpleMessage("提交"),
|
||||||
"sync": MessageLookupByLibrary.simpleMessage("同步"),
|
"sync": MessageLookupByLibrary.simpleMessage("同步"),
|
||||||
|
"system": MessageLookupByLibrary.simpleMessage("系统"),
|
||||||
"systemFont": MessageLookupByLibrary.simpleMessage("系统字体"),
|
"systemFont": MessageLookupByLibrary.simpleMessage("系统字体"),
|
||||||
"systemProxy": MessageLookupByLibrary.simpleMessage("系统代理"),
|
"systemProxy": MessageLookupByLibrary.simpleMessage("系统代理"),
|
||||||
"systemProxyDesc":
|
"systemProxyDesc": MessageLookupByLibrary.simpleMessage("设置系统代理"),
|
||||||
MessageLookupByLibrary.simpleMessage("为VpnService附加HTTP代理"),
|
|
||||||
"tab": MessageLookupByLibrary.simpleMessage("标签页"),
|
"tab": MessageLookupByLibrary.simpleMessage("标签页"),
|
||||||
"tabAnimation": MessageLookupByLibrary.simpleMessage("选项卡动画"),
|
"tabAnimation": MessageLookupByLibrary.simpleMessage("选项卡动画"),
|
||||||
"tabAnimationDesc":
|
"tabAnimationDesc":
|
||||||
@@ -381,6 +387,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"vpnDesc": MessageLookupByLibrary.simpleMessage("修改VPN相关设置"),
|
"vpnDesc": MessageLookupByLibrary.simpleMessage("修改VPN相关设置"),
|
||||||
"vpnEnableDesc":
|
"vpnEnableDesc":
|
||||||
MessageLookupByLibrary.simpleMessage("通过VpnService自动路由系统所有流量"),
|
MessageLookupByLibrary.simpleMessage("通过VpnService自动路由系统所有流量"),
|
||||||
|
"vpnSystemProxyDesc":
|
||||||
|
MessageLookupByLibrary.simpleMessage("为VpnService附加HTTP代理"),
|
||||||
"vpnTip": MessageLookupByLibrary.simpleMessage("重启VPN后改变生效"),
|
"vpnTip": MessageLookupByLibrary.simpleMessage("重启VPN后改变生效"),
|
||||||
"webDAVConfiguration": MessageLookupByLibrary.simpleMessage("WebDAV配置"),
|
"webDAVConfiguration": MessageLookupByLibrary.simpleMessage("WebDAV配置"),
|
||||||
"whitelistMode": MessageLookupByLibrary.simpleMessage("白名单模式"),
|
"whitelistMode": MessageLookupByLibrary.simpleMessage("白名单模式"),
|
||||||
|
|||||||
@@ -1740,6 +1740,16 @@ class AppLocalizations {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `Attach HTTP proxy to VpnService`
|
||||||
|
String get vpnSystemProxyDesc {
|
||||||
|
return Intl.message(
|
||||||
|
'Attach HTTP proxy to VpnService',
|
||||||
|
name: 'vpnSystemProxyDesc',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// `Attach HTTP proxy to VpnService`
|
/// `Attach HTTP proxy to VpnService`
|
||||||
String get systemProxyDesc {
|
String get systemProxyDesc {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
@@ -3299,6 +3309,66 @@ class AppLocalizations {
|
|||||||
args: [],
|
args: [],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `System`
|
||||||
|
String get system {
|
||||||
|
return Intl.message(
|
||||||
|
'System',
|
||||||
|
name: 'system',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Route mode`
|
||||||
|
String get routeMode {
|
||||||
|
return Intl.message(
|
||||||
|
'Route mode',
|
||||||
|
name: 'routeMode',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Bypass private route address`
|
||||||
|
String get routeMode_bypassPrivate {
|
||||||
|
return Intl.message(
|
||||||
|
'Bypass private route address',
|
||||||
|
name: 'routeMode_bypassPrivate',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Use config`
|
||||||
|
String get routeMode_config {
|
||||||
|
return Intl.message(
|
||||||
|
'Use config',
|
||||||
|
name: 'routeMode_config',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Route address`
|
||||||
|
String get routeAddress {
|
||||||
|
return Intl.message(
|
||||||
|
'Route address',
|
||||||
|
name: 'routeAddress',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Config listen route address`
|
||||||
|
String get routeAddressDesc {
|
||||||
|
return Intl.message(
|
||||||
|
'Config listen route address',
|
||||||
|
name: 'routeAddressDesc',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {
|
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ Future<void> main() async {
|
|||||||
globalState.packageInfo = await PackageInfo.fromPlatform();
|
globalState.packageInfo = await PackageInfo.fromPlatform();
|
||||||
final version = await system.version;
|
final version = await system.version;
|
||||||
final config = await preferences.getConfig() ?? Config();
|
final config = await preferences.getConfig() ?? Config();
|
||||||
|
await AppLocalizations.load(
|
||||||
|
other.getLocaleForString(config.appSetting.locale) ??
|
||||||
|
WidgetsBinding.instance.platformDispatcher.locale,
|
||||||
|
);
|
||||||
final clashConfig = await preferences.getClashConfig() ?? ClashConfig();
|
final clashConfig = await preferences.getClashConfig() ?? ClashConfig();
|
||||||
await android?.init();
|
await android?.init();
|
||||||
await window?.init(config.windowProps, version);
|
await window?.init(config.windowProps, version);
|
||||||
@@ -27,10 +31,17 @@ Future<void> main() async {
|
|||||||
version: version,
|
version: version,
|
||||||
selectedMap: config.currentSelectedMap,
|
selectedMap: config.currentSelectedMap,
|
||||||
);
|
);
|
||||||
|
final appFlowingState = AppFlowingState();
|
||||||
appState.navigationItems = navigation.getItems(
|
appState.navigationItems = navigation.getItems(
|
||||||
openLogs: config.appSetting.openLogs,
|
openLogs: config.appSetting.openLogs,
|
||||||
hasProxies: false,
|
hasProxies: false,
|
||||||
);
|
);
|
||||||
|
globalState.updateTray(
|
||||||
|
appState: appState,
|
||||||
|
appFlowingState: appFlowingState,
|
||||||
|
config: config,
|
||||||
|
clashConfig: clashConfig,
|
||||||
|
);
|
||||||
await globalState.init(
|
await globalState.init(
|
||||||
appState: appState,
|
appState: appState,
|
||||||
config: config,
|
config: config,
|
||||||
@@ -40,6 +51,7 @@ Future<void> main() async {
|
|||||||
runAppWithPreferences(
|
runAppWithPreferences(
|
||||||
const Application(),
|
const Application(),
|
||||||
appState: appState,
|
appState: appState,
|
||||||
|
appFlowingState: appFlowingState,
|
||||||
config: config,
|
config: config,
|
||||||
clashConfig: clashConfig,
|
clashConfig: clashConfig,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.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';
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ class ClashManager extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ClashContainerState extends State<ClashManager> with AppMessageListener {
|
class _ClashContainerState extends State<ClashManager> with AppMessageListener {
|
||||||
Function? updateClashConfigDebounce;
|
|
||||||
Function? updateDelayDebounce;
|
Function? updateDelayDebounce;
|
||||||
|
|
||||||
Widget _updateContainer(Widget child) {
|
Widget _updateContainer(Widget child) {
|
||||||
@@ -47,10 +46,7 @@ class _ClashContainerState extends State<ClashManager> with AppMessageListener {
|
|||||||
),
|
),
|
||||||
shouldRebuild: (prev, next) {
|
shouldRebuild: (prev, next) {
|
||||||
if (prev != next) {
|
if (prev != next) {
|
||||||
updateClashConfigDebounce ??= debounce<Function()>(() async {
|
globalState.appController.updateClashConfigDebounce();
|
||||||
await globalState.appController.updateClashConfig();
|
|
||||||
});
|
|
||||||
updateClashConfigDebounce!();
|
|
||||||
}
|
}
|
||||||
return prev != next;
|
return prev != next;
|
||||||
},
|
},
|
||||||
@@ -68,11 +64,12 @@ class _ClashContainerState extends State<ClashManager> with AppMessageListener {
|
|||||||
accessControl: config.isAccessControl ? config.accessControl : null,
|
accessControl: config.isAccessControl ? config.accessControl : null,
|
||||||
ipv6: config.vpnProps.ipv6,
|
ipv6: config.vpnProps.ipv6,
|
||||||
allowBypass: config.vpnProps.allowBypass,
|
allowBypass: config.vpnProps.allowBypass,
|
||||||
bypassDomain: config.vpnProps.bypassDomain,
|
bypassDomain: config.networkProps.bypassDomain,
|
||||||
systemProxy: config.vpnProps.systemProxy,
|
systemProxy: config.vpnProps.systemProxy,
|
||||||
onlyProxy: config.appSetting.onlyProxy,
|
onlyProxy: config.appSetting.onlyProxy,
|
||||||
currentProfileName:
|
currentProfileName:
|
||||||
config.currentProfile?.label ?? config.currentProfileId ?? "",
|
config.currentProfile?.label ?? config.currentProfileId ?? "",
|
||||||
|
routeAddress: clashConfig.routeAddress,
|
||||||
),
|
),
|
||||||
builder: (__, state, child) {
|
builder: (__, state, child) {
|
||||||
clashCore.setState(state);
|
clashCore.setState(state);
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ class ProxyManager extends StatelessWidget {
|
|||||||
|
|
||||||
const ProxyManager({super.key, required this.child});
|
const ProxyManager({super.key, required this.child});
|
||||||
|
|
||||||
_updateProxy(ProxyState proxyState) {
|
_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;
|
||||||
if (isStart && systemProxy) {
|
if (isStart && systemProxy) {
|
||||||
proxy?.startProxy(port);
|
proxy?.startProxy(port, proxyState.bassDomain);
|
||||||
}else{
|
} else {
|
||||||
proxy?.stopProxy();
|
proxy?.stopProxy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,8 +24,9 @@ class ProxyManager extends StatelessWidget {
|
|||||||
return Selector3<AppFlowingState, Config, ClashConfig, ProxyState>(
|
return Selector3<AppFlowingState, Config, ClashConfig, ProxyState>(
|
||||||
selector: (_, appFlowingState, config, clashConfig) => ProxyState(
|
selector: (_, appFlowingState, config, clashConfig) => ProxyState(
|
||||||
isStart: appFlowingState.isStart,
|
isStart: appFlowingState.isStart,
|
||||||
systemProxy: config.desktopProps.systemProxy,
|
systemProxy: config.networkProps.systemProxy,
|
||||||
port: clashConfig.mixedPort,
|
port: clashConfig.mixedPort,
|
||||||
|
bassDomain: config.networkProps.bypassDomain,
|
||||||
),
|
),
|
||||||
builder: (_, state, child) {
|
builder: (_, state, child) {
|
||||||
_updateProxy(state);
|
_updateProxy(state);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'package:fl_clash/plugins/app.dart';
|
|
||||||
import 'package:fl_clash/plugins/tile.dart';
|
import 'package:fl_clash/plugins/tile.dart';
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -16,8 +15,6 @@ class TileManager extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _TileContainerState extends State<TileManager> with TileListener {
|
class _TileContainerState extends State<TileManager> with TileListener {
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return widget.child;
|
return widget.child;
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ class TrayManager extends StatefulWidget {
|
|||||||
State<TrayManager> createState() => _TrayContainerState();
|
State<TrayManager> createState() => _TrayContainerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TrayContainerState extends State<TrayManager>
|
class _TrayContainerState extends State<TrayManager> with TrayListener {
|
||||||
with TrayListener {
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -35,15 +34,17 @@ class _TrayContainerState extends State<TrayManager>
|
|||||||
autoLaunch: config.appSetting.autoLaunch,
|
autoLaunch: config.appSetting.autoLaunch,
|
||||||
isStart: appFlowingState.isStart,
|
isStart: appFlowingState.isStart,
|
||||||
locale: config.appSetting.locale,
|
locale: config.appSetting.locale,
|
||||||
systemProxy: config.desktopProps.systemProxy,
|
systemProxy: config.networkProps.systemProxy,
|
||||||
tunEnable: clashConfig.tun.enable,
|
tunEnable: clashConfig.tun.enable,
|
||||||
brightness: appState.brightness,
|
brightness: appState.brightness,
|
||||||
),
|
),
|
||||||
shouldRebuild: (prev, next) {
|
shouldRebuild: (prev, next) {
|
||||||
|
if (prev != next) {
|
||||||
|
globalState.appController.updateTray();
|
||||||
|
}
|
||||||
return prev != next;
|
return prev != next;
|
||||||
},
|
},
|
||||||
builder: (_, state, child) {
|
builder: (_, state, child) {
|
||||||
globalState.appController.updateTray();
|
|
||||||
return child!;
|
return child!;
|
||||||
},
|
},
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
|
|||||||
@@ -59,15 +59,15 @@ class _WindowContainerState extends State<WindowManager>
|
|||||||
super.onWindowClose();
|
super.onWindowClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onShouldTerminate() async {
|
||||||
|
await globalState.appController.handleExit();
|
||||||
|
super.onShouldTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onWindowMoved() async {
|
Future<void> onWindowMoved() async {
|
||||||
super.onWindowMoved();
|
super.onWindowMoved();
|
||||||
final offset = await windowManager.getPosition();
|
|
||||||
final config = globalState.appController.config;
|
|
||||||
config.windowProps = config.windowProps.copyWith(
|
|
||||||
top: offset.dy,
|
|
||||||
left: offset.dx,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -7,9 +7,8 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
|
|
||||||
import '../enum/enum.dart';
|
import '../enum/enum.dart';
|
||||||
|
|
||||||
part 'generated/clash_config.g.dart';
|
|
||||||
|
|
||||||
part 'generated/clash_config.freezed.dart';
|
part 'generated/clash_config.freezed.dart';
|
||||||
|
part 'generated/clash_config.g.dart';
|
||||||
|
|
||||||
const defaultTun = Tun();
|
const defaultTun = Tun();
|
||||||
|
|
||||||
@@ -126,6 +125,91 @@ typedef HostsMap = Map<String, String>;
|
|||||||
const defaultMixedPort = 7890;
|
const defaultMixedPort = 7890;
|
||||||
const defaultKeepAliveInterval = 30;
|
const defaultKeepAliveInterval = 30;
|
||||||
|
|
||||||
|
const defaultBypassPrivateRouteAddress = [
|
||||||
|
"1.0.0.0/8",
|
||||||
|
"2.0.0.0/7",
|
||||||
|
"4.0.0.0/6",
|
||||||
|
"8.0.0.0/7",
|
||||||
|
"11.0.0.0/8",
|
||||||
|
"12.0.0.0/6",
|
||||||
|
"16.0.0.0/4",
|
||||||
|
"32.0.0.0/3",
|
||||||
|
"64.0.0.0/3",
|
||||||
|
"96.0.0.0/4",
|
||||||
|
"112.0.0.0/5",
|
||||||
|
"120.0.0.0/6",
|
||||||
|
"124.0.0.0/7",
|
||||||
|
"126.0.0.0/8",
|
||||||
|
"128.0.0.0/3",
|
||||||
|
"160.0.0.0/5",
|
||||||
|
"168.0.0.0/8",
|
||||||
|
"169.0.0.0/9",
|
||||||
|
"169.128.0.0/10",
|
||||||
|
"169.192.0.0/11",
|
||||||
|
"169.224.0.0/12",
|
||||||
|
"169.240.0.0/13",
|
||||||
|
"169.248.0.0/14",
|
||||||
|
"169.252.0.0/15",
|
||||||
|
"169.255.0.0/16",
|
||||||
|
"170.0.0.0/7",
|
||||||
|
"172.0.0.0/12",
|
||||||
|
"172.32.0.0/11",
|
||||||
|
"172.64.0.0/10",
|
||||||
|
"172.128.0.0/9",
|
||||||
|
"173.0.0.0/8",
|
||||||
|
"174.0.0.0/7",
|
||||||
|
"176.0.0.0/4",
|
||||||
|
"192.0.0.0/9",
|
||||||
|
"192.128.0.0/11",
|
||||||
|
"192.160.0.0/13",
|
||||||
|
"192.169.0.0/16",
|
||||||
|
"192.170.0.0/15",
|
||||||
|
"192.172.0.0/14",
|
||||||
|
"192.176.0.0/12",
|
||||||
|
"192.192.0.0/10",
|
||||||
|
"193.0.0.0/8",
|
||||||
|
"194.0.0.0/7",
|
||||||
|
"196.0.0.0/6",
|
||||||
|
"200.0.0.0/5",
|
||||||
|
"208.0.0.0/4",
|
||||||
|
"240.0.0.0/5",
|
||||||
|
"248.0.0.0/6",
|
||||||
|
"252.0.0.0/7",
|
||||||
|
"254.0.0.0/8",
|
||||||
|
"255.0.0.0/9",
|
||||||
|
"255.128.0.0/10",
|
||||||
|
"255.192.0.0/11",
|
||||||
|
"255.224.0.0/12",
|
||||||
|
"255.240.0.0/13",
|
||||||
|
"255.248.0.0/14",
|
||||||
|
"255.252.0.0/15",
|
||||||
|
"255.254.0.0/16",
|
||||||
|
"255.255.0.0/17",
|
||||||
|
"255.255.128.0/18",
|
||||||
|
"255.255.192.0/19",
|
||||||
|
"255.255.224.0/20",
|
||||||
|
"255.255.240.0/21",
|
||||||
|
"255.255.248.0/22",
|
||||||
|
"255.255.252.0/23",
|
||||||
|
"255.255.254.0/24",
|
||||||
|
"255.255.255.0/25",
|
||||||
|
"255.255.255.128/26",
|
||||||
|
"255.255.255.192/27",
|
||||||
|
"255.255.255.224/28",
|
||||||
|
"255.255.255.240/29",
|
||||||
|
"255.255.255.248/30",
|
||||||
|
"255.255.255.252/31",
|
||||||
|
"255.255.255.254/32",
|
||||||
|
"::/1",
|
||||||
|
"8000::/2",
|
||||||
|
"c000::/3",
|
||||||
|
"e000::/4",
|
||||||
|
"f000::/5",
|
||||||
|
"f800::/6",
|
||||||
|
"fe00::/9",
|
||||||
|
"fec0::/10"
|
||||||
|
];
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class ClashConfig extends ChangeNotifier {
|
class ClashConfig extends ChangeNotifier {
|
||||||
int _mixedPort;
|
int _mixedPort;
|
||||||
@@ -145,6 +229,8 @@ class ClashConfig extends ChangeNotifier {
|
|||||||
List<String> _rules;
|
List<String> _rules;
|
||||||
String? _globalRealUa;
|
String? _globalRealUa;
|
||||||
HostsMap _hosts;
|
HostsMap _hosts;
|
||||||
|
List<String> _includeRouteAddress;
|
||||||
|
RouteMode _routeMode;
|
||||||
|
|
||||||
ClashConfig()
|
ClashConfig()
|
||||||
: _mixedPort = defaultMixedPort,
|
: _mixedPort = defaultMixedPort,
|
||||||
@@ -161,6 +247,8 @@ class ClashConfig extends ChangeNotifier {
|
|||||||
_keepAliveInterval = defaultKeepAliveInterval,
|
_keepAliveInterval = defaultKeepAliveInterval,
|
||||||
_dns = defaultDns,
|
_dns = defaultDns,
|
||||||
_geoXUrl = defaultGeoXMap,
|
_geoXUrl = defaultGeoXMap,
|
||||||
|
_routeMode = RouteMode.config,
|
||||||
|
_includeRouteAddress = [],
|
||||||
_rules = [],
|
_rules = [],
|
||||||
_hosts = {};
|
_hosts = {};
|
||||||
|
|
||||||
@@ -343,6 +431,34 @@ class ClashConfig extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonKey(name: "route-address", includeFromJson: false, includeToJson: true)
|
||||||
|
List<String> get routeAddress {
|
||||||
|
return switch (_routeMode == RouteMode.config) {
|
||||||
|
true => _includeRouteAddress,
|
||||||
|
false => defaultBypassPrivateRouteAddress,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(name: "include-route-address", defaultValue: [])
|
||||||
|
List<String> get includeRouteAddress => _includeRouteAddress;
|
||||||
|
|
||||||
|
set includeRouteAddress(List<String> value) {
|
||||||
|
if (!stringListEquality.equals(value, _includeRouteAddress)) {
|
||||||
|
_includeRouteAddress = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(name: "route-mode", defaultValue: RouteMode.config)
|
||||||
|
RouteMode get routeMode => _routeMode;
|
||||||
|
|
||||||
|
set routeMode(RouteMode value) {
|
||||||
|
if (value != _routeMode) {
|
||||||
|
_routeMode = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
update([ClashConfig? clashConfig]) {
|
update([ClashConfig? clashConfig]) {
|
||||||
if (clashConfig != null) {
|
if (clashConfig != null) {
|
||||||
_mixedPort = clashConfig._mixedPort;
|
_mixedPort = clashConfig._mixedPort;
|
||||||
@@ -360,6 +476,8 @@ class ClashConfig extends ChangeNotifier {
|
|||||||
_geodataLoader = clashConfig._geodataLoader;
|
_geodataLoader = clashConfig._geodataLoader;
|
||||||
_dns = clashConfig._dns;
|
_dns = clashConfig._dns;
|
||||||
_rules = clashConfig._rules;
|
_rules = clashConfig._rules;
|
||||||
|
_routeMode = clashConfig._routeMode;
|
||||||
|
_includeRouteAddress = clashConfig._includeRouteAddress;
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:io';
|
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:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -6,9 +7,8 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
|
|
||||||
import 'models.dart';
|
import 'models.dart';
|
||||||
|
|
||||||
part 'generated/config.g.dart';
|
|
||||||
|
|
||||||
part 'generated/config.freezed.dart';
|
part 'generated/config.freezed.dart';
|
||||||
|
part 'generated/config.g.dart';
|
||||||
|
|
||||||
final defaultAppSetting = const AppSetting().copyWith(
|
final defaultAppSetting = const AppSetting().copyWith(
|
||||||
isAnimateToPage: system.isDesktop ? false : true,
|
isAnimateToPage: system.isDesktop ? false : true,
|
||||||
@@ -38,9 +38,8 @@ class AppSetting with _$AppSetting {
|
|||||||
_$AppSettingFromJson(json);
|
_$AppSettingFromJson(json);
|
||||||
|
|
||||||
factory AppSetting.realFromJson(Map<String, Object?>? json) {
|
factory AppSetting.realFromJson(Map<String, Object?>? json) {
|
||||||
final appSetting = json == null
|
final appSetting =
|
||||||
? defaultAppSetting
|
json == null ? defaultAppSetting : AppSetting.fromJson(json);
|
||||||
: AppSetting.fromJson(json);
|
|
||||||
return appSetting.copyWith(
|
return appSetting.copyWith(
|
||||||
isAnimateToPage: system.isDesktop ? false : appSetting.isAnimateToPage,
|
isAnimateToPage: system.isDesktop ? false : appSetting.isAnimateToPage,
|
||||||
);
|
);
|
||||||
@@ -110,7 +109,6 @@ class VpnProps with _$VpnProps {
|
|||||||
@Default(true) bool systemProxy,
|
@Default(true) bool systemProxy,
|
||||||
@Default(false) bool ipv6,
|
@Default(false) bool ipv6,
|
||||||
@Default(true) bool allowBypass,
|
@Default(true) bool allowBypass,
|
||||||
@Default(defaultBypassDomain) List<String> bypassDomain,
|
|
||||||
}) = _VpnProps;
|
}) = _VpnProps;
|
||||||
|
|
||||||
factory VpnProps.fromJson(Map<String, Object?>? json) =>
|
factory VpnProps.fromJson(Map<String, Object?>? json) =>
|
||||||
@@ -118,13 +116,14 @@ class VpnProps with _$VpnProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class DesktopProps with _$DesktopProps {
|
class NetworkProps with _$NetworkProps {
|
||||||
const factory DesktopProps({
|
const factory NetworkProps({
|
||||||
@Default(true) bool systemProxy,
|
@Default(true) bool systemProxy,
|
||||||
}) = _DesktopProps;
|
@Default(defaultBypassDomain) List<String> bypassDomain,
|
||||||
|
}) = _NetworkProps;
|
||||||
|
|
||||||
factory DesktopProps.fromJson(Map<String, Object?>? json) =>
|
factory NetworkProps.fromJson(Map<String, Object?>? json) =>
|
||||||
json == null ? const DesktopProps() : _$DesktopPropsFromJson(json);
|
json == null ? const NetworkProps() : _$NetworkPropsFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultProxiesStyle = ProxiesStyle();
|
const defaultProxiesStyle = ProxiesStyle();
|
||||||
@@ -188,7 +187,7 @@ class Config extends ChangeNotifier {
|
|||||||
WindowProps _windowProps;
|
WindowProps _windowProps;
|
||||||
ThemeProps _themeProps;
|
ThemeProps _themeProps;
|
||||||
VpnProps _vpnProps;
|
VpnProps _vpnProps;
|
||||||
DesktopProps _desktopProps;
|
NetworkProps _networkProps;
|
||||||
bool _overrideDns;
|
bool _overrideDns;
|
||||||
List<HotKeyAction> _hotKeyActions;
|
List<HotKeyAction> _hotKeyActions;
|
||||||
ProxiesStyle _proxiesStyle;
|
ProxiesStyle _proxiesStyle;
|
||||||
@@ -199,7 +198,7 @@ class Config extends ChangeNotifier {
|
|||||||
_accessControl = const AccessControl(),
|
_accessControl = const AccessControl(),
|
||||||
_windowProps = const WindowProps(),
|
_windowProps = const WindowProps(),
|
||||||
_vpnProps = defaultVpnProps,
|
_vpnProps = defaultVpnProps,
|
||||||
_desktopProps = const DesktopProps(),
|
_networkProps = const NetworkProps(),
|
||||||
_overrideDns = false,
|
_overrideDns = false,
|
||||||
_appSetting = defaultAppSetting,
|
_appSetting = defaultAppSetting,
|
||||||
_hotKeyActions = [],
|
_hotKeyActions = [],
|
||||||
@@ -384,11 +383,11 @@ class Config extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopProps get desktopProps => _desktopProps;
|
NetworkProps get networkProps => _networkProps;
|
||||||
|
|
||||||
set desktopProps(DesktopProps value) {
|
set networkProps(NetworkProps value) {
|
||||||
if (_desktopProps != value) {
|
if (_networkProps != value) {
|
||||||
_desktopProps = value;
|
_networkProps = value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,7 +470,7 @@ class Config extends ChangeNotifier {
|
|||||||
_proxiesStyle = config._proxiesStyle;
|
_proxiesStyle = config._proxiesStyle;
|
||||||
_vpnProps = config._vpnProps;
|
_vpnProps = config._vpnProps;
|
||||||
_overrideDns = config._overrideDns;
|
_overrideDns = config._overrideDns;
|
||||||
_desktopProps = config._desktopProps;
|
_networkProps = config._networkProps;
|
||||||
_hotKeyActions = config._hotKeyActions;
|
_hotKeyActions = config._hotKeyActions;
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -487,6 +486,6 @@ class Config extends ChangeNotifier {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Config{_appSetting: $_appSetting, _profiles: $_profiles, _currentProfileId: $_currentProfileId, _isAccessControl: $_isAccessControl, _accessControl: $_accessControl, _dav: $_dav, _windowProps: $_windowProps, _themeProps: $_themeProps, _vpnProps: $_vpnProps, _desktopProps: $_desktopProps, _overrideDns: $_overrideDns, _hotKeyActions: $_hotKeyActions, _proxiesStyle: $_proxiesStyle}';
|
return 'Config{_appSetting: $_appSetting, _profiles: $_profiles, _currentProfileId: $_currentProfileId, _isAccessControl: $_isAccessControl, _accessControl: $_accessControl, _dav: $_dav, _windowProps: $_windowProps, _themeProps: $_themeProps, _vpnProps: $_vpnProps, _networkProps: $_networkProps, _overrideDns: $_overrideDns, _hotKeyActions: $_hotKeyActions, _proxiesStyle: $_proxiesStyle}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,8 @@ import 'package:fl_clash/enum/enum.dart';
|
|||||||
import 'package:fl_clash/models/models.dart';
|
import 'package:fl_clash/models/models.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'generated/ffi.g.dart';
|
|
||||||
|
|
||||||
part 'generated/ffi.freezed.dart';
|
part 'generated/ffi.freezed.dart';
|
||||||
|
part 'generated/ffi.g.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class CoreState with _$CoreState {
|
class CoreState with _$CoreState {
|
||||||
@@ -17,6 +16,7 @@ class CoreState with _$CoreState {
|
|||||||
required bool allowBypass,
|
required bool allowBypass,
|
||||||
required bool systemProxy,
|
required bool systemProxy,
|
||||||
required List<String> bypassDomain,
|
required List<String> bypassDomain,
|
||||||
|
required List<String> routeAddress,
|
||||||
required bool ipv6,
|
required bool ipv6,
|
||||||
required bool onlyProxy,
|
required bool onlyProxy,
|
||||||
}) = _CoreState;
|
}) = _CoreState;
|
||||||
@@ -36,6 +36,7 @@ class AndroidVpnOptions with _$AndroidVpnOptions {
|
|||||||
required List<String> bypassDomain,
|
required List<String> bypassDomain,
|
||||||
required String ipv4Address,
|
required String ipv4Address,
|
||||||
required String ipv6Address,
|
required String ipv6Address,
|
||||||
|
required List<String> routeAddress,
|
||||||
required String dnsServerAddress,
|
required String dnsServerAddress,
|
||||||
}) = _AndroidVpnOptions;
|
}) = _AndroidVpnOptions;
|
||||||
|
|
||||||
@@ -154,13 +155,38 @@ class ProcessMapItem with _$ProcessMapItem {
|
|||||||
_$ProcessMapItemFromJson(json);
|
_$ProcessMapItemFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class ProviderSubscriptionInfo with _$ProviderSubscriptionInfo {
|
||||||
|
const factory ProviderSubscriptionInfo({
|
||||||
|
@JsonKey(name: "UPLOAD") @Default(0) int upload,
|
||||||
|
@JsonKey(name: "DOWNLOAD") @Default(0) int download,
|
||||||
|
@JsonKey(name: "TOTAL") @Default(0) int total,
|
||||||
|
@JsonKey(name: "EXPIRE") @Default(0) int expire,
|
||||||
|
}) = _ProviderSubscriptionInfo;
|
||||||
|
|
||||||
|
factory ProviderSubscriptionInfo.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$ProviderSubscriptionInfoFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
SubscriptionInfo? subscriptionInfoFormCore(Map<String, Object?>? json) {
|
||||||
|
if (json == null) return null;
|
||||||
|
return SubscriptionInfo(
|
||||||
|
upload: (json['Upload'] as num?)?.toInt() ?? 0,
|
||||||
|
download: (json['Download'] as num?)?.toInt() ?? 0,
|
||||||
|
total: (json['Total'] as num?)?.toInt() ?? 0,
|
||||||
|
expire: (json['Expire'] as num?)?.toInt() ?? 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ExternalProvider with _$ExternalProvider {
|
class ExternalProvider with _$ExternalProvider {
|
||||||
const factory ExternalProvider({
|
const factory ExternalProvider({
|
||||||
required String name,
|
required String name,
|
||||||
required String type,
|
required String type,
|
||||||
required String path,
|
String? path,
|
||||||
required int count,
|
required int count,
|
||||||
|
@JsonKey(name: "subscription-info", fromJson: subscriptionInfoFormCore)
|
||||||
|
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,
|
||||||
|
|||||||
@@ -26,8 +26,12 @@ mixin _$Tun {
|
|||||||
@JsonKey(name: "dns-hijack")
|
@JsonKey(name: "dns-hijack")
|
||||||
List<String> get dnsHijack => throw _privateConstructorUsedError;
|
List<String> get dnsHijack => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Tun to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Tun
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$TunCopyWith<Tun> get copyWith => throw _privateConstructorUsedError;
|
$TunCopyWith<Tun> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +56,8 @@ class _$TunCopyWithImpl<$Res, $Val extends Tun> implements $TunCopyWith<$Res> {
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Tun
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -100,6 +106,8 @@ class __$$TunImplCopyWithImpl<$Res> extends _$TunCopyWithImpl<$Res, _$TunImpl>
|
|||||||
__$$TunImplCopyWithImpl(_$TunImpl _value, $Res Function(_$TunImpl) _then)
|
__$$TunImplCopyWithImpl(_$TunImpl _value, $Res Function(_$TunImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Tun
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -178,12 +186,14 @@ class _$TunImpl implements _Tun {
|
|||||||
.equals(other._dnsHijack, _dnsHijack));
|
.equals(other._dnsHijack, _dnsHijack));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, enable, device, stack,
|
int get hashCode => Object.hash(runtimeType, enable, device, stack,
|
||||||
const DeepCollectionEquality().hash(_dnsHijack));
|
const DeepCollectionEquality().hash(_dnsHijack));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Tun
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$TunImplCopyWith<_$TunImpl> get copyWith =>
|
_$$TunImplCopyWith<_$TunImpl> get copyWith =>
|
||||||
@@ -215,8 +225,11 @@ abstract class _Tun implements Tun {
|
|||||||
@override
|
@override
|
||||||
@JsonKey(name: "dns-hijack")
|
@JsonKey(name: "dns-hijack")
|
||||||
List<String> get dnsHijack;
|
List<String> get dnsHijack;
|
||||||
|
|
||||||
|
/// Create a copy of Tun
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$TunImplCopyWith<_$TunImpl> get copyWith =>
|
_$$TunImplCopyWith<_$TunImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -234,8 +247,12 @@ mixin _$FallbackFilter {
|
|||||||
List<String> get ipcidr => throw _privateConstructorUsedError;
|
List<String> get ipcidr => throw _privateConstructorUsedError;
|
||||||
List<String> get domain => throw _privateConstructorUsedError;
|
List<String> get domain => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this FallbackFilter to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of FallbackFilter
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$FallbackFilterCopyWith<FallbackFilter> get copyWith =>
|
$FallbackFilterCopyWith<FallbackFilter> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -264,6 +281,8 @@ class _$FallbackFilterCopyWithImpl<$Res, $Val extends FallbackFilter>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of FallbackFilter
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -322,6 +341,8 @@ class __$$FallbackFilterImplCopyWithImpl<$Res>
|
|||||||
_$FallbackFilterImpl _value, $Res Function(_$FallbackFilterImpl) _then)
|
_$FallbackFilterImpl _value, $Res Function(_$FallbackFilterImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of FallbackFilter
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -427,7 +448,7 @@ class _$FallbackFilterImpl implements _FallbackFilter {
|
|||||||
const DeepCollectionEquality().equals(other._domain, _domain));
|
const DeepCollectionEquality().equals(other._domain, _domain));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
@@ -437,7 +458,9 @@ class _$FallbackFilterImpl implements _FallbackFilter {
|
|||||||
const DeepCollectionEquality().hash(_ipcidr),
|
const DeepCollectionEquality().hash(_ipcidr),
|
||||||
const DeepCollectionEquality().hash(_domain));
|
const DeepCollectionEquality().hash(_domain));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of FallbackFilter
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$FallbackFilterImplCopyWith<_$FallbackFilterImpl> get copyWith =>
|
_$$FallbackFilterImplCopyWith<_$FallbackFilterImpl> get copyWith =>
|
||||||
@@ -474,8 +497,11 @@ abstract class _FallbackFilter implements FallbackFilter {
|
|||||||
List<String> get ipcidr;
|
List<String> get ipcidr;
|
||||||
@override
|
@override
|
||||||
List<String> get domain;
|
List<String> get domain;
|
||||||
|
|
||||||
|
/// Create a copy of FallbackFilter
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$FallbackFilterImplCopyWith<_$FallbackFilterImpl> get copyWith =>
|
_$$FallbackFilterImplCopyWith<_$FallbackFilterImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -514,8 +540,12 @@ mixin _$Dns {
|
|||||||
@JsonKey(name: "fallback-filter")
|
@JsonKey(name: "fallback-filter")
|
||||||
FallbackFilter get fallbackFilter => throw _privateConstructorUsedError;
|
FallbackFilter get fallbackFilter => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Dns to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Dns
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$DnsCopyWith<Dns> get copyWith => throw _privateConstructorUsedError;
|
$DnsCopyWith<Dns> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,6 +584,8 @@ class _$DnsCopyWithImpl<$Res, $Val extends Dns> implements $DnsCopyWith<$Res> {
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Dns
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -637,6 +669,8 @@ class _$DnsCopyWithImpl<$Res, $Val extends Dns> implements $DnsCopyWith<$Res> {
|
|||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of Dns
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$FallbackFilterCopyWith<$Res> get fallbackFilter {
|
$FallbackFilterCopyWith<$Res> get fallbackFilter {
|
||||||
@@ -680,6 +714,8 @@ class __$$DnsImplCopyWithImpl<$Res> extends _$DnsCopyWithImpl<$Res, _$DnsImpl>
|
|||||||
__$$DnsImplCopyWithImpl(_$DnsImpl _value, $Res Function(_$DnsImpl) _then)
|
__$$DnsImplCopyWithImpl(_$DnsImpl _value, $Res Function(_$DnsImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Dns
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -932,7 +968,7 @@ class _$DnsImpl implements _Dns {
|
|||||||
other.fallbackFilter == fallbackFilter));
|
other.fallbackFilter == fallbackFilter));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
@@ -952,7 +988,9 @@ class _$DnsImpl implements _Dns {
|
|||||||
const DeepCollectionEquality().hash(_proxyServerNameserver),
|
const DeepCollectionEquality().hash(_proxyServerNameserver),
|
||||||
fallbackFilter);
|
fallbackFilter);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Dns
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$DnsImplCopyWith<_$DnsImpl> get copyWith =>
|
_$$DnsImplCopyWith<_$DnsImpl> get copyWith =>
|
||||||
@@ -1030,8 +1068,11 @@ abstract class _Dns implements Dns {
|
|||||||
@override
|
@override
|
||||||
@JsonKey(name: "fallback-filter")
|
@JsonKey(name: "fallback-filter")
|
||||||
FallbackFilter get fallbackFilter;
|
FallbackFilter get fallbackFilter;
|
||||||
|
|
||||||
|
/// Create a copy of Dns
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$DnsImplCopyWith<_$DnsImpl> get copyWith =>
|
_$$DnsImplCopyWith<_$DnsImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,13 @@ ClashConfig _$ClashConfigFromJson(Map<String, dynamic> json) => ClashConfig()
|
|||||||
..hosts = (json['hosts'] as Map<String, dynamic>?)?.map(
|
..hosts = (json['hosts'] as Map<String, dynamic>?)?.map(
|
||||||
(k, e) => MapEntry(k, e as String),
|
(k, e) => MapEntry(k, e as String),
|
||||||
) ??
|
) ??
|
||||||
{};
|
{}
|
||||||
|
..includeRouteAddress = (json['include-route-address'] as List<dynamic>?)
|
||||||
|
?.map((e) => e as String)
|
||||||
|
.toList() ??
|
||||||
|
[]
|
||||||
|
..routeMode = $enumDecodeNullable(_$RouteModeEnumMap, json['route-mode']) ??
|
||||||
|
RouteMode.config;
|
||||||
|
|
||||||
Map<String, dynamic> _$ClashConfigToJson(ClashConfig instance) =>
|
Map<String, dynamic> _$ClashConfigToJson(ClashConfig instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
@@ -63,6 +69,9 @@ Map<String, dynamic> _$ClashConfigToJson(ClashConfig instance) =>
|
|||||||
'global-real-ua': instance.globalRealUa,
|
'global-real-ua': instance.globalRealUa,
|
||||||
'geox-url': instance.geoXUrl,
|
'geox-url': instance.geoXUrl,
|
||||||
'hosts': instance.hosts,
|
'hosts': instance.hosts,
|
||||||
|
'route-address': instance.routeAddress,
|
||||||
|
'include-route-address': instance.includeRouteAddress,
|
||||||
|
'route-mode': _$RouteModeEnumMap[instance.routeMode]!,
|
||||||
};
|
};
|
||||||
|
|
||||||
const _$ModeEnumMap = {
|
const _$ModeEnumMap = {
|
||||||
@@ -84,6 +93,11 @@ const _$LogLevelEnumMap = {
|
|||||||
LogLevel.silent: 'silent',
|
LogLevel.silent: 'silent',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const _$RouteModeEnumMap = {
|
||||||
|
RouteMode.bypassPrivate: 'bypassPrivate',
|
||||||
|
RouteMode.config: 'config',
|
||||||
|
};
|
||||||
|
|
||||||
_$TunImpl _$$TunImplFromJson(Map<String, dynamic> json) => _$TunImpl(
|
_$TunImpl _$$TunImplFromJson(Map<String, dynamic> json) => _$TunImpl(
|
||||||
enable: json['enable'] as bool? ?? false,
|
enable: json['enable'] as bool? ?? false,
|
||||||
device: json['device'] as String? ?? appName,
|
device: json['device'] as String? ?? appName,
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ mixin _$NavigationItem {
|
|||||||
String? get path => throw _privateConstructorUsedError;
|
String? get path => throw _privateConstructorUsedError;
|
||||||
List<NavigationItemMode> get modes => throw _privateConstructorUsedError;
|
List<NavigationItemMode> get modes => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of NavigationItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$NavigationItemCopyWith<NavigationItem> get copyWith =>
|
$NavigationItemCopyWith<NavigationItem> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -55,6 +57,8 @@ class _$NavigationItemCopyWithImpl<$Res, $Val extends NavigationItem>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of NavigationItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -125,6 +129,8 @@ class __$$NavigationItemImplCopyWithImpl<$Res>
|
|||||||
_$NavigationItemImpl _value, $Res Function(_$NavigationItemImpl) _then)
|
_$NavigationItemImpl _value, $Res Function(_$NavigationItemImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of NavigationItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -232,7 +238,9 @@ class _$NavigationItemImpl implements _NavigationItem {
|
|||||||
int get hashCode => Object.hash(runtimeType, icon, label, description,
|
int get hashCode => Object.hash(runtimeType, icon, label, description,
|
||||||
fragment, keep, path, const DeepCollectionEquality().hash(_modes));
|
fragment, keep, path, const DeepCollectionEquality().hash(_modes));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of NavigationItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$NavigationItemImplCopyWith<_$NavigationItemImpl> get copyWith =>
|
_$$NavigationItemImplCopyWith<_$NavigationItemImpl> get copyWith =>
|
||||||
@@ -264,8 +272,11 @@ abstract class _NavigationItem implements NavigationItem {
|
|||||||
String? get path;
|
String? get path;
|
||||||
@override
|
@override
|
||||||
List<NavigationItemMode> get modes;
|
List<NavigationItemMode> get modes;
|
||||||
|
|
||||||
|
/// Create a copy of NavigationItem
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$NavigationItemImplCopyWith<_$NavigationItemImpl> get copyWith =>
|
_$$NavigationItemImplCopyWith<_$NavigationItemImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -281,8 +292,12 @@ mixin _$Package {
|
|||||||
bool get isSystem => throw _privateConstructorUsedError;
|
bool get isSystem => throw _privateConstructorUsedError;
|
||||||
int get firstInstallTime => throw _privateConstructorUsedError;
|
int get firstInstallTime => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Package to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Package
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$PackageCopyWith<Package> get copyWith => throw _privateConstructorUsedError;
|
$PackageCopyWith<Package> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +320,8 @@ class _$PackageCopyWithImpl<$Res, $Val extends Package>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Package
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -353,6 +370,8 @@ class __$$PackageImplCopyWithImpl<$Res>
|
|||||||
_$PackageImpl _value, $Res Function(_$PackageImpl) _then)
|
_$PackageImpl _value, $Res Function(_$PackageImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Package
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -422,12 +441,14 @@ class _$PackageImpl implements _Package {
|
|||||||
other.firstInstallTime == firstInstallTime));
|
other.firstInstallTime == firstInstallTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
Object.hash(runtimeType, packageName, label, isSystem, firstInstallTime);
|
Object.hash(runtimeType, packageName, label, isSystem, firstInstallTime);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Package
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$PackageImplCopyWith<_$PackageImpl> get copyWith =>
|
_$$PackageImplCopyWith<_$PackageImpl> get copyWith =>
|
||||||
@@ -458,8 +479,11 @@ abstract class _Package implements Package {
|
|||||||
bool get isSystem;
|
bool get isSystem;
|
||||||
@override
|
@override
|
||||||
int get firstInstallTime;
|
int get firstInstallTime;
|
||||||
|
|
||||||
|
/// Create a copy of Package
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$PackageImplCopyWith<_$PackageImpl> get copyWith =>
|
_$$PackageImplCopyWith<_$PackageImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -480,8 +504,12 @@ mixin _$Metadata {
|
|||||||
String get process => throw _privateConstructorUsedError;
|
String get process => throw _privateConstructorUsedError;
|
||||||
String get remoteDestination => throw _privateConstructorUsedError;
|
String get remoteDestination => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Metadata to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Metadata
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$MetadataCopyWith<Metadata> get copyWith =>
|
$MetadataCopyWith<Metadata> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -513,6 +541,8 @@ class _$MetadataCopyWithImpl<$Res, $Val extends Metadata>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Metadata
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -595,6 +625,8 @@ class __$$MetadataImplCopyWithImpl<$Res>
|
|||||||
_$MetadataImpl _value, $Res Function(_$MetadataImpl) _then)
|
_$MetadataImpl _value, $Res Function(_$MetadataImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Metadata
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -711,7 +743,7 @@ class _$MetadataImpl implements _Metadata {
|
|||||||
other.remoteDestination == remoteDestination));
|
other.remoteDestination == remoteDestination));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
@@ -725,7 +757,9 @@ class _$MetadataImpl implements _Metadata {
|
|||||||
process,
|
process,
|
||||||
remoteDestination);
|
remoteDestination);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Metadata
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$MetadataImplCopyWith<_$MetadataImpl> get copyWith =>
|
_$$MetadataImplCopyWith<_$MetadataImpl> get copyWith =>
|
||||||
@@ -772,8 +806,11 @@ abstract class _Metadata implements Metadata {
|
|||||||
String get process;
|
String get process;
|
||||||
@override
|
@override
|
||||||
String get remoteDestination;
|
String get remoteDestination;
|
||||||
|
|
||||||
|
/// Create a copy of Metadata
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$MetadataImplCopyWith<_$MetadataImpl> get copyWith =>
|
_$$MetadataImplCopyWith<_$MetadataImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -791,8 +828,12 @@ mixin _$Connection {
|
|||||||
Metadata get metadata => throw _privateConstructorUsedError;
|
Metadata get metadata => throw _privateConstructorUsedError;
|
||||||
List<String> get chains => throw _privateConstructorUsedError;
|
List<String> get chains => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Connection to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Connection
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$ConnectionCopyWith<Connection> get copyWith =>
|
$ConnectionCopyWith<Connection> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -824,6 +865,8 @@ class _$ConnectionCopyWithImpl<$Res, $Val extends Connection>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Connection
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -862,6 +905,8 @@ class _$ConnectionCopyWithImpl<$Res, $Val extends Connection>
|
|||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of Connection
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$MetadataCopyWith<$Res> get metadata {
|
$MetadataCopyWith<$Res> get metadata {
|
||||||
@@ -899,6 +944,8 @@ class __$$ConnectionImplCopyWithImpl<$Res>
|
|||||||
_$ConnectionImpl _value, $Res Function(_$ConnectionImpl) _then)
|
_$ConnectionImpl _value, $Res Function(_$ConnectionImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Connection
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -991,12 +1038,14 @@ class _$ConnectionImpl implements _Connection {
|
|||||||
const DeepCollectionEquality().equals(other._chains, _chains));
|
const DeepCollectionEquality().equals(other._chains, _chains));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, id, upload, download, start,
|
int get hashCode => Object.hash(runtimeType, id, upload, download, start,
|
||||||
metadata, const DeepCollectionEquality().hash(_chains));
|
metadata, const DeepCollectionEquality().hash(_chains));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Connection
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$ConnectionImplCopyWith<_$ConnectionImpl> get copyWith =>
|
_$$ConnectionImplCopyWith<_$ConnectionImpl> get copyWith =>
|
||||||
@@ -1034,8 +1083,11 @@ abstract class _Connection implements Connection {
|
|||||||
Metadata get metadata;
|
Metadata get metadata;
|
||||||
@override
|
@override
|
||||||
List<String> get chains;
|
List<String> get chains;
|
||||||
|
|
||||||
|
/// Create a copy of Connection
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$ConnectionImplCopyWith<_$ConnectionImpl> get copyWith =>
|
_$$ConnectionImplCopyWith<_$ConnectionImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1049,8 +1101,12 @@ mixin _$LogsAndKeywords {
|
|||||||
List<Log> get logs => throw _privateConstructorUsedError;
|
List<Log> get logs => throw _privateConstructorUsedError;
|
||||||
List<String> get keywords => throw _privateConstructorUsedError;
|
List<String> get keywords => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this LogsAndKeywords to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of LogsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$LogsAndKeywordsCopyWith<LogsAndKeywords> get copyWith =>
|
$LogsAndKeywordsCopyWith<LogsAndKeywords> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1074,6 +1130,8 @@ class _$LogsAndKeywordsCopyWithImpl<$Res, $Val extends LogsAndKeywords>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LogsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1112,6 +1170,8 @@ class __$$LogsAndKeywordsImplCopyWithImpl<$Res>
|
|||||||
_$LogsAndKeywordsImpl _value, $Res Function(_$LogsAndKeywordsImpl) _then)
|
_$LogsAndKeywordsImpl _value, $Res Function(_$LogsAndKeywordsImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of LogsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1174,14 +1234,16 @@ class _$LogsAndKeywordsImpl implements _LogsAndKeywords {
|
|||||||
const DeepCollectionEquality().equals(other._keywords, _keywords));
|
const DeepCollectionEquality().equals(other._keywords, _keywords));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
const DeepCollectionEquality().hash(_logs),
|
const DeepCollectionEquality().hash(_logs),
|
||||||
const DeepCollectionEquality().hash(_keywords));
|
const DeepCollectionEquality().hash(_keywords));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of LogsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$LogsAndKeywordsImplCopyWith<_$LogsAndKeywordsImpl> get copyWith =>
|
_$$LogsAndKeywordsImplCopyWith<_$LogsAndKeywordsImpl> get copyWith =>
|
||||||
@@ -1208,8 +1270,11 @@ abstract class _LogsAndKeywords implements LogsAndKeywords {
|
|||||||
List<Log> get logs;
|
List<Log> get logs;
|
||||||
@override
|
@override
|
||||||
List<String> get keywords;
|
List<String> get keywords;
|
||||||
|
|
||||||
|
/// Create a copy of LogsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$LogsAndKeywordsImplCopyWith<_$LogsAndKeywordsImpl> get copyWith =>
|
_$$LogsAndKeywordsImplCopyWith<_$LogsAndKeywordsImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1224,8 +1289,12 @@ mixin _$ConnectionsAndKeywords {
|
|||||||
List<Connection> get connections => throw _privateConstructorUsedError;
|
List<Connection> get connections => throw _privateConstructorUsedError;
|
||||||
List<String> get keywords => throw _privateConstructorUsedError;
|
List<String> get keywords => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this ConnectionsAndKeywords to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of ConnectionsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$ConnectionsAndKeywordsCopyWith<ConnectionsAndKeywords> get copyWith =>
|
$ConnectionsAndKeywordsCopyWith<ConnectionsAndKeywords> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1250,6 +1319,8 @@ class _$ConnectionsAndKeywordsCopyWithImpl<$Res,
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ConnectionsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1291,6 +1362,8 @@ class __$$ConnectionsAndKeywordsImplCopyWithImpl<$Res>
|
|||||||
$Res Function(_$ConnectionsAndKeywordsImpl) _then)
|
$Res Function(_$ConnectionsAndKeywordsImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of ConnectionsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1355,14 +1428,16 @@ class _$ConnectionsAndKeywordsImpl implements _ConnectionsAndKeywords {
|
|||||||
const DeepCollectionEquality().equals(other._keywords, _keywords));
|
const DeepCollectionEquality().equals(other._keywords, _keywords));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
const DeepCollectionEquality().hash(_connections),
|
const DeepCollectionEquality().hash(_connections),
|
||||||
const DeepCollectionEquality().hash(_keywords));
|
const DeepCollectionEquality().hash(_keywords));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of ConnectionsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$ConnectionsAndKeywordsImplCopyWith<_$ConnectionsAndKeywordsImpl>
|
_$$ConnectionsAndKeywordsImplCopyWith<_$ConnectionsAndKeywordsImpl>
|
||||||
@@ -1389,8 +1464,11 @@ abstract class _ConnectionsAndKeywords implements ConnectionsAndKeywords {
|
|||||||
List<Connection> get connections;
|
List<Connection> get connections;
|
||||||
@override
|
@override
|
||||||
List<String> get keywords;
|
List<String> get keywords;
|
||||||
|
|
||||||
|
/// Create a copy of ConnectionsAndKeywords
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$ConnectionsAndKeywordsImplCopyWith<_$ConnectionsAndKeywordsImpl>
|
_$$ConnectionsAndKeywordsImplCopyWith<_$ConnectionsAndKeywordsImpl>
|
||||||
get copyWith => throw _privateConstructorUsedError;
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1406,8 +1484,12 @@ mixin _$DAV {
|
|||||||
String get password => throw _privateConstructorUsedError;
|
String get password => throw _privateConstructorUsedError;
|
||||||
String get fileName => throw _privateConstructorUsedError;
|
String get fileName => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this DAV to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of DAV
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$DAVCopyWith<DAV> get copyWith => throw _privateConstructorUsedError;
|
$DAVCopyWith<DAV> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1428,6 +1510,8 @@ class _$DAVCopyWithImpl<$Res, $Val extends DAV> implements $DAVCopyWith<$Res> {
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of DAV
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1472,6 +1556,8 @@ class __$$DAVImplCopyWithImpl<$Res> extends _$DAVCopyWithImpl<$Res, _$DAVImpl>
|
|||||||
__$$DAVImplCopyWithImpl(_$DAVImpl _value, $Res Function(_$DAVImpl) _then)
|
__$$DAVImplCopyWithImpl(_$DAVImpl _value, $Res Function(_$DAVImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of DAV
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1541,11 +1627,13 @@ class _$DAVImpl implements _DAV {
|
|||||||
other.fileName == fileName));
|
other.fileName == fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, uri, user, password, fileName);
|
int get hashCode => Object.hash(runtimeType, uri, user, password, fileName);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of DAV
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$DAVImplCopyWith<_$DAVImpl> get copyWith =>
|
_$$DAVImplCopyWith<_$DAVImpl> get copyWith =>
|
||||||
@@ -1576,8 +1664,11 @@ abstract class _DAV implements DAV {
|
|||||||
String get password;
|
String get password;
|
||||||
@override
|
@override
|
||||||
String get fileName;
|
String get fileName;
|
||||||
|
|
||||||
|
/// Create a copy of DAV
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$DAVImplCopyWith<_$DAVImpl> get copyWith =>
|
_$$DAVImplCopyWith<_$DAVImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1587,7 +1678,9 @@ mixin _$FileInfo {
|
|||||||
int get size => throw _privateConstructorUsedError;
|
int get size => throw _privateConstructorUsedError;
|
||||||
DateTime get lastModified => throw _privateConstructorUsedError;
|
DateTime get lastModified => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of FileInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$FileInfoCopyWith<FileInfo> get copyWith =>
|
$FileInfoCopyWith<FileInfo> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1610,6 +1703,8 @@ class _$FileInfoCopyWithImpl<$Res, $Val extends FileInfo>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of FileInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1648,6 +1743,8 @@ class __$$FileInfoImplCopyWithImpl<$Res>
|
|||||||
_$FileInfoImpl _value, $Res Function(_$FileInfoImpl) _then)
|
_$FileInfoImpl _value, $Res Function(_$FileInfoImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of FileInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1695,7 +1792,9 @@ class _$FileInfoImpl implements _FileInfo {
|
|||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, size, lastModified);
|
int get hashCode => Object.hash(runtimeType, size, lastModified);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of FileInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$FileInfoImplCopyWith<_$FileInfoImpl> get copyWith =>
|
_$$FileInfoImplCopyWith<_$FileInfoImpl> get copyWith =>
|
||||||
@@ -1711,8 +1810,11 @@ abstract class _FileInfo implements FileInfo {
|
|||||||
int get size;
|
int get size;
|
||||||
@override
|
@override
|
||||||
DateTime get lastModified;
|
DateTime get lastModified;
|
||||||
|
|
||||||
|
/// Create a copy of FileInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$FileInfoImplCopyWith<_$FileInfoImpl> get copyWith =>
|
_$$FileInfoImplCopyWith<_$FileInfoImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1726,8 +1828,12 @@ mixin _$VersionInfo {
|
|||||||
String get clashName => throw _privateConstructorUsedError;
|
String get clashName => throw _privateConstructorUsedError;
|
||||||
String get version => throw _privateConstructorUsedError;
|
String get version => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this VersionInfo to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of VersionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$VersionInfoCopyWith<VersionInfo> get copyWith =>
|
$VersionInfoCopyWith<VersionInfo> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1751,6 +1857,8 @@ class _$VersionInfoCopyWithImpl<$Res, $Val extends VersionInfo>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VersionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1789,6 +1897,8 @@ class __$$VersionInfoImplCopyWithImpl<$Res>
|
|||||||
_$VersionInfoImpl _value, $Res Function(_$VersionInfoImpl) _then)
|
_$VersionInfoImpl _value, $Res Function(_$VersionInfoImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of VersionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1838,11 +1948,13 @@ class _$VersionInfoImpl implements _VersionInfo {
|
|||||||
(identical(other.version, version) || other.version == version));
|
(identical(other.version, version) || other.version == version));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, clashName, version);
|
int get hashCode => Object.hash(runtimeType, clashName, version);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of VersionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$VersionInfoImplCopyWith<_$VersionInfoImpl> get copyWith =>
|
_$$VersionInfoImplCopyWith<_$VersionInfoImpl> get copyWith =>
|
||||||
@@ -1867,8 +1979,11 @@ abstract class _VersionInfo implements VersionInfo {
|
|||||||
String get clashName;
|
String get clashName;
|
||||||
@override
|
@override
|
||||||
String get version;
|
String get version;
|
||||||
|
|
||||||
|
/// Create a copy of VersionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$VersionInfoImplCopyWith<_$VersionInfoImpl> get copyWith =>
|
_$$VersionInfoImplCopyWith<_$VersionInfoImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1886,8 +2001,12 @@ mixin _$Group {
|
|||||||
String get icon => throw _privateConstructorUsedError;
|
String get icon => throw _privateConstructorUsedError;
|
||||||
String get name => throw _privateConstructorUsedError;
|
String get name => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Group to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Group
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$GroupCopyWith<Group> get copyWith => throw _privateConstructorUsedError;
|
$GroupCopyWith<Group> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1915,6 +2034,8 @@ class _$GroupCopyWithImpl<$Res, $Val extends Group>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Group
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1978,6 +2099,8 @@ class __$$GroupImplCopyWithImpl<$Res>
|
|||||||
_$GroupImpl _value, $Res Function(_$GroupImpl) _then)
|
_$GroupImpl _value, $Res Function(_$GroupImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Group
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -2071,12 +2194,14 @@ class _$GroupImpl implements _Group {
|
|||||||
(identical(other.name, name) || other.name == name));
|
(identical(other.name, name) || other.name == name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, type,
|
int get hashCode => Object.hash(runtimeType, type,
|
||||||
const DeepCollectionEquality().hash(_all), now, hidden, icon, name);
|
const DeepCollectionEquality().hash(_all), now, hidden, icon, name);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Group
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$GroupImplCopyWith<_$GroupImpl> get copyWith =>
|
_$$GroupImplCopyWith<_$GroupImpl> get copyWith =>
|
||||||
@@ -2113,8 +2238,11 @@ abstract class _Group implements Group {
|
|||||||
String get icon;
|
String get icon;
|
||||||
@override
|
@override
|
||||||
String get name;
|
String get name;
|
||||||
|
|
||||||
|
/// Create a copy of Group
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$GroupImplCopyWith<_$GroupImpl> get copyWith =>
|
_$$GroupImplCopyWith<_$GroupImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -2129,8 +2257,12 @@ mixin _$Proxy {
|
|||||||
String get type => throw _privateConstructorUsedError;
|
String get type => throw _privateConstructorUsedError;
|
||||||
String? get now => throw _privateConstructorUsedError;
|
String? get now => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Proxy to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Proxy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$ProxyCopyWith<Proxy> get copyWith => throw _privateConstructorUsedError;
|
$ProxyCopyWith<Proxy> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2152,6 +2284,8 @@ class _$ProxyCopyWithImpl<$Res, $Val extends Proxy>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Proxy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -2194,6 +2328,8 @@ class __$$ProxyImplCopyWithImpl<$Res>
|
|||||||
_$ProxyImpl _value, $Res Function(_$ProxyImpl) _then)
|
_$ProxyImpl _value, $Res Function(_$ProxyImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Proxy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -2248,11 +2384,13 @@ class _$ProxyImpl implements _Proxy {
|
|||||||
(identical(other.now, now) || other.now == now));
|
(identical(other.now, now) || other.now == now));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, name, type, now);
|
int get hashCode => Object.hash(runtimeType, name, type, now);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Proxy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$ProxyImplCopyWith<_$ProxyImpl> get copyWith =>
|
_$$ProxyImplCopyWith<_$ProxyImpl> get copyWith =>
|
||||||
@@ -2280,8 +2418,11 @@ abstract class _Proxy implements Proxy {
|
|||||||
String get type;
|
String get type;
|
||||||
@override
|
@override
|
||||||
String? get now;
|
String? get now;
|
||||||
|
|
||||||
|
/// Create a copy of Proxy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$ProxyImplCopyWith<_$ProxyImpl> get copyWith =>
|
_$$ProxyImplCopyWith<_$ProxyImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -2296,8 +2437,12 @@ mixin _$HotKeyAction {
|
|||||||
int? get key => throw _privateConstructorUsedError;
|
int? get key => throw _privateConstructorUsedError;
|
||||||
Set<KeyboardModifier> get modifiers => throw _privateConstructorUsedError;
|
Set<KeyboardModifier> get modifiers => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this HotKeyAction to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of HotKeyAction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$HotKeyActionCopyWith<HotKeyAction> get copyWith =>
|
$HotKeyActionCopyWith<HotKeyAction> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -2321,6 +2466,8 @@ class _$HotKeyActionCopyWithImpl<$Res, $Val extends HotKeyAction>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of HotKeyAction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -2364,6 +2511,8 @@ class __$$HotKeyActionImplCopyWithImpl<$Res>
|
|||||||
_$HotKeyActionImpl _value, $Res Function(_$HotKeyActionImpl) _then)
|
_$HotKeyActionImpl _value, $Res Function(_$HotKeyActionImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of HotKeyAction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -2429,12 +2578,14 @@ class _$HotKeyActionImpl implements _HotKeyAction {
|
|||||||
.equals(other._modifiers, _modifiers));
|
.equals(other._modifiers, _modifiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, action, key,
|
int get hashCode => Object.hash(runtimeType, action, key,
|
||||||
const DeepCollectionEquality().hash(_modifiers));
|
const DeepCollectionEquality().hash(_modifiers));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of HotKeyAction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$HotKeyActionImplCopyWith<_$HotKeyActionImpl> get copyWith =>
|
_$$HotKeyActionImplCopyWith<_$HotKeyActionImpl> get copyWith =>
|
||||||
@@ -2463,8 +2614,11 @@ abstract class _HotKeyAction implements HotKeyAction {
|
|||||||
int? get key;
|
int? get key;
|
||||||
@override
|
@override
|
||||||
Set<KeyboardModifier> get modifiers;
|
Set<KeyboardModifier> get modifiers;
|
||||||
|
|
||||||
|
/// Create a copy of HotKeyAction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$HotKeyActionImplCopyWith<_$HotKeyActionImpl> get copyWith =>
|
_$$HotKeyActionImplCopyWith<_$HotKeyActionImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -2475,7 +2629,9 @@ mixin _$Field {
|
|||||||
String get value => throw _privateConstructorUsedError;
|
String get value => throw _privateConstructorUsedError;
|
||||||
Validator? get validator => throw _privateConstructorUsedError;
|
Validator? get validator => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Field
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$FieldCopyWith<Field> get copyWith => throw _privateConstructorUsedError;
|
$FieldCopyWith<Field> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2497,6 +2653,8 @@ class _$FieldCopyWithImpl<$Res, $Val extends Field>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Field
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -2539,6 +2697,8 @@ class __$$FieldImplCopyWithImpl<$Res>
|
|||||||
_$FieldImpl _value, $Res Function(_$FieldImpl) _then)
|
_$FieldImpl _value, $Res Function(_$FieldImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Field
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -2594,7 +2754,9 @@ class _$FieldImpl implements _Field {
|
|||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, label, value, validator);
|
int get hashCode => Object.hash(runtimeType, label, value, validator);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Field
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$FieldImplCopyWith<_$FieldImpl> get copyWith =>
|
_$$FieldImplCopyWith<_$FieldImpl> get copyWith =>
|
||||||
@@ -2613,8 +2775,11 @@ abstract class _Field implements Field {
|
|||||||
String get value;
|
String get value;
|
||||||
@override
|
@override
|
||||||
Validator? get validator;
|
Validator? get validator;
|
||||||
|
|
||||||
|
/// Create a copy of Field
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$FieldImplCopyWith<_$FieldImpl> get copyWith =>
|
_$$FieldImplCopyWith<_$FieldImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,12 @@ mixin _$AppSetting {
|
|||||||
bool get minimizeOnExit => throw _privateConstructorUsedError;
|
bool get minimizeOnExit => throw _privateConstructorUsedError;
|
||||||
bool get hidden => throw _privateConstructorUsedError;
|
bool get hidden => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this AppSetting to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of AppSetting
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$AppSettingCopyWith<AppSetting> get copyWith =>
|
$AppSettingCopyWith<AppSetting> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -76,6 +80,8 @@ class _$AppSettingCopyWithImpl<$Res, $Val extends AppSetting>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AppSetting
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -194,6 +200,8 @@ class __$$AppSettingImplCopyWithImpl<$Res>
|
|||||||
_$AppSettingImpl _value, $Res Function(_$AppSettingImpl) _then)
|
_$AppSettingImpl _value, $Res Function(_$AppSettingImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of AppSetting
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -384,7 +392,7 @@ class _$AppSettingImpl implements _AppSetting {
|
|||||||
(identical(other.hidden, hidden) || other.hidden == hidden));
|
(identical(other.hidden, hidden) || other.hidden == hidden));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
@@ -404,7 +412,9 @@ class _$AppSettingImpl implements _AppSetting {
|
|||||||
minimizeOnExit,
|
minimizeOnExit,
|
||||||
hidden);
|
hidden);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of AppSetting
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$AppSettingImplCopyWith<_$AppSettingImpl> get copyWith =>
|
_$$AppSettingImplCopyWith<_$AppSettingImpl> get copyWith =>
|
||||||
@@ -469,8 +479,11 @@ abstract class _AppSetting implements AppSetting {
|
|||||||
bool get minimizeOnExit;
|
bool get minimizeOnExit;
|
||||||
@override
|
@override
|
||||||
bool get hidden;
|
bool get hidden;
|
||||||
|
|
||||||
|
/// Create a copy of AppSetting
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$AppSettingImplCopyWith<_$AppSettingImpl> get copyWith =>
|
_$$AppSettingImplCopyWith<_$AppSettingImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -487,8 +500,12 @@ mixin _$AccessControl {
|
|||||||
AccessSortType get sort => throw _privateConstructorUsedError;
|
AccessSortType get sort => throw _privateConstructorUsedError;
|
||||||
bool get isFilterSystemApp => throw _privateConstructorUsedError;
|
bool get isFilterSystemApp => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this AccessControl to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of AccessControl
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$AccessControlCopyWith<AccessControl> get copyWith =>
|
$AccessControlCopyWith<AccessControl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -517,6 +534,8 @@ class _$AccessControlCopyWithImpl<$Res, $Val extends AccessControl>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AccessControl
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -575,6 +594,8 @@ class __$$AccessControlImplCopyWithImpl<$Res>
|
|||||||
_$AccessControlImpl _value, $Res Function(_$AccessControlImpl) _then)
|
_$AccessControlImpl _value, $Res Function(_$AccessControlImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of AccessControl
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -672,7 +693,7 @@ class _$AccessControlImpl implements _AccessControl {
|
|||||||
other.isFilterSystemApp == isFilterSystemApp));
|
other.isFilterSystemApp == isFilterSystemApp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
@@ -682,7 +703,9 @@ class _$AccessControlImpl implements _AccessControl {
|
|||||||
sort,
|
sort,
|
||||||
isFilterSystemApp);
|
isFilterSystemApp);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of AccessControl
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$AccessControlImplCopyWith<_$AccessControlImpl> get copyWith =>
|
_$$AccessControlImplCopyWith<_$AccessControlImpl> get copyWith =>
|
||||||
@@ -717,8 +740,11 @@ abstract class _AccessControl implements AccessControl {
|
|||||||
AccessSortType get sort;
|
AccessSortType get sort;
|
||||||
@override
|
@override
|
||||||
bool get isFilterSystemApp;
|
bool get isFilterSystemApp;
|
||||||
|
|
||||||
|
/// Create a copy of AccessControl
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$AccessControlImplCopyWith<_$AccessControlImpl> get copyWith =>
|
_$$AccessControlImplCopyWith<_$AccessControlImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -734,8 +760,12 @@ mixin _$WindowProps {
|
|||||||
double? get top => throw _privateConstructorUsedError;
|
double? get top => throw _privateConstructorUsedError;
|
||||||
double? get left => throw _privateConstructorUsedError;
|
double? get left => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this WindowProps to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of WindowProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$WindowPropsCopyWith<WindowProps> get copyWith =>
|
$WindowPropsCopyWith<WindowProps> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -759,6 +789,8 @@ class _$WindowPropsCopyWithImpl<$Res, $Val extends WindowProps>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of WindowProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -807,6 +839,8 @@ class __$$WindowPropsImplCopyWithImpl<$Res>
|
|||||||
_$WindowPropsImpl _value, $Res Function(_$WindowPropsImpl) _then)
|
_$WindowPropsImpl _value, $Res Function(_$WindowPropsImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of WindowProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -872,11 +906,13 @@ class _$WindowPropsImpl implements _WindowProps {
|
|||||||
(identical(other.left, left) || other.left == left));
|
(identical(other.left, left) || other.left == left));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, width, height, top, left);
|
int get hashCode => Object.hash(runtimeType, width, height, top, left);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of WindowProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$WindowPropsImplCopyWith<_$WindowPropsImpl> get copyWith =>
|
_$$WindowPropsImplCopyWith<_$WindowPropsImpl> get copyWith =>
|
||||||
@@ -908,8 +944,11 @@ abstract class _WindowProps implements WindowProps {
|
|||||||
double? get top;
|
double? get top;
|
||||||
@override
|
@override
|
||||||
double? get left;
|
double? get left;
|
||||||
|
|
||||||
|
/// Create a copy of WindowProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$WindowPropsImplCopyWith<_$WindowPropsImpl> get copyWith =>
|
_$$WindowPropsImplCopyWith<_$WindowPropsImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -924,10 +963,13 @@ mixin _$VpnProps {
|
|||||||
bool get systemProxy => throw _privateConstructorUsedError;
|
bool get systemProxy => throw _privateConstructorUsedError;
|
||||||
bool get ipv6 => throw _privateConstructorUsedError;
|
bool get ipv6 => throw _privateConstructorUsedError;
|
||||||
bool get allowBypass => throw _privateConstructorUsedError;
|
bool get allowBypass => throw _privateConstructorUsedError;
|
||||||
List<String> get bypassDomain => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
|
/// Serializes this VpnProps to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of VpnProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$VpnPropsCopyWith<VpnProps> get copyWith =>
|
$VpnPropsCopyWith<VpnProps> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -937,12 +979,7 @@ abstract class $VpnPropsCopyWith<$Res> {
|
|||||||
factory $VpnPropsCopyWith(VpnProps value, $Res Function(VpnProps) then) =
|
factory $VpnPropsCopyWith(VpnProps value, $Res Function(VpnProps) then) =
|
||||||
_$VpnPropsCopyWithImpl<$Res, VpnProps>;
|
_$VpnPropsCopyWithImpl<$Res, VpnProps>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call({bool enable, bool systemProxy, bool ipv6, bool allowBypass});
|
||||||
{bool enable,
|
|
||||||
bool systemProxy,
|
|
||||||
bool ipv6,
|
|
||||||
bool allowBypass,
|
|
||||||
List<String> bypassDomain});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -955,6 +992,8 @@ class _$VpnPropsCopyWithImpl<$Res, $Val extends VpnProps>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VpnProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -962,7 +1001,6 @@ class _$VpnPropsCopyWithImpl<$Res, $Val extends VpnProps>
|
|||||||
Object? systemProxy = null,
|
Object? systemProxy = null,
|
||||||
Object? ipv6 = null,
|
Object? ipv6 = null,
|
||||||
Object? allowBypass = null,
|
Object? allowBypass = null,
|
||||||
Object? bypassDomain = null,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
enable: null == enable
|
enable: null == enable
|
||||||
@@ -981,10 +1019,6 @@ class _$VpnPropsCopyWithImpl<$Res, $Val extends VpnProps>
|
|||||||
? _value.allowBypass
|
? _value.allowBypass
|
||||||
: allowBypass // ignore: cast_nullable_to_non_nullable
|
: allowBypass // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
bypassDomain: null == bypassDomain
|
|
||||||
? _value.bypassDomain
|
|
||||||
: bypassDomain // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<String>,
|
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -997,12 +1031,7 @@ abstract class _$$VpnPropsImplCopyWith<$Res>
|
|||||||
__$$VpnPropsImplCopyWithImpl<$Res>;
|
__$$VpnPropsImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call({bool enable, bool systemProxy, bool ipv6, bool allowBypass});
|
||||||
{bool enable,
|
|
||||||
bool systemProxy,
|
|
||||||
bool ipv6,
|
|
||||||
bool allowBypass,
|
|
||||||
List<String> bypassDomain});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -1013,6 +1042,8 @@ class __$$VpnPropsImplCopyWithImpl<$Res>
|
|||||||
_$VpnPropsImpl _value, $Res Function(_$VpnPropsImpl) _then)
|
_$VpnPropsImpl _value, $Res Function(_$VpnPropsImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of VpnProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1020,7 +1051,6 @@ class __$$VpnPropsImplCopyWithImpl<$Res>
|
|||||||
Object? systemProxy = null,
|
Object? systemProxy = null,
|
||||||
Object? ipv6 = null,
|
Object? ipv6 = null,
|
||||||
Object? allowBypass = null,
|
Object? allowBypass = null,
|
||||||
Object? bypassDomain = null,
|
|
||||||
}) {
|
}) {
|
||||||
return _then(_$VpnPropsImpl(
|
return _then(_$VpnPropsImpl(
|
||||||
enable: null == enable
|
enable: null == enable
|
||||||
@@ -1039,10 +1069,6 @@ class __$$VpnPropsImplCopyWithImpl<$Res>
|
|||||||
? _value.allowBypass
|
? _value.allowBypass
|
||||||
: allowBypass // ignore: cast_nullable_to_non_nullable
|
: allowBypass // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
bypassDomain: null == bypassDomain
|
|
||||||
? _value._bypassDomain
|
|
||||||
: bypassDomain // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<String>,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1054,9 +1080,7 @@ class _$VpnPropsImpl implements _VpnProps {
|
|||||||
{this.enable = true,
|
{this.enable = true,
|
||||||
this.systemProxy = true,
|
this.systemProxy = true,
|
||||||
this.ipv6 = false,
|
this.ipv6 = false,
|
||||||
this.allowBypass = true,
|
this.allowBypass = true});
|
||||||
final List<String> bypassDomain = defaultBypassDomain})
|
|
||||||
: _bypassDomain = bypassDomain;
|
|
||||||
|
|
||||||
factory _$VpnPropsImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$VpnPropsImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$VpnPropsImplFromJson(json);
|
_$$VpnPropsImplFromJson(json);
|
||||||
@@ -1073,18 +1097,10 @@ class _$VpnPropsImpl implements _VpnProps {
|
|||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final bool allowBypass;
|
final bool allowBypass;
|
||||||
final List<String> _bypassDomain;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
List<String> get bypassDomain {
|
|
||||||
if (_bypassDomain is EqualUnmodifiableListView) return _bypassDomain;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableListView(_bypassDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'VpnProps(enable: $enable, systemProxy: $systemProxy, ipv6: $ipv6, allowBypass: $allowBypass, bypassDomain: $bypassDomain)';
|
return 'VpnProps(enable: $enable, systemProxy: $systemProxy, ipv6: $ipv6, allowBypass: $allowBypass)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1097,17 +1113,17 @@ class _$VpnPropsImpl implements _VpnProps {
|
|||||||
other.systemProxy == systemProxy) &&
|
other.systemProxy == systemProxy) &&
|
||||||
(identical(other.ipv6, ipv6) || other.ipv6 == ipv6) &&
|
(identical(other.ipv6, ipv6) || other.ipv6 == ipv6) &&
|
||||||
(identical(other.allowBypass, allowBypass) ||
|
(identical(other.allowBypass, allowBypass) ||
|
||||||
other.allowBypass == allowBypass) &&
|
other.allowBypass == allowBypass));
|
||||||
const DeepCollectionEquality()
|
|
||||||
.equals(other._bypassDomain, _bypassDomain));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, enable, systemProxy, ipv6,
|
int get hashCode =>
|
||||||
allowBypass, const DeepCollectionEquality().hash(_bypassDomain));
|
Object.hash(runtimeType, enable, systemProxy, ipv6, allowBypass);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of VpnProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$VpnPropsImplCopyWith<_$VpnPropsImpl> get copyWith =>
|
_$$VpnPropsImplCopyWith<_$VpnPropsImpl> get copyWith =>
|
||||||
@@ -1126,8 +1142,7 @@ abstract class _VpnProps implements VpnProps {
|
|||||||
{final bool enable,
|
{final bool enable,
|
||||||
final bool systemProxy,
|
final bool systemProxy,
|
||||||
final bool ipv6,
|
final bool ipv6,
|
||||||
final bool allowBypass,
|
final bool allowBypass}) = _$VpnPropsImpl;
|
||||||
final List<String> bypassDomain}) = _$VpnPropsImpl;
|
|
||||||
|
|
||||||
factory _VpnProps.fromJson(Map<String, dynamic> json) =
|
factory _VpnProps.fromJson(Map<String, dynamic> json) =
|
||||||
_$VpnPropsImpl.fromJson;
|
_$VpnPropsImpl.fromJson;
|
||||||
@@ -1140,149 +1155,192 @@ abstract class _VpnProps implements VpnProps {
|
|||||||
bool get ipv6;
|
bool get ipv6;
|
||||||
@override
|
@override
|
||||||
bool get allowBypass;
|
bool get allowBypass;
|
||||||
|
|
||||||
|
/// Create a copy of VpnProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
List<String> get bypassDomain;
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
|
||||||
@JsonKey(ignore: true)
|
|
||||||
_$$VpnPropsImplCopyWith<_$VpnPropsImpl> get copyWith =>
|
_$$VpnPropsImplCopyWith<_$VpnPropsImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopProps _$DesktopPropsFromJson(Map<String, dynamic> json) {
|
NetworkProps _$NetworkPropsFromJson(Map<String, dynamic> json) {
|
||||||
return _DesktopProps.fromJson(json);
|
return _NetworkProps.fromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$DesktopProps {
|
mixin _$NetworkProps {
|
||||||
bool get systemProxy => throw _privateConstructorUsedError;
|
bool get systemProxy => throw _privateConstructorUsedError;
|
||||||
|
List<String> get bypassDomain => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this NetworkProps to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
$DesktopPropsCopyWith<DesktopProps> get copyWith =>
|
/// Create a copy of NetworkProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$NetworkPropsCopyWith<NetworkProps> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class $DesktopPropsCopyWith<$Res> {
|
abstract class $NetworkPropsCopyWith<$Res> {
|
||||||
factory $DesktopPropsCopyWith(
|
factory $NetworkPropsCopyWith(
|
||||||
DesktopProps value, $Res Function(DesktopProps) then) =
|
NetworkProps value, $Res Function(NetworkProps) then) =
|
||||||
_$DesktopPropsCopyWithImpl<$Res, DesktopProps>;
|
_$NetworkPropsCopyWithImpl<$Res, NetworkProps>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({bool systemProxy});
|
$Res call({bool systemProxy, List<String> bypassDomain});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$DesktopPropsCopyWithImpl<$Res, $Val extends DesktopProps>
|
class _$NetworkPropsCopyWithImpl<$Res, $Val extends NetworkProps>
|
||||||
implements $DesktopPropsCopyWith<$Res> {
|
implements $NetworkPropsCopyWith<$Res> {
|
||||||
_$DesktopPropsCopyWithImpl(this._value, this._then);
|
_$NetworkPropsCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Val _value;
|
final $Val _value;
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of NetworkProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? systemProxy = null,
|
Object? systemProxy = null,
|
||||||
|
Object? bypassDomain = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
systemProxy: null == systemProxy
|
systemProxy: null == systemProxy
|
||||||
? _value.systemProxy
|
? _value.systemProxy
|
||||||
: systemProxy // ignore: cast_nullable_to_non_nullable
|
: systemProxy // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
|
bypassDomain: null == bypassDomain
|
||||||
|
? _value.bypassDomain
|
||||||
|
: bypassDomain // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<String>,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$DesktopPropsImplCopyWith<$Res>
|
abstract class _$$NetworkPropsImplCopyWith<$Res>
|
||||||
implements $DesktopPropsCopyWith<$Res> {
|
implements $NetworkPropsCopyWith<$Res> {
|
||||||
factory _$$DesktopPropsImplCopyWith(
|
factory _$$NetworkPropsImplCopyWith(
|
||||||
_$DesktopPropsImpl value, $Res Function(_$DesktopPropsImpl) then) =
|
_$NetworkPropsImpl value, $Res Function(_$NetworkPropsImpl) then) =
|
||||||
__$$DesktopPropsImplCopyWithImpl<$Res>;
|
__$$NetworkPropsImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({bool systemProxy});
|
$Res call({bool systemProxy, List<String> bypassDomain});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$DesktopPropsImplCopyWithImpl<$Res>
|
class __$$NetworkPropsImplCopyWithImpl<$Res>
|
||||||
extends _$DesktopPropsCopyWithImpl<$Res, _$DesktopPropsImpl>
|
extends _$NetworkPropsCopyWithImpl<$Res, _$NetworkPropsImpl>
|
||||||
implements _$$DesktopPropsImplCopyWith<$Res> {
|
implements _$$NetworkPropsImplCopyWith<$Res> {
|
||||||
__$$DesktopPropsImplCopyWithImpl(
|
__$$NetworkPropsImplCopyWithImpl(
|
||||||
_$DesktopPropsImpl _value, $Res Function(_$DesktopPropsImpl) _then)
|
_$NetworkPropsImpl _value, $Res Function(_$NetworkPropsImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of NetworkProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? systemProxy = null,
|
Object? systemProxy = null,
|
||||||
|
Object? bypassDomain = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$DesktopPropsImpl(
|
return _then(_$NetworkPropsImpl(
|
||||||
systemProxy: null == systemProxy
|
systemProxy: null == systemProxy
|
||||||
? _value.systemProxy
|
? _value.systemProxy
|
||||||
: systemProxy // ignore: cast_nullable_to_non_nullable
|
: systemProxy // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
|
bypassDomain: null == bypassDomain
|
||||||
|
? _value._bypassDomain
|
||||||
|
: bypassDomain // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<String>,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$DesktopPropsImpl implements _DesktopProps {
|
class _$NetworkPropsImpl implements _NetworkProps {
|
||||||
const _$DesktopPropsImpl({this.systemProxy = true});
|
const _$NetworkPropsImpl(
|
||||||
|
{this.systemProxy = true,
|
||||||
|
final List<String> bypassDomain = defaultBypassDomain})
|
||||||
|
: _bypassDomain = bypassDomain;
|
||||||
|
|
||||||
factory _$DesktopPropsImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$NetworkPropsImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$DesktopPropsImplFromJson(json);
|
_$$NetworkPropsImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final bool systemProxy;
|
final bool systemProxy;
|
||||||
|
final List<String> _bypassDomain;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
List<String> get bypassDomain {
|
||||||
|
if (_bypassDomain is EqualUnmodifiableListView) return _bypassDomain;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_bypassDomain);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'DesktopProps(systemProxy: $systemProxy)';
|
return 'NetworkProps(systemProxy: $systemProxy, bypassDomain: $bypassDomain)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$DesktopPropsImpl &&
|
other is _$NetworkPropsImpl &&
|
||||||
(identical(other.systemProxy, systemProxy) ||
|
(identical(other.systemProxy, systemProxy) ||
|
||||||
other.systemProxy == systemProxy));
|
other.systemProxy == systemProxy) &&
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other._bypassDomain, _bypassDomain));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, systemProxy);
|
int get hashCode => Object.hash(runtimeType, systemProxy,
|
||||||
|
const DeepCollectionEquality().hash(_bypassDomain));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of NetworkProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$DesktopPropsImplCopyWith<_$DesktopPropsImpl> get copyWith =>
|
_$$NetworkPropsImplCopyWith<_$NetworkPropsImpl> get copyWith =>
|
||||||
__$$DesktopPropsImplCopyWithImpl<_$DesktopPropsImpl>(this, _$identity);
|
__$$NetworkPropsImplCopyWithImpl<_$NetworkPropsImpl>(this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$$DesktopPropsImplToJson(
|
return _$$NetworkPropsImplToJson(
|
||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _DesktopProps implements DesktopProps {
|
abstract class _NetworkProps implements NetworkProps {
|
||||||
const factory _DesktopProps({final bool systemProxy}) = _$DesktopPropsImpl;
|
const factory _NetworkProps(
|
||||||
|
{final bool systemProxy,
|
||||||
|
final List<String> bypassDomain}) = _$NetworkPropsImpl;
|
||||||
|
|
||||||
factory _DesktopProps.fromJson(Map<String, dynamic> json) =
|
factory _NetworkProps.fromJson(Map<String, dynamic> json) =
|
||||||
_$DesktopPropsImpl.fromJson;
|
_$NetworkPropsImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get systemProxy;
|
bool get systemProxy;
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
List<String> get bypassDomain;
|
||||||
_$$DesktopPropsImplCopyWith<_$DesktopPropsImpl> get copyWith =>
|
|
||||||
|
/// Create a copy of NetworkProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$NetworkPropsImplCopyWith<_$NetworkPropsImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1299,8 +1357,12 @@ mixin _$ProxiesStyle {
|
|||||||
ProxyCardType get cardType => throw _privateConstructorUsedError;
|
ProxyCardType get cardType => throw _privateConstructorUsedError;
|
||||||
Map<String, String> get iconMap => throw _privateConstructorUsedError;
|
Map<String, String> get iconMap => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this ProxiesStyle to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of ProxiesStyle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$ProxiesStyleCopyWith<ProxiesStyle> get copyWith =>
|
$ProxiesStyleCopyWith<ProxiesStyle> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1330,6 +1392,8 @@ class _$ProxiesStyleCopyWithImpl<$Res, $Val extends ProxiesStyle>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ProxiesStyle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1394,6 +1458,8 @@ class __$$ProxiesStyleImplCopyWithImpl<$Res>
|
|||||||
_$ProxiesStyleImpl _value, $Res Function(_$ProxiesStyleImpl) _then)
|
_$ProxiesStyleImpl _value, $Res Function(_$ProxiesStyleImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of ProxiesStyle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1493,12 +1559,14 @@ class _$ProxiesStyleImpl implements _ProxiesStyle {
|
|||||||
const DeepCollectionEquality().equals(other._iconMap, _iconMap));
|
const DeepCollectionEquality().equals(other._iconMap, _iconMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, type, sortType, layout,
|
int get hashCode => Object.hash(runtimeType, type, sortType, layout,
|
||||||
iconStyle, cardType, const DeepCollectionEquality().hash(_iconMap));
|
iconStyle, cardType, const DeepCollectionEquality().hash(_iconMap));
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of ProxiesStyle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$ProxiesStyleImplCopyWith<_$ProxiesStyleImpl> get copyWith =>
|
_$$ProxiesStyleImplCopyWith<_$ProxiesStyleImpl> get copyWith =>
|
||||||
@@ -1536,8 +1604,11 @@ abstract class _ProxiesStyle implements ProxiesStyle {
|
|||||||
ProxyCardType get cardType;
|
ProxyCardType get cardType;
|
||||||
@override
|
@override
|
||||||
Map<String, String> get iconMap;
|
Map<String, String> get iconMap;
|
||||||
|
|
||||||
|
/// Create a copy of ProxiesStyle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$ProxiesStyleImplCopyWith<_$ProxiesStyleImpl> get copyWith =>
|
_$$ProxiesStyleImplCopyWith<_$ProxiesStyleImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1553,8 +1624,12 @@ mixin _$ThemeProps {
|
|||||||
bool get prueBlack => throw _privateConstructorUsedError;
|
bool get prueBlack => throw _privateConstructorUsedError;
|
||||||
FontFamily get fontFamily => throw _privateConstructorUsedError;
|
FontFamily get fontFamily => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this ThemeProps to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of ThemeProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$ThemePropsCopyWith<ThemeProps> get copyWith =>
|
$ThemePropsCopyWith<ThemeProps> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -1582,6 +1657,8 @@ class _$ThemePropsCopyWithImpl<$Res, $Val extends ThemeProps>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ThemeProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1634,6 +1711,8 @@ class __$$ThemePropsImplCopyWithImpl<$Res>
|
|||||||
_$ThemePropsImpl _value, $Res Function(_$ThemePropsImpl) _then)
|
_$ThemePropsImpl _value, $Res Function(_$ThemePropsImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of ThemeProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -1707,12 +1786,14 @@ class _$ThemePropsImpl implements _ThemeProps {
|
|||||||
other.fontFamily == fontFamily));
|
other.fontFamily == fontFamily));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
Object.hash(runtimeType, primaryColor, themeMode, prueBlack, fontFamily);
|
Object.hash(runtimeType, primaryColor, themeMode, prueBlack, fontFamily);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of ThemeProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$ThemePropsImplCopyWith<_$ThemePropsImpl> get copyWith =>
|
_$$ThemePropsImplCopyWith<_$ThemePropsImpl> get copyWith =>
|
||||||
@@ -1744,8 +1825,11 @@ abstract class _ThemeProps implements ThemeProps {
|
|||||||
bool get prueBlack;
|
bool get prueBlack;
|
||||||
@override
|
@override
|
||||||
FontFamily get fontFamily;
|
FontFamily get fontFamily;
|
||||||
|
|
||||||
|
/// Create a copy of ThemeProps
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$ThemePropsImplCopyWith<_$ThemePropsImpl> get copyWith =>
|
_$$ThemePropsImplCopyWith<_$ThemePropsImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ Config _$ConfigFromJson(Map<String, dynamic> json) => Config()
|
|||||||
..windowProps =
|
..windowProps =
|
||||||
WindowProps.fromJson(json['windowProps'] as Map<String, dynamic>?)
|
WindowProps.fromJson(json['windowProps'] as Map<String, dynamic>?)
|
||||||
..vpnProps = VpnProps.fromJson(json['vpnProps'] as Map<String, dynamic>?)
|
..vpnProps = VpnProps.fromJson(json['vpnProps'] as Map<String, dynamic>?)
|
||||||
..desktopProps =
|
..networkProps =
|
||||||
DesktopProps.fromJson(json['desktopProps'] as Map<String, dynamic>?)
|
NetworkProps.fromJson(json['networkProps'] as Map<String, dynamic>?)
|
||||||
..overrideDns = json['overrideDns'] as bool? ?? false
|
..overrideDns = json['overrideDns'] as bool? ?? false
|
||||||
..hotKeyActions = (json['hotKeyActions'] as List<dynamic>?)
|
..hotKeyActions = (json['hotKeyActions'] as List<dynamic>?)
|
||||||
?.map((e) => HotKeyAction.fromJson(e as Map<String, dynamic>))
|
?.map((e) => HotKeyAction.fromJson(e as Map<String, dynamic>))
|
||||||
@@ -44,7 +44,7 @@ Map<String, dynamic> _$ConfigToJson(Config instance) => <String, dynamic>{
|
|||||||
'dav': instance.dav,
|
'dav': instance.dav,
|
||||||
'windowProps': instance.windowProps,
|
'windowProps': instance.windowProps,
|
||||||
'vpnProps': instance.vpnProps,
|
'vpnProps': instance.vpnProps,
|
||||||
'desktopProps': instance.desktopProps,
|
'networkProps': instance.networkProps,
|
||||||
'overrideDns': instance.overrideDns,
|
'overrideDns': instance.overrideDns,
|
||||||
'hotKeyActions': instance.hotKeyActions,
|
'hotKeyActions': instance.hotKeyActions,
|
||||||
'proxiesStyle': instance.proxiesStyle,
|
'proxiesStyle': instance.proxiesStyle,
|
||||||
@@ -148,10 +148,6 @@ _$VpnPropsImpl _$$VpnPropsImplFromJson(Map<String, dynamic> json) =>
|
|||||||
systemProxy: json['systemProxy'] as bool? ?? true,
|
systemProxy: json['systemProxy'] as bool? ?? true,
|
||||||
ipv6: json['ipv6'] as bool? ?? false,
|
ipv6: json['ipv6'] as bool? ?? false,
|
||||||
allowBypass: json['allowBypass'] as bool? ?? true,
|
allowBypass: json['allowBypass'] as bool? ?? true,
|
||||||
bypassDomain: (json['bypassDomain'] as List<dynamic>?)
|
|
||||||
?.map((e) => e as String)
|
|
||||||
.toList() ??
|
|
||||||
defaultBypassDomain,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$VpnPropsImplToJson(_$VpnPropsImpl instance) =>
|
Map<String, dynamic> _$$VpnPropsImplToJson(_$VpnPropsImpl instance) =>
|
||||||
@@ -160,17 +156,21 @@ Map<String, dynamic> _$$VpnPropsImplToJson(_$VpnPropsImpl instance) =>
|
|||||||
'systemProxy': instance.systemProxy,
|
'systemProxy': instance.systemProxy,
|
||||||
'ipv6': instance.ipv6,
|
'ipv6': instance.ipv6,
|
||||||
'allowBypass': instance.allowBypass,
|
'allowBypass': instance.allowBypass,
|
||||||
'bypassDomain': instance.bypassDomain,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_$DesktopPropsImpl _$$DesktopPropsImplFromJson(Map<String, dynamic> json) =>
|
_$NetworkPropsImpl _$$NetworkPropsImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$DesktopPropsImpl(
|
_$NetworkPropsImpl(
|
||||||
systemProxy: json['systemProxy'] as bool? ?? true,
|
systemProxy: json['systemProxy'] as bool? ?? true,
|
||||||
|
bypassDomain: (json['bypassDomain'] as List<dynamic>?)
|
||||||
|
?.map((e) => e as String)
|
||||||
|
.toList() ??
|
||||||
|
defaultBypassDomain,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$DesktopPropsImplToJson(_$DesktopPropsImpl instance) =>
|
Map<String, dynamic> _$$NetworkPropsImplToJson(_$NetworkPropsImpl instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'systemProxy': instance.systemProxy,
|
'systemProxy': instance.systemProxy,
|
||||||
|
'bypassDomain': instance.bypassDomain,
|
||||||
};
|
};
|
||||||
|
|
||||||
_$ProxiesStyleImpl _$$ProxiesStyleImplFromJson(Map<String, dynamic> json) =>
|
_$ProxiesStyleImpl _$$ProxiesStyleImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,9 @@ _$CoreStateImpl _$$CoreStateImplFromJson(Map<String, dynamic> json) =>
|
|||||||
bypassDomain: (json['bypassDomain'] as List<dynamic>)
|
bypassDomain: (json['bypassDomain'] as List<dynamic>)
|
||||||
.map((e) => e as String)
|
.map((e) => e as String)
|
||||||
.toList(),
|
.toList(),
|
||||||
|
routeAddress: (json['routeAddress'] as List<dynamic>)
|
||||||
|
.map((e) => e as String)
|
||||||
|
.toList(),
|
||||||
ipv6: json['ipv6'] as bool,
|
ipv6: json['ipv6'] as bool,
|
||||||
onlyProxy: json['onlyProxy'] as bool,
|
onlyProxy: json['onlyProxy'] as bool,
|
||||||
);
|
);
|
||||||
@@ -31,6 +34,7 @@ Map<String, dynamic> _$$CoreStateImplToJson(_$CoreStateImpl instance) =>
|
|||||||
'allowBypass': instance.allowBypass,
|
'allowBypass': instance.allowBypass,
|
||||||
'systemProxy': instance.systemProxy,
|
'systemProxy': instance.systemProxy,
|
||||||
'bypassDomain': instance.bypassDomain,
|
'bypassDomain': instance.bypassDomain,
|
||||||
|
'routeAddress': instance.routeAddress,
|
||||||
'ipv6': instance.ipv6,
|
'ipv6': instance.ipv6,
|
||||||
'onlyProxy': instance.onlyProxy,
|
'onlyProxy': instance.onlyProxy,
|
||||||
};
|
};
|
||||||
@@ -51,6 +55,9 @@ _$AndroidVpnOptionsImpl _$$AndroidVpnOptionsImplFromJson(
|
|||||||
.toList(),
|
.toList(),
|
||||||
ipv4Address: json['ipv4Address'] as String,
|
ipv4Address: json['ipv4Address'] as String,
|
||||||
ipv6Address: json['ipv6Address'] as String,
|
ipv6Address: json['ipv6Address'] as String,
|
||||||
|
routeAddress: (json['routeAddress'] as List<dynamic>)
|
||||||
|
.map((e) => e as String)
|
||||||
|
.toList(),
|
||||||
dnsServerAddress: json['dnsServerAddress'] as String,
|
dnsServerAddress: json['dnsServerAddress'] as String,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -65,6 +72,7 @@ Map<String, dynamic> _$$AndroidVpnOptionsImplToJson(
|
|||||||
'bypassDomain': instance.bypassDomain,
|
'bypassDomain': instance.bypassDomain,
|
||||||
'ipv4Address': instance.ipv4Address,
|
'ipv4Address': instance.ipv4Address,
|
||||||
'ipv6Address': instance.ipv6Address,
|
'ipv6Address': instance.ipv6Address,
|
||||||
|
'routeAddress': instance.routeAddress,
|
||||||
'dnsServerAddress': instance.dnsServerAddress,
|
'dnsServerAddress': instance.dnsServerAddress,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -215,13 +223,33 @@ Map<String, dynamic> _$$ProcessMapItemImplToJson(
|
|||||||
'value': instance.value,
|
'value': instance.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_$ProviderSubscriptionInfoImpl _$$ProviderSubscriptionInfoImplFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$ProviderSubscriptionInfoImpl(
|
||||||
|
upload: (json['UPLOAD'] as num?)?.toInt() ?? 0,
|
||||||
|
download: (json['DOWNLOAD'] as num?)?.toInt() ?? 0,
|
||||||
|
total: (json['TOTAL'] as num?)?.toInt() ?? 0,
|
||||||
|
expire: (json['EXPIRE'] as num?)?.toInt() ?? 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$ProviderSubscriptionInfoImplToJson(
|
||||||
|
_$ProviderSubscriptionInfoImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'UPLOAD': instance.upload,
|
||||||
|
'DOWNLOAD': instance.download,
|
||||||
|
'TOTAL': instance.total,
|
||||||
|
'EXPIRE': instance.expire,
|
||||||
|
};
|
||||||
|
|
||||||
_$ExternalProviderImpl _$$ExternalProviderImplFromJson(
|
_$ExternalProviderImpl _$$ExternalProviderImplFromJson(
|
||||||
Map<String, dynamic> json) =>
|
Map<String, dynamic> json) =>
|
||||||
_$ExternalProviderImpl(
|
_$ExternalProviderImpl(
|
||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
type: json['type'] as String,
|
type: json['type'] as String,
|
||||||
path: json['path'] as String,
|
path: json['path'] as String?,
|
||||||
count: (json['count'] as num).toInt(),
|
count: (json['count'] as num).toInt(),
|
||||||
|
subscriptionInfo: subscriptionInfoFormCore(
|
||||||
|
json['subscription-info'] as Map<String, Object?>?),
|
||||||
isUpdating: json['isUpdating'] as bool? ?? false,
|
isUpdating: json['isUpdating'] as bool? ?? false,
|
||||||
vehicleType: json['vehicle-type'] as String,
|
vehicleType: json['vehicle-type'] as String,
|
||||||
updateAt: DateTime.parse(json['update-at'] as String),
|
updateAt: DateTime.parse(json['update-at'] as String),
|
||||||
@@ -234,6 +262,7 @@ Map<String, dynamic> _$$ExternalProviderImplToJson(
|
|||||||
'type': instance.type,
|
'type': instance.type,
|
||||||
'path': instance.path,
|
'path': instance.path,
|
||||||
'count': instance.count,
|
'count': instance.count,
|
||||||
|
'subscription-info': instance.subscriptionInfo,
|
||||||
'isUpdating': instance.isUpdating,
|
'isUpdating': instance.isUpdating,
|
||||||
'vehicle-type': instance.vehicleType,
|
'vehicle-type': instance.vehicleType,
|
||||||
'update-at': instance.updateAt.toIso8601String(),
|
'update-at': instance.updateAt.toIso8601String(),
|
||||||
|
|||||||
@@ -14,41 +14,48 @@ T _$identity<T>(T value) => value;
|
|||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
UserInfo _$UserInfoFromJson(Map<String, dynamic> json) {
|
SubscriptionInfo _$SubscriptionInfoFromJson(Map<String, dynamic> json) {
|
||||||
return _UserInfo.fromJson(json);
|
return _SubscriptionInfo.fromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$UserInfo {
|
mixin _$SubscriptionInfo {
|
||||||
int get upload => throw _privateConstructorUsedError;
|
int get upload => throw _privateConstructorUsedError;
|
||||||
int get download => throw _privateConstructorUsedError;
|
int get download => throw _privateConstructorUsedError;
|
||||||
int get total => throw _privateConstructorUsedError;
|
int get total => throw _privateConstructorUsedError;
|
||||||
int get expire => throw _privateConstructorUsedError;
|
int get expire => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this SubscriptionInfo to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
$UserInfoCopyWith<UserInfo> get copyWith =>
|
/// Create a copy of SubscriptionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$SubscriptionInfoCopyWith<SubscriptionInfo> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class $UserInfoCopyWith<$Res> {
|
abstract class $SubscriptionInfoCopyWith<$Res> {
|
||||||
factory $UserInfoCopyWith(UserInfo value, $Res Function(UserInfo) then) =
|
factory $SubscriptionInfoCopyWith(
|
||||||
_$UserInfoCopyWithImpl<$Res, UserInfo>;
|
SubscriptionInfo value, $Res Function(SubscriptionInfo) then) =
|
||||||
|
_$SubscriptionInfoCopyWithImpl<$Res, SubscriptionInfo>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({int upload, int download, int total, int expire});
|
$Res call({int upload, int download, int total, int expire});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$UserInfoCopyWithImpl<$Res, $Val extends UserInfo>
|
class _$SubscriptionInfoCopyWithImpl<$Res, $Val extends SubscriptionInfo>
|
||||||
implements $UserInfoCopyWith<$Res> {
|
implements $SubscriptionInfoCopyWith<$Res> {
|
||||||
_$UserInfoCopyWithImpl(this._value, this._then);
|
_$SubscriptionInfoCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Val _value;
|
final $Val _value;
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SubscriptionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -79,24 +86,26 @@ class _$UserInfoCopyWithImpl<$Res, $Val extends UserInfo>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$UserInfoImplCopyWith<$Res>
|
abstract class _$$SubscriptionInfoImplCopyWith<$Res>
|
||||||
implements $UserInfoCopyWith<$Res> {
|
implements $SubscriptionInfoCopyWith<$Res> {
|
||||||
factory _$$UserInfoImplCopyWith(
|
factory _$$SubscriptionInfoImplCopyWith(_$SubscriptionInfoImpl value,
|
||||||
_$UserInfoImpl value, $Res Function(_$UserInfoImpl) then) =
|
$Res Function(_$SubscriptionInfoImpl) then) =
|
||||||
__$$UserInfoImplCopyWithImpl<$Res>;
|
__$$SubscriptionInfoImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({int upload, int download, int total, int expire});
|
$Res call({int upload, int download, int total, int expire});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$UserInfoImplCopyWithImpl<$Res>
|
class __$$SubscriptionInfoImplCopyWithImpl<$Res>
|
||||||
extends _$UserInfoCopyWithImpl<$Res, _$UserInfoImpl>
|
extends _$SubscriptionInfoCopyWithImpl<$Res, _$SubscriptionInfoImpl>
|
||||||
implements _$$UserInfoImplCopyWith<$Res> {
|
implements _$$SubscriptionInfoImplCopyWith<$Res> {
|
||||||
__$$UserInfoImplCopyWithImpl(
|
__$$SubscriptionInfoImplCopyWithImpl(_$SubscriptionInfoImpl _value,
|
||||||
_$UserInfoImpl _value, $Res Function(_$UserInfoImpl) _then)
|
$Res Function(_$SubscriptionInfoImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of SubscriptionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -105,7 +114,7 @@ class __$$UserInfoImplCopyWithImpl<$Res>
|
|||||||
Object? total = null,
|
Object? total = null,
|
||||||
Object? expire = null,
|
Object? expire = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$UserInfoImpl(
|
return _then(_$SubscriptionInfoImpl(
|
||||||
upload: null == upload
|
upload: null == upload
|
||||||
? _value.upload
|
? _value.upload
|
||||||
: upload // ignore: cast_nullable_to_non_nullable
|
: upload // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -128,12 +137,12 @@ class __$$UserInfoImplCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$UserInfoImpl implements _UserInfo {
|
class _$SubscriptionInfoImpl implements _SubscriptionInfo {
|
||||||
const _$UserInfoImpl(
|
const _$SubscriptionInfoImpl(
|
||||||
{this.upload = 0, this.download = 0, this.total = 0, this.expire = 0});
|
{this.upload = 0, this.download = 0, this.total = 0, this.expire = 0});
|
||||||
|
|
||||||
factory _$UserInfoImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$SubscriptionInfoImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$UserInfoImplFromJson(json);
|
_$$SubscriptionInfoImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
@@ -150,14 +159,14 @@ class _$UserInfoImpl implements _UserInfo {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'UserInfo(upload: $upload, download: $download, total: $total, expire: $expire)';
|
return 'SubscriptionInfo(upload: $upload, download: $download, total: $total, expire: $expire)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$UserInfoImpl &&
|
other is _$SubscriptionInfoImpl &&
|
||||||
(identical(other.upload, upload) || other.upload == upload) &&
|
(identical(other.upload, upload) || other.upload == upload) &&
|
||||||
(identical(other.download, download) ||
|
(identical(other.download, download) ||
|
||||||
other.download == download) &&
|
other.download == download) &&
|
||||||
@@ -165,33 +174,36 @@ class _$UserInfoImpl implements _UserInfo {
|
|||||||
(identical(other.expire, expire) || other.expire == expire));
|
(identical(other.expire, expire) || other.expire == expire));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, upload, download, total, expire);
|
int get hashCode => Object.hash(runtimeType, upload, download, total, expire);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of SubscriptionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$UserInfoImplCopyWith<_$UserInfoImpl> get copyWith =>
|
_$$SubscriptionInfoImplCopyWith<_$SubscriptionInfoImpl> get copyWith =>
|
||||||
__$$UserInfoImplCopyWithImpl<_$UserInfoImpl>(this, _$identity);
|
__$$SubscriptionInfoImplCopyWithImpl<_$SubscriptionInfoImpl>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$$UserInfoImplToJson(
|
return _$$SubscriptionInfoImplToJson(
|
||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _UserInfo implements UserInfo {
|
abstract class _SubscriptionInfo implements SubscriptionInfo {
|
||||||
const factory _UserInfo(
|
const factory _SubscriptionInfo(
|
||||||
{final int upload,
|
{final int upload,
|
||||||
final int download,
|
final int download,
|
||||||
final int total,
|
final int total,
|
||||||
final int expire}) = _$UserInfoImpl;
|
final int expire}) = _$SubscriptionInfoImpl;
|
||||||
|
|
||||||
factory _UserInfo.fromJson(Map<String, dynamic> json) =
|
factory _SubscriptionInfo.fromJson(Map<String, dynamic> json) =
|
||||||
_$UserInfoImpl.fromJson;
|
_$SubscriptionInfoImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get upload;
|
int get upload;
|
||||||
@@ -201,9 +213,12 @@ abstract class _UserInfo implements UserInfo {
|
|||||||
int get total;
|
int get total;
|
||||||
@override
|
@override
|
||||||
int get expire;
|
int get expire;
|
||||||
|
|
||||||
|
/// Create a copy of SubscriptionInfo
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$UserInfoImplCopyWith<_$UserInfoImpl> get copyWith =>
|
_$$SubscriptionInfoImplCopyWith<_$SubscriptionInfoImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,15 +234,19 @@ mixin _$Profile {
|
|||||||
String get url => throw _privateConstructorUsedError;
|
String get url => throw _privateConstructorUsedError;
|
||||||
DateTime? get lastUpdateDate => throw _privateConstructorUsedError;
|
DateTime? get lastUpdateDate => throw _privateConstructorUsedError;
|
||||||
Duration get autoUpdateDuration => throw _privateConstructorUsedError;
|
Duration get autoUpdateDuration => throw _privateConstructorUsedError;
|
||||||
UserInfo? get userInfo => throw _privateConstructorUsedError;
|
SubscriptionInfo? get subscriptionInfo => throw _privateConstructorUsedError;
|
||||||
bool get autoUpdate => throw _privateConstructorUsedError;
|
bool get autoUpdate => throw _privateConstructorUsedError;
|
||||||
Map<String, String> get selectedMap => throw _privateConstructorUsedError;
|
Map<String, String> get selectedMap => throw _privateConstructorUsedError;
|
||||||
Set<String> get unfoldSet => throw _privateConstructorUsedError;
|
Set<String> get unfoldSet => throw _privateConstructorUsedError;
|
||||||
@JsonKey(includeToJson: false, includeFromJson: false)
|
@JsonKey(includeToJson: false, includeFromJson: false)
|
||||||
bool get isUpdating => throw _privateConstructorUsedError;
|
bool get isUpdating => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this Profile to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of Profile
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$ProfileCopyWith<Profile> get copyWith => throw _privateConstructorUsedError;
|
$ProfileCopyWith<Profile> get copyWith => throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,13 +262,13 @@ abstract class $ProfileCopyWith<$Res> {
|
|||||||
String url,
|
String url,
|
||||||
DateTime? lastUpdateDate,
|
DateTime? lastUpdateDate,
|
||||||
Duration autoUpdateDuration,
|
Duration autoUpdateDuration,
|
||||||
UserInfo? userInfo,
|
SubscriptionInfo? subscriptionInfo,
|
||||||
bool autoUpdate,
|
bool autoUpdate,
|
||||||
Map<String, String> selectedMap,
|
Map<String, String> selectedMap,
|
||||||
Set<String> unfoldSet,
|
Set<String> unfoldSet,
|
||||||
@JsonKey(includeToJson: false, includeFromJson: false) bool isUpdating});
|
@JsonKey(includeToJson: false, includeFromJson: false) bool isUpdating});
|
||||||
|
|
||||||
$UserInfoCopyWith<$Res>? get userInfo;
|
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -262,6 +281,8 @@ class _$ProfileCopyWithImpl<$Res, $Val extends Profile>
|
|||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function($Val) _then;
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of Profile
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -271,7 +292,7 @@ class _$ProfileCopyWithImpl<$Res, $Val extends Profile>
|
|||||||
Object? url = null,
|
Object? url = null,
|
||||||
Object? lastUpdateDate = freezed,
|
Object? lastUpdateDate = freezed,
|
||||||
Object? autoUpdateDuration = null,
|
Object? autoUpdateDuration = null,
|
||||||
Object? userInfo = freezed,
|
Object? subscriptionInfo = freezed,
|
||||||
Object? autoUpdate = null,
|
Object? autoUpdate = null,
|
||||||
Object? selectedMap = null,
|
Object? selectedMap = null,
|
||||||
Object? unfoldSet = null,
|
Object? unfoldSet = null,
|
||||||
@@ -302,10 +323,10 @@ class _$ProfileCopyWithImpl<$Res, $Val extends Profile>
|
|||||||
? _value.autoUpdateDuration
|
? _value.autoUpdateDuration
|
||||||
: autoUpdateDuration // ignore: cast_nullable_to_non_nullable
|
: autoUpdateDuration // ignore: cast_nullable_to_non_nullable
|
||||||
as Duration,
|
as Duration,
|
||||||
userInfo: freezed == userInfo
|
subscriptionInfo: freezed == subscriptionInfo
|
||||||
? _value.userInfo
|
? _value.subscriptionInfo
|
||||||
: userInfo // ignore: cast_nullable_to_non_nullable
|
: subscriptionInfo // ignore: cast_nullable_to_non_nullable
|
||||||
as UserInfo?,
|
as SubscriptionInfo?,
|
||||||
autoUpdate: null == autoUpdate
|
autoUpdate: null == autoUpdate
|
||||||
? _value.autoUpdate
|
? _value.autoUpdate
|
||||||
: autoUpdate // ignore: cast_nullable_to_non_nullable
|
: autoUpdate // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -325,15 +346,17 @@ class _$ProfileCopyWithImpl<$Res, $Val extends Profile>
|
|||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of Profile
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$UserInfoCopyWith<$Res>? get userInfo {
|
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo {
|
||||||
if (_value.userInfo == null) {
|
if (_value.subscriptionInfo == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $UserInfoCopyWith<$Res>(_value.userInfo!, (value) {
|
return $SubscriptionInfoCopyWith<$Res>(_value.subscriptionInfo!, (value) {
|
||||||
return _then(_value.copyWith(userInfo: value) as $Val);
|
return _then(_value.copyWith(subscriptionInfo: value) as $Val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,14 +375,14 @@ abstract class _$$ProfileImplCopyWith<$Res> implements $ProfileCopyWith<$Res> {
|
|||||||
String url,
|
String url,
|
||||||
DateTime? lastUpdateDate,
|
DateTime? lastUpdateDate,
|
||||||
Duration autoUpdateDuration,
|
Duration autoUpdateDuration,
|
||||||
UserInfo? userInfo,
|
SubscriptionInfo? subscriptionInfo,
|
||||||
bool autoUpdate,
|
bool autoUpdate,
|
||||||
Map<String, String> selectedMap,
|
Map<String, String> selectedMap,
|
||||||
Set<String> unfoldSet,
|
Set<String> unfoldSet,
|
||||||
@JsonKey(includeToJson: false, includeFromJson: false) bool isUpdating});
|
@JsonKey(includeToJson: false, includeFromJson: false) bool isUpdating});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$UserInfoCopyWith<$Res>? get userInfo;
|
$SubscriptionInfoCopyWith<$Res>? get subscriptionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -370,6 +393,8 @@ class __$$ProfileImplCopyWithImpl<$Res>
|
|||||||
_$ProfileImpl _value, $Res Function(_$ProfileImpl) _then)
|
_$ProfileImpl _value, $Res Function(_$ProfileImpl) _then)
|
||||||
: super(_value, _then);
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of Profile
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
@@ -379,7 +404,7 @@ class __$$ProfileImplCopyWithImpl<$Res>
|
|||||||
Object? url = null,
|
Object? url = null,
|
||||||
Object? lastUpdateDate = freezed,
|
Object? lastUpdateDate = freezed,
|
||||||
Object? autoUpdateDuration = null,
|
Object? autoUpdateDuration = null,
|
||||||
Object? userInfo = freezed,
|
Object? subscriptionInfo = freezed,
|
||||||
Object? autoUpdate = null,
|
Object? autoUpdate = null,
|
||||||
Object? selectedMap = null,
|
Object? selectedMap = null,
|
||||||
Object? unfoldSet = null,
|
Object? unfoldSet = null,
|
||||||
@@ -410,10 +435,10 @@ class __$$ProfileImplCopyWithImpl<$Res>
|
|||||||
? _value.autoUpdateDuration
|
? _value.autoUpdateDuration
|
||||||
: autoUpdateDuration // ignore: cast_nullable_to_non_nullable
|
: autoUpdateDuration // ignore: cast_nullable_to_non_nullable
|
||||||
as Duration,
|
as Duration,
|
||||||
userInfo: freezed == userInfo
|
subscriptionInfo: freezed == subscriptionInfo
|
||||||
? _value.userInfo
|
? _value.subscriptionInfo
|
||||||
: userInfo // ignore: cast_nullable_to_non_nullable
|
: subscriptionInfo // ignore: cast_nullable_to_non_nullable
|
||||||
as UserInfo?,
|
as SubscriptionInfo?,
|
||||||
autoUpdate: null == autoUpdate
|
autoUpdate: null == autoUpdate
|
||||||
? _value.autoUpdate
|
? _value.autoUpdate
|
||||||
: autoUpdate // ignore: cast_nullable_to_non_nullable
|
: autoUpdate // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -444,7 +469,7 @@ class _$ProfileImpl implements _Profile {
|
|||||||
this.url = "",
|
this.url = "",
|
||||||
this.lastUpdateDate,
|
this.lastUpdateDate,
|
||||||
required this.autoUpdateDuration,
|
required this.autoUpdateDuration,
|
||||||
this.userInfo,
|
this.subscriptionInfo,
|
||||||
this.autoUpdate = true,
|
this.autoUpdate = true,
|
||||||
final Map<String, String> selectedMap = const {},
|
final Map<String, String> selectedMap = const {},
|
||||||
final Set<String> unfoldSet = const {},
|
final Set<String> unfoldSet = const {},
|
||||||
@@ -470,7 +495,7 @@ class _$ProfileImpl implements _Profile {
|
|||||||
@override
|
@override
|
||||||
final Duration autoUpdateDuration;
|
final Duration autoUpdateDuration;
|
||||||
@override
|
@override
|
||||||
final UserInfo? userInfo;
|
final SubscriptionInfo? subscriptionInfo;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final bool autoUpdate;
|
final bool autoUpdate;
|
||||||
@@ -498,7 +523,7 @@ class _$ProfileImpl implements _Profile {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Profile(id: $id, label: $label, currentGroupName: $currentGroupName, url: $url, lastUpdateDate: $lastUpdateDate, autoUpdateDuration: $autoUpdateDuration, userInfo: $userInfo, autoUpdate: $autoUpdate, selectedMap: $selectedMap, unfoldSet: $unfoldSet, isUpdating: $isUpdating)';
|
return 'Profile(id: $id, label: $label, currentGroupName: $currentGroupName, url: $url, lastUpdateDate: $lastUpdateDate, autoUpdateDuration: $autoUpdateDuration, subscriptionInfo: $subscriptionInfo, autoUpdate: $autoUpdate, selectedMap: $selectedMap, unfoldSet: $unfoldSet, isUpdating: $isUpdating)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -515,8 +540,8 @@ class _$ProfileImpl implements _Profile {
|
|||||||
other.lastUpdateDate == lastUpdateDate) &&
|
other.lastUpdateDate == lastUpdateDate) &&
|
||||||
(identical(other.autoUpdateDuration, autoUpdateDuration) ||
|
(identical(other.autoUpdateDuration, autoUpdateDuration) ||
|
||||||
other.autoUpdateDuration == autoUpdateDuration) &&
|
other.autoUpdateDuration == autoUpdateDuration) &&
|
||||||
(identical(other.userInfo, userInfo) ||
|
(identical(other.subscriptionInfo, subscriptionInfo) ||
|
||||||
other.userInfo == userInfo) &&
|
other.subscriptionInfo == subscriptionInfo) &&
|
||||||
(identical(other.autoUpdate, autoUpdate) ||
|
(identical(other.autoUpdate, autoUpdate) ||
|
||||||
other.autoUpdate == autoUpdate) &&
|
other.autoUpdate == autoUpdate) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
@@ -527,7 +552,7 @@ class _$ProfileImpl implements _Profile {
|
|||||||
other.isUpdating == isUpdating));
|
other.isUpdating == isUpdating));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
@@ -537,13 +562,15 @@ class _$ProfileImpl implements _Profile {
|
|||||||
url,
|
url,
|
||||||
lastUpdateDate,
|
lastUpdateDate,
|
||||||
autoUpdateDuration,
|
autoUpdateDuration,
|
||||||
userInfo,
|
subscriptionInfo,
|
||||||
autoUpdate,
|
autoUpdate,
|
||||||
const DeepCollectionEquality().hash(_selectedMap),
|
const DeepCollectionEquality().hash(_selectedMap),
|
||||||
const DeepCollectionEquality().hash(_unfoldSet),
|
const DeepCollectionEquality().hash(_unfoldSet),
|
||||||
isUpdating);
|
isUpdating);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of Profile
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$$ProfileImplCopyWith<_$ProfileImpl> get copyWith =>
|
_$$ProfileImplCopyWith<_$ProfileImpl> get copyWith =>
|
||||||
@@ -565,7 +592,7 @@ abstract class _Profile implements Profile {
|
|||||||
final String url,
|
final String url,
|
||||||
final DateTime? lastUpdateDate,
|
final DateTime? lastUpdateDate,
|
||||||
required final Duration autoUpdateDuration,
|
required final Duration autoUpdateDuration,
|
||||||
final UserInfo? userInfo,
|
final SubscriptionInfo? subscriptionInfo,
|
||||||
final bool autoUpdate,
|
final bool autoUpdate,
|
||||||
final Map<String, String> selectedMap,
|
final Map<String, String> selectedMap,
|
||||||
final Set<String> unfoldSet,
|
final Set<String> unfoldSet,
|
||||||
@@ -587,7 +614,7 @@ abstract class _Profile implements Profile {
|
|||||||
@override
|
@override
|
||||||
Duration get autoUpdateDuration;
|
Duration get autoUpdateDuration;
|
||||||
@override
|
@override
|
||||||
UserInfo? get userInfo;
|
SubscriptionInfo? get subscriptionInfo;
|
||||||
@override
|
@override
|
||||||
bool get autoUpdate;
|
bool get autoUpdate;
|
||||||
@override
|
@override
|
||||||
@@ -597,8 +624,11 @@ abstract class _Profile implements Profile {
|
|||||||
@override
|
@override
|
||||||
@JsonKey(includeToJson: false, includeFromJson: false)
|
@JsonKey(includeToJson: false, includeFromJson: false)
|
||||||
bool get isUpdating;
|
bool get isUpdating;
|
||||||
|
|
||||||
|
/// Create a copy of Profile
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$ProfileImplCopyWith<_$ProfileImpl> get copyWith =>
|
_$$ProfileImplCopyWith<_$ProfileImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,17 @@ part of '../profile.dart';
|
|||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
_$UserInfoImpl _$$UserInfoImplFromJson(Map<String, dynamic> json) =>
|
_$SubscriptionInfoImpl _$$SubscriptionInfoImplFromJson(
|
||||||
_$UserInfoImpl(
|
Map<String, dynamic> json) =>
|
||||||
|
_$SubscriptionInfoImpl(
|
||||||
upload: (json['upload'] as num?)?.toInt() ?? 0,
|
upload: (json['upload'] as num?)?.toInt() ?? 0,
|
||||||
download: (json['download'] as num?)?.toInt() ?? 0,
|
download: (json['download'] as num?)?.toInt() ?? 0,
|
||||||
total: (json['total'] as num?)?.toInt() ?? 0,
|
total: (json['total'] as num?)?.toInt() ?? 0,
|
||||||
expire: (json['expire'] as num?)?.toInt() ?? 0,
|
expire: (json['expire'] as num?)?.toInt() ?? 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$UserInfoImplToJson(_$UserInfoImpl instance) =>
|
Map<String, dynamic> _$$SubscriptionInfoImplToJson(
|
||||||
|
_$SubscriptionInfoImpl instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'upload': instance.upload,
|
'upload': instance.upload,
|
||||||
'download': instance.download,
|
'download': instance.download,
|
||||||
@@ -33,9 +35,10 @@ _$ProfileImpl _$$ProfileImplFromJson(Map<String, dynamic> json) =>
|
|||||||
: DateTime.parse(json['lastUpdateDate'] as String),
|
: DateTime.parse(json['lastUpdateDate'] as String),
|
||||||
autoUpdateDuration:
|
autoUpdateDuration:
|
||||||
Duration(microseconds: (json['autoUpdateDuration'] as num).toInt()),
|
Duration(microseconds: (json['autoUpdateDuration'] as num).toInt()),
|
||||||
userInfo: json['userInfo'] == null
|
subscriptionInfo: json['subscriptionInfo'] == null
|
||||||
? null
|
? null
|
||||||
: UserInfo.fromJson(json['userInfo'] as Map<String, dynamic>),
|
: SubscriptionInfo.fromJson(
|
||||||
|
json['subscriptionInfo'] as Map<String, dynamic>),
|
||||||
autoUpdate: json['autoUpdate'] as bool? ?? true,
|
autoUpdate: json['autoUpdate'] as bool? ?? true,
|
||||||
selectedMap: (json['selectedMap'] as Map<String, dynamic>?)?.map(
|
selectedMap: (json['selectedMap'] as Map<String, dynamic>?)?.map(
|
||||||
(k, e) => MapEntry(k, e as String),
|
(k, e) => MapEntry(k, e as String),
|
||||||
@@ -55,7 +58,7 @@ Map<String, dynamic> _$$ProfileImplToJson(_$ProfileImpl instance) =>
|
|||||||
'url': instance.url,
|
'url': instance.url,
|
||||||
'lastUpdateDate': instance.lastUpdateDate?.toIso8601String(),
|
'lastUpdateDate': instance.lastUpdateDate?.toIso8601String(),
|
||||||
'autoUpdateDuration': instance.autoUpdateDuration.inMicroseconds,
|
'autoUpdateDuration': instance.autoUpdateDuration.inMicroseconds,
|
||||||
'userInfo': instance.userInfo,
|
'subscriptionInfo': instance.subscriptionInfo,
|
||||||
'autoUpdate': instance.autoUpdate,
|
'autoUpdate': instance.autoUpdate,
|
||||||
'selectedMap': instance.selectedMap,
|
'selectedMap': instance.selectedMap,
|
||||||
'unfoldSet': instance.unfoldSet.toList(),
|
'unfoldSet': instance.unfoldSet.toList(),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,37 +4,36 @@ import 'dart:io';
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:fl_clash/clash/core.dart';
|
import 'package:fl_clash/clash/core.dart';
|
||||||
import 'package:fl_clash/enum/enum.dart';
|
|
||||||
import 'package:fl_clash/common/common.dart';
|
import 'package:fl_clash/common/common.dart';
|
||||||
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'generated/profile.g.dart';
|
|
||||||
|
|
||||||
part 'generated/profile.freezed.dart';
|
part 'generated/profile.freezed.dart';
|
||||||
|
part 'generated/profile.g.dart';
|
||||||
|
|
||||||
typedef SelectedMap = Map<String, String>;
|
typedef SelectedMap = Map<String, String>;
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class UserInfo with _$UserInfo {
|
class SubscriptionInfo with _$SubscriptionInfo {
|
||||||
const factory UserInfo({
|
const factory SubscriptionInfo({
|
||||||
@Default(0) int upload,
|
@Default(0) int upload,
|
||||||
@Default(0) int download,
|
@Default(0) int download,
|
||||||
@Default(0) int total,
|
@Default(0) int total,
|
||||||
@Default(0) int expire,
|
@Default(0) int expire,
|
||||||
}) = _UserInfo;
|
}) = _SubscriptionInfo;
|
||||||
|
|
||||||
factory UserInfo.fromJson(Map<String, Object?> json) =>
|
factory SubscriptionInfo.fromJson(Map<String, Object?> json) =>
|
||||||
_$UserInfoFromJson(json);
|
_$SubscriptionInfoFromJson(json);
|
||||||
|
|
||||||
factory UserInfo.formHString(String? info) {
|
factory SubscriptionInfo.formHString(String? info) {
|
||||||
if (info == null) return const UserInfo();
|
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 UserInfo(
|
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,
|
||||||
@@ -52,7 +51,7 @@ class Profile with _$Profile {
|
|||||||
@Default("") String url,
|
@Default("") String url,
|
||||||
DateTime? lastUpdateDate,
|
DateTime? lastUpdateDate,
|
||||||
required Duration autoUpdateDuration,
|
required Duration autoUpdateDuration,
|
||||||
UserInfo? userInfo,
|
SubscriptionInfo? subscriptionInfo,
|
||||||
@Default(true) bool autoUpdate,
|
@Default(true) bool autoUpdate,
|
||||||
@Default({}) SelectedMap selectedMap,
|
@Default({}) SelectedMap selectedMap,
|
||||||
@Default({}) Set<String> unfoldSet,
|
@Default({}) Set<String> unfoldSet,
|
||||||
@@ -103,7 +102,7 @@ extension ProfileExtension on Profile {
|
|||||||
final userinfo = response.headers.value('subscription-userinfo');
|
final userinfo = response.headers.value('subscription-userinfo');
|
||||||
return await copyWith(
|
return await copyWith(
|
||||||
label: label ?? other.getFileNameForDisposition(disposition) ?? id,
|
label: label ?? other.getFileNameForDisposition(disposition) ?? id,
|
||||||
userInfo: UserInfo.formHString(userinfo),
|
subscriptionInfo: SubscriptionInfo.formHString(userinfo),
|
||||||
).saveFile(response.data);
|
).saveFile(response.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ class ProxyState with _$ProxyState {
|
|||||||
const factory ProxyState({
|
const factory ProxyState({
|
||||||
required bool isStart,
|
required bool isStart,
|
||||||
required bool systemProxy,
|
required bool systemProxy,
|
||||||
|
required List<String> bassDomain,
|
||||||
required int port,
|
required int port,
|
||||||
}) = _ProxyState;
|
}) = _ProxyState;
|
||||||
}
|
}
|
||||||
@@ -218,8 +219,6 @@ class HttpOverridesState with _$HttpOverridesState {
|
|||||||
}) = _HttpOverridesState;
|
}) = _HttpOverridesState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ClashConfigState with _$ClashConfigState {
|
class ClashConfigState with _$ClashConfigState {
|
||||||
const factory ClashConfigState({
|
const factory ClashConfigState({
|
||||||
@@ -251,4 +250,4 @@ class VPNState with _$VPNState {
|
|||||||
required TunStack stack,
|
required TunStack stack,
|
||||||
required VpnProps vpnProps,
|
required VpnProps vpnProps,
|
||||||
}) = _VPNState;
|
}) = _VPNState;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:convert';
|
|||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:fl_clash/clash/clash.dart';
|
import 'package:fl_clash/clash/clash.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';
|
||||||
|
|||||||
161
lib/state.dart
161
lib/state.dart
@@ -3,16 +3,19 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
import 'package:fl_clash/clash/clash.dart';
|
import 'package:fl_clash/clash/clash.dart';
|
||||||
|
import 'package:fl_clash/enum/enum.dart';
|
||||||
import 'package:fl_clash/plugins/service.dart';
|
import 'package:fl_clash/plugins/service.dart';
|
||||||
import 'package:fl_clash/plugins/vpn.dart';
|
import 'package:fl_clash/plugins/vpn.dart';
|
||||||
import 'package:fl_clash/widgets/scaffold.dart';
|
import 'package:fl_clash/widgets/scaffold.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
import 'package:tray_manager/tray_manager.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
import 'common/common.dart';
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
import 'models/models.dart';
|
import 'models/models.dart';
|
||||||
import 'common/common.dart';
|
|
||||||
|
|
||||||
class GlobalState {
|
class GlobalState {
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
@@ -101,6 +104,7 @@ class GlobalState {
|
|||||||
required Config config,
|
required Config config,
|
||||||
required ClashConfig clashConfig,
|
required ClashConfig clashConfig,
|
||||||
}) async {
|
}) async {
|
||||||
|
clashCore.requestGc();
|
||||||
await updateClashConfig(
|
await updateClashConfig(
|
||||||
clashConfig: clashConfig,
|
clashConfig: clashConfig,
|
||||||
config: config,
|
config: config,
|
||||||
@@ -126,19 +130,22 @@ class GlobalState {
|
|||||||
clashConfig: clashConfig,
|
clashConfig: clashConfig,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
clashCore.setState(
|
if (Platform.isAndroid && !isVpnService) {
|
||||||
CoreState(
|
clashCore.setState(
|
||||||
enable: config.vpnProps.enable,
|
CoreState(
|
||||||
accessControl: config.isAccessControl ? config.accessControl : null,
|
enable: config.vpnProps.enable,
|
||||||
ipv6: config.vpnProps.ipv6,
|
accessControl: config.isAccessControl ? config.accessControl : null,
|
||||||
allowBypass: config.vpnProps.allowBypass,
|
ipv6: config.vpnProps.ipv6,
|
||||||
systemProxy: config.vpnProps.systemProxy,
|
allowBypass: config.vpnProps.allowBypass,
|
||||||
onlyProxy: config.appSetting.onlyProxy,
|
systemProxy: config.vpnProps.systemProxy,
|
||||||
bypassDomain: config.vpnProps.bypassDomain,
|
onlyProxy: config.appSetting.onlyProxy,
|
||||||
currentProfileName:
|
bypassDomain: config.networkProps.bypassDomain,
|
||||||
config.currentProfile?.label ?? config.currentProfileId ?? "",
|
routeAddress: clashConfig.routeAddress,
|
||||||
),
|
currentProfileName:
|
||||||
);
|
config.currentProfile?.label ?? config.currentProfileId ?? "",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
updateCoreVersionInfo(appState);
|
updateCoreVersionInfo(appState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,6 +301,132 @@ class GlobalState {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future _updateSystemTray({
|
||||||
|
required Brightness? brightness,
|
||||||
|
bool force = false,
|
||||||
|
}) async {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Platform.isLinux || force) {
|
||||||
|
await trayManager.destroy();
|
||||||
|
}
|
||||||
|
await trayManager.setIcon(
|
||||||
|
other.getTrayIconPath(
|
||||||
|
brightness: brightness ??
|
||||||
|
WidgetsBinding.instance.platformDispatcher.platformBrightness,
|
||||||
|
),
|
||||||
|
isTemplate: true,
|
||||||
|
);
|
||||||
|
if (!Platform.isLinux) {
|
||||||
|
await trayManager.setToolTip(
|
||||||
|
appName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTray({
|
||||||
|
required AppState appState,
|
||||||
|
required AppFlowingState appFlowingState,
|
||||||
|
required Config config,
|
||||||
|
required ClashConfig clashConfig,
|
||||||
|
bool focus = false,
|
||||||
|
}) async {
|
||||||
|
if (!Platform.isLinux) {
|
||||||
|
await _updateSystemTray(
|
||||||
|
brightness: appState.brightness,
|
||||||
|
force: focus,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
List<MenuItem> menuItems = [];
|
||||||
|
final showMenuItem = MenuItem(
|
||||||
|
label: appLocalizations.show,
|
||||||
|
onClick: (_) {
|
||||||
|
window?.show();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
menuItems.add(showMenuItem);
|
||||||
|
final startMenuItem = MenuItem.checkbox(
|
||||||
|
label: appFlowingState.isStart
|
||||||
|
? appLocalizations.stop
|
||||||
|
: appLocalizations.start,
|
||||||
|
onClick: (_) async {
|
||||||
|
globalState.appController.updateStart();
|
||||||
|
},
|
||||||
|
checked: false,
|
||||||
|
);
|
||||||
|
menuItems.add(startMenuItem);
|
||||||
|
menuItems.add(MenuItem.separator());
|
||||||
|
for (final mode in Mode.values) {
|
||||||
|
menuItems.add(
|
||||||
|
MenuItem.checkbox(
|
||||||
|
label: Intl.message(mode.name),
|
||||||
|
onClick: (_) {
|
||||||
|
globalState.appController.clashConfig.mode = mode;
|
||||||
|
},
|
||||||
|
checked: mode == clashConfig.mode,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
menuItems.add(MenuItem.separator());
|
||||||
|
if (appFlowingState.isStart) {
|
||||||
|
menuItems.add(
|
||||||
|
MenuItem.checkbox(
|
||||||
|
label: appLocalizations.tun,
|
||||||
|
onClick: (_) {
|
||||||
|
globalState.appController.updateTun();
|
||||||
|
},
|
||||||
|
checked: clashConfig.tun.enable,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
menuItems.add(
|
||||||
|
MenuItem.checkbox(
|
||||||
|
label: appLocalizations.systemProxy,
|
||||||
|
onClick: (_) {
|
||||||
|
globalState.appController.updateSystemProxy();
|
||||||
|
},
|
||||||
|
checked: config.networkProps.systemProxy,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
menuItems.add(MenuItem.separator());
|
||||||
|
}
|
||||||
|
final autoStartMenuItem = MenuItem.checkbox(
|
||||||
|
label: appLocalizations.autoLaunch,
|
||||||
|
onClick: (_) async {
|
||||||
|
globalState.appController.updateAutoLaunch();
|
||||||
|
},
|
||||||
|
checked: config.appSetting.autoLaunch,
|
||||||
|
);
|
||||||
|
menuItems.add(autoStartMenuItem);
|
||||||
|
|
||||||
|
if (Platform.isWindows) {
|
||||||
|
final adminAutoStartMenuItem = MenuItem.checkbox(
|
||||||
|
label: appLocalizations.adminAutoLaunch,
|
||||||
|
onClick: (_) async {
|
||||||
|
globalState.appController.updateAdminAutoLaunch();
|
||||||
|
},
|
||||||
|
checked: config.appSetting.adminAutoLaunch,
|
||||||
|
);
|
||||||
|
menuItems.add(adminAutoStartMenuItem);
|
||||||
|
}
|
||||||
|
menuItems.add(MenuItem.separator());
|
||||||
|
final exitMenuItem = MenuItem(
|
||||||
|
label: appLocalizations.exit,
|
||||||
|
onClick: (_) async {
|
||||||
|
await globalState.appController.handleExit();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
menuItems.add(exitMenuItem);
|
||||||
|
final menu = Menu(items: menuItems);
|
||||||
|
await trayManager.setContextMenu(menu);
|
||||||
|
if (Platform.isLinux) {
|
||||||
|
await _updateSystemTray(
|
||||||
|
brightness: appState.brightness,
|
||||||
|
force: focus,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final globalState = GlobalState();
|
final globalState = GlobalState();
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
|
||||||
import 'package:fl_clash/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
@@ -19,7 +17,7 @@ class _PopContainerState extends State<BackScope> {
|
|||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
onPopInvoked: (_) async {
|
onPopInvokedWithResult: (_, __) async {
|
||||||
final canPop = Navigator.canPop(context);
|
final canPop = Navigator.canPop(context);
|
||||||
if (canPop) {
|
if (canPop) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import 'card.dart';
|
import 'card.dart';
|
||||||
import 'input.dart';
|
import 'input.dart';
|
||||||
import 'sheet.dart';
|
|
||||||
import 'scaffold.dart';
|
import 'scaffold.dart';
|
||||||
|
import 'sheet.dart';
|
||||||
|
|
||||||
class Delegate {
|
class Delegate {
|
||||||
const Delegate();
|
const Delegate();
|
||||||
@@ -360,11 +360,13 @@ class ListItem<T> extends StatelessWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseNavigator.push(context, CommonScaffold(
|
BaseNavigator.push(
|
||||||
key: Key(nextDelegate.title),
|
context,
|
||||||
body: nextDelegate.widget,
|
CommonScaffold(
|
||||||
title: nextDelegate.title,
|
key: Key(nextDelegate.title),
|
||||||
));
|
body: nextDelegate.widget,
|
||||||
|
title: nextDelegate.title,
|
||||||
|
));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -468,7 +470,7 @@ class ListHeader extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> generateSection({
|
List<Widget> generateSection({
|
||||||
required String title,
|
String? title,
|
||||||
required Iterable<Widget> items,
|
required Iterable<Widget> items,
|
||||||
List<Widget>? actions,
|
List<Widget>? actions,
|
||||||
bool separated = true,
|
bool separated = true,
|
||||||
@@ -481,7 +483,7 @@ List<Widget> generateSection({
|
|||||||
)
|
)
|
||||||
: items;
|
: items;
|
||||||
return [
|
return [
|
||||||
if (items.isNotEmpty)
|
if (items.isNotEmpty && title != null)
|
||||||
ListHeader(
|
ListHeader(
|
||||||
title: title,
|
title: title,
|
||||||
actions: actions,
|
actions: actions,
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ 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/state.dart';
|
import 'package:fl_clash/state.dart';
|
||||||
import 'package:fl_clash/widgets/scaffold.dart';
|
import 'package:fl_clash/widgets/scaffold.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'side_sheet.dart';
|
import 'side_sheet.dart';
|
||||||
|
|
||||||
showExtendPage(
|
showExtendPage(
|
||||||
|
|||||||
53
lib/widgets/subscription_info_view.dart
Normal file
53
lib/widgets/subscription_info_view.dart
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import 'package:fl_clash/common/common.dart';
|
||||||
|
import 'package:fl_clash/models/models.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SubscriptionInfoView extends StatelessWidget {
|
||||||
|
final SubscriptionInfo? subscriptionInfo;
|
||||||
|
|
||||||
|
const SubscriptionInfoView({
|
||||||
|
super.key,
|
||||||
|
this.subscriptionInfo,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (subscriptionInfo == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
if (subscriptionInfo?.total == 0) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
final use = subscriptionInfo!.upload + subscriptionInfo!.download;
|
||||||
|
final total = subscriptionInfo!.total;
|
||||||
|
final progress = use / total;
|
||||||
|
|
||||||
|
final useShow = TrafficValue(value: use).show;
|
||||||
|
final totalShow = TrafficValue(value: total).show;
|
||||||
|
final expireShow = subscriptionInfo?.expire != null &&
|
||||||
|
subscriptionInfo!.expire != 0
|
||||||
|
? DateTime.fromMillisecondsSinceEpoch(subscriptionInfo!.expire * 1000)
|
||||||
|
.show
|
||||||
|
: appLocalizations.infiniteTime;
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
LinearProgressIndicator(
|
||||||
|
minHeight: 6,
|
||||||
|
value: progress,
|
||||||
|
backgroundColor: context.colorScheme.primary.toSoft(),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"$useShow / $totalShow · $expireShow",
|
||||||
|
style: context.textTheme.labelMedium?.toLight,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,25 @@
|
|||||||
export 'scaffold.dart';
|
|
||||||
export 'float_layout.dart';
|
|
||||||
export 'popup_menu.dart';
|
|
||||||
export 'card.dart';
|
|
||||||
export 'list.dart';
|
|
||||||
export 'line_chart.dart';
|
|
||||||
export 'grid.dart';
|
|
||||||
export 'open_container.dart';
|
|
||||||
export 'color_scheme_box.dart';
|
|
||||||
export 'null_status.dart';
|
|
||||||
export 'disabled_mask.dart';
|
|
||||||
export 'side_sheet.dart';
|
|
||||||
export 'sheet.dart';
|
|
||||||
export 'animate_grid.dart';
|
export 'animate_grid.dart';
|
||||||
export 'chip.dart';
|
export 'back_scope.dart';
|
||||||
export 'fade_box.dart';
|
|
||||||
export 'text.dart';
|
|
||||||
export 'connection_item.dart';
|
|
||||||
export 'builder.dart';
|
export 'builder.dart';
|
||||||
export 'setting.dart';
|
export 'card.dart';
|
||||||
|
export 'chip.dart';
|
||||||
|
export 'color_scheme_box.dart';
|
||||||
|
export 'connection_item.dart';
|
||||||
|
export 'disabled_mask.dart';
|
||||||
|
export 'fade_box.dart';
|
||||||
|
export 'float_layout.dart';
|
||||||
|
export 'grid.dart';
|
||||||
|
export 'icon.dart';
|
||||||
export 'input.dart';
|
export 'input.dart';
|
||||||
export 'keep_scope.dart';
|
export 'keep_scope.dart';
|
||||||
export 'back_scope.dart';
|
export 'line_chart.dart';
|
||||||
export 'icon.dart';
|
export 'list.dart';
|
||||||
|
export 'null_status.dart';
|
||||||
|
export 'open_container.dart';
|
||||||
|
export 'popup_menu.dart';
|
||||||
|
export 'scaffold.dart';
|
||||||
|
export 'setting.dart';
|
||||||
|
export 'sheet.dart';
|
||||||
|
export 'side_sheet.dart';
|
||||||
|
export 'subscription_info_view.dart';
|
||||||
|
export 'text.dart';
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include <file_selector_linux/file_selector_plugin.h>
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
#include <gtk/gtk_plugin.h>
|
#include <gtk/gtk_plugin.h>
|
||||||
#include <hotkey_manager_linux/hotkey_manager_linux_plugin.h>
|
#include <hotkey_manager_linux/hotkey_manager_linux_plugin.h>
|
||||||
#include <screen_retriever/screen_retriever_plugin.h>
|
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
|
||||||
#include <tray_manager/tray_manager_plugin.h>
|
#include <tray_manager/tray_manager_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
#include <window_manager/window_manager_plugin.h>
|
#include <window_manager/window_manager_plugin.h>
|
||||||
@@ -28,9 +28,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||||||
g_autoptr(FlPluginRegistrar) hotkey_manager_linux_registrar =
|
g_autoptr(FlPluginRegistrar) hotkey_manager_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "HotkeyManagerLinuxPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "HotkeyManagerLinuxPlugin");
|
||||||
hotkey_manager_linux_plugin_register_with_registrar(hotkey_manager_linux_registrar);
|
hotkey_manager_linux_plugin_register_with_registrar(hotkey_manager_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
|
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
|
||||||
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
|
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) tray_manager_registrar =
|
g_autoptr(FlPluginRegistrar) tray_manager_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin");
|
||||||
tray_manager_plugin_register_with_registrar(tray_manager_registrar);
|
tray_manager_plugin_register_with_registrar(tray_manager_registrar);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
file_selector_linux
|
file_selector_linux
|
||||||
gtk
|
gtk
|
||||||
hotkey_manager_linux
|
hotkey_manager_linux
|
||||||
screen_retriever
|
screen_retriever_linux
|
||||||
tray_manager
|
tray_manager
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
window_manager
|
window_manager
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import FlutterMacOS
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import app_links
|
import app_links
|
||||||
|
import connectivity_plus
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
import dynamic_color
|
import dynamic_color
|
||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
@@ -13,15 +14,17 @@ import hotkey_manager_macos
|
|||||||
import mobile_scanner
|
import mobile_scanner
|
||||||
import package_info_plus
|
import package_info_plus
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
import screen_retriever
|
import screen_retriever_macos
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite
|
import sqflite_darwin
|
||||||
import tray_manager
|
import tray_manager
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
|
import window_ext
|
||||||
import window_manager
|
import window_manager
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
||||||
|
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
@@ -29,10 +32,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
|
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
|
||||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin"))
|
TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
|
WindowExtPlugin.register(with: registry.registrar(forPlugin: "WindowExtPlugin"))
|
||||||
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
import Cocoa
|
import Cocoa
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
|
import window_ext
|
||||||
|
|
||||||
@main
|
@main
|
||||||
class AppDelegate: FlutterAppDelegate {
|
class AppDelegate: FlutterAppDelegate {
|
||||||
|
|
||||||
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
|
override func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
|
||||||
if !flag {
|
WindowExtPlugin.instance?.handleShouldTerminate()
|
||||||
for window in NSApp.windows {
|
return .terminateCancel
|
||||||
if !window.isVisible {
|
}
|
||||||
window.setIsVisible(true)
|
|
||||||
}
|
override func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
|
||||||
window.makeKeyAndOrderFront(self)
|
if !flag {
|
||||||
NSApp.activate(ignoringOtherApps: true)
|
for window in NSApp.windows {
|
||||||
}
|
if !window.isVisible {
|
||||||
}
|
window.setIsVisible(true)
|
||||||
return true
|
}
|
||||||
}
|
window.makeKeyAndOrderFront(self)
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ class MainFlutterWindow: NSWindow {
|
|||||||
let windowFrame = self.frame
|
let windowFrame = self.frame
|
||||||
self.contentViewController = flutterViewController
|
self.contentViewController = flutterViewController
|
||||||
self.setFrame(windowFrame, display: true)
|
self.setFrame(windowFrame, display: true)
|
||||||
|
|
||||||
RegisterGeneratedPlugins(registry: flutterViewController)
|
RegisterGeneratedPlugins(registry: flutterViewController)
|
||||||
|
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
}
|
}
|
||||||
override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) {
|
override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) {
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'proxy_platform_interface.dart';
|
|
||||||
import "package:path/path.dart";
|
import "package:path/path.dart";
|
||||||
|
|
||||||
|
import 'proxy_platform_interface.dart';
|
||||||
|
|
||||||
enum ProxyTypes { http, https, socks }
|
enum ProxyTypes { http, https, socks }
|
||||||
|
|
||||||
class Proxy extends ProxyPlatform {
|
class Proxy extends ProxyPlatform {
|
||||||
static String url = "127.0.0.1";
|
static String url = "127.0.0.1";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool?> startProxy(int port) async {
|
Future<bool?> startProxy(
|
||||||
|
int port, [
|
||||||
|
List<String> bypassDomain = const [],
|
||||||
|
]) async {
|
||||||
return switch (Platform.operatingSystem) {
|
return switch (Platform.operatingSystem) {
|
||||||
"macos" => await _startProxyWithMacos(port),
|
"macos" => await _startProxyWithMacos(port, bypassDomain),
|
||||||
"linux" => await _startProxyWithLinux(port),
|
"linux" => await _startProxyWithLinux(port, bypassDomain),
|
||||||
"windows" => await ProxyPlatform.instance.startProxy(port),
|
"windows" => await ProxyPlatform.instance.startProxy(port, bypassDomain),
|
||||||
String() => false,
|
String() => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -28,48 +32,93 @@ class Proxy extends ProxyPlatform {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _startProxyWithLinux(int port) async {
|
Future<bool> _startProxyWithLinux(int port, List<String> bypassDomain) async {
|
||||||
try {
|
try {
|
||||||
final homeDir = Platform.environment['HOME']!;
|
final homeDir = Platform.environment['HOME']!;
|
||||||
final configDir = join(homeDir, ".config");
|
final configDir = join(homeDir, ".config");
|
||||||
final cmdList = List<List<String>>.empty(growable: true);
|
final cmdList = List<List<String>>.empty(growable: true);
|
||||||
final desktop = Platform.environment['XDG_CURRENT_DESKTOP'];
|
final desktop = Platform.environment['XDG_CURRENT_DESKTOP'];
|
||||||
final isKDE = desktop == "KDE";
|
final isKDE = desktop == "KDE";
|
||||||
for (final type in ProxyTypes.values) {
|
if (isKDE) {
|
||||||
|
cmdList.add(
|
||||||
|
[
|
||||||
|
"kwriteconfig5",
|
||||||
|
"--file",
|
||||||
|
"$configDir/kioslaverc",
|
||||||
|
"--group",
|
||||||
|
"Proxy Settings",
|
||||||
|
"--key",
|
||||||
|
"ProxyType",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
);
|
||||||
|
cmdList.add(
|
||||||
|
[
|
||||||
|
"kwriteconfig5",
|
||||||
|
"--file",
|
||||||
|
"$configDir/kioslaverc",
|
||||||
|
"--group",
|
||||||
|
"Proxy Settings",
|
||||||
|
"--key",
|
||||||
|
"NoProxyFor",
|
||||||
|
bypassDomain.join(",")
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
cmdList.add(
|
cmdList.add(
|
||||||
["gsettings", "set", "org.gnome.system.proxy", "mode", "manual"],
|
["gsettings", "set", "org.gnome.system.proxy", "mode", "manual"],
|
||||||
);
|
);
|
||||||
|
final ignoreHosts = "\"['${bypassDomain.join("', '")}']\"";
|
||||||
cmdList.add(
|
cmdList.add(
|
||||||
[
|
[
|
||||||
"gsettings",
|
"gsettings",
|
||||||
"set",
|
"set",
|
||||||
"org.gnome.system.proxy.${type.name}",
|
"org.gnome.system.proxy",
|
||||||
"host",
|
"ignore-hosts",
|
||||||
url
|
ignoreHosts
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
cmdList.add(
|
}
|
||||||
[
|
for (final type in ProxyTypes.values) {
|
||||||
"gsettings",
|
if (!isKDE) {
|
||||||
"set",
|
|
||||||
"org.gnome.system.proxy.${type.name}",
|
|
||||||
"port",
|
|
||||||
"$port"
|
|
||||||
],
|
|
||||||
);
|
|
||||||
if (isKDE) {
|
|
||||||
cmdList.add(
|
cmdList.add(
|
||||||
[
|
[
|
||||||
"kwriteconfig5",
|
"gsettings",
|
||||||
"--file",
|
"set",
|
||||||
"$configDir/kioslaverc",
|
"org.gnome.system.proxy.${type.name}",
|
||||||
"--group",
|
"host",
|
||||||
"Proxy Settings",
|
url
|
||||||
"--key",
|
|
||||||
"ProxyType",
|
|
||||||
"1"
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
cmdList.add(
|
||||||
|
[
|
||||||
|
"gsettings",
|
||||||
|
"set",
|
||||||
|
"org.gnome.system.proxy.${type.name}",
|
||||||
|
"port",
|
||||||
|
"$port"
|
||||||
|
],
|
||||||
|
);
|
||||||
|
cmdList.add(
|
||||||
|
[
|
||||||
|
"gsettings",
|
||||||
|
"set",
|
||||||
|
"org.gnome.system.proxy.${type.name}",
|
||||||
|
"port",
|
||||||
|
"$port"
|
||||||
|
],
|
||||||
|
);
|
||||||
|
cmdList.add(
|
||||||
|
[
|
||||||
|
"gsettings",
|
||||||
|
"set",
|
||||||
|
"org.gnome.system.proxy.${type.name}",
|
||||||
|
"port",
|
||||||
|
"$port"
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isKDE) {
|
||||||
cmdList.add(
|
cmdList.add(
|
||||||
[
|
[
|
||||||
"kwriteconfig5",
|
"kwriteconfig5",
|
||||||
@@ -100,19 +149,23 @@ class Proxy extends ProxyPlatform {
|
|||||||
final cmdList = List<List<String>>.empty(growable: true);
|
final cmdList = List<List<String>>.empty(growable: true);
|
||||||
final desktop = Platform.environment['XDG_CURRENT_DESKTOP'];
|
final desktop = Platform.environment['XDG_CURRENT_DESKTOP'];
|
||||||
final isKDE = desktop == "KDE";
|
final isKDE = desktop == "KDE";
|
||||||
cmdList
|
|
||||||
.add(["gsettings", "set", "org.gnome.system.proxy", "mode", "none"]);
|
|
||||||
if (isKDE) {
|
if (isKDE) {
|
||||||
cmdList.add([
|
cmdList.add(
|
||||||
"kwriteconfig5",
|
[
|
||||||
"--file",
|
"kwriteconfig5",
|
||||||
"$configDir/kioslaverc",
|
"--file",
|
||||||
"--group",
|
"$configDir/kioslaverc",
|
||||||
"Proxy Settings",
|
"--group",
|
||||||
"--key",
|
"Proxy Settings",
|
||||||
"ProxyType",
|
"--key",
|
||||||
"0"
|
"ProxyType",
|
||||||
]);
|
"0"
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
cmdList.add(
|
||||||
|
["gsettings", "set", "org.gnome.system.proxy", "mode", "none"],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
for (final cmd in cmdList) {
|
for (final cmd in cmdList) {
|
||||||
await Process.run(cmd[0], cmd.sublist(1));
|
await Process.run(cmd[0], cmd.sublist(1));
|
||||||
@@ -123,23 +176,43 @@ class Proxy extends ProxyPlatform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _startProxyWithMacos(int port) async {
|
Future<bool> _startProxyWithMacos(int port, List<String> bypassDomain) async {
|
||||||
try {
|
try {
|
||||||
final devices = await _getNetworkDeviceListWithMacos();
|
final devices = await _getNetworkDeviceListWithMacos();
|
||||||
for (final dev in devices) {
|
for (final dev in devices) {
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
Process.run(
|
Process.run(
|
||||||
"/usr/sbin/networksetup", ["-setwebproxystate", dev, "on"]),
|
"/usr/sbin/networksetup",
|
||||||
|
["-setwebproxystate", dev, "on"],
|
||||||
|
),
|
||||||
Process.run(
|
Process.run(
|
||||||
"/usr/sbin/networksetup", ["-setwebproxy", dev, url, "$port"]),
|
"/usr/sbin/networksetup",
|
||||||
|
["-setwebproxy", dev, url, "$port"],
|
||||||
|
),
|
||||||
Process.run(
|
Process.run(
|
||||||
"/usr/sbin/networksetup", ["-setsecurewebproxystate", dev, "on"]),
|
"/usr/sbin/networksetup",
|
||||||
Process.run("/usr/sbin/networksetup",
|
["-setsecurewebproxystate", dev, "on"],
|
||||||
["-setsecurewebproxy", dev, url, "$port"]),
|
),
|
||||||
Process.run("/usr/sbin/networksetup",
|
Process.run(
|
||||||
["-setsocksfirewallproxystate", dev, "on"]),
|
"/usr/sbin/networksetup",
|
||||||
Process.run("/usr/sbin/networksetup",
|
["-setsecurewebproxy", dev, url, "$port"],
|
||||||
["-setsocksfirewallproxy", dev, url, "$port"]),
|
),
|
||||||
|
Process.run(
|
||||||
|
"/usr/sbin/networksetup",
|
||||||
|
["-setsocksfirewallproxystate", dev, "on"],
|
||||||
|
),
|
||||||
|
Process.run(
|
||||||
|
"/usr/sbin/networksetup",
|
||||||
|
["-setsocksfirewallproxy", dev, url, "$port"],
|
||||||
|
),
|
||||||
|
Process.run(
|
||||||
|
"/usr/sbin/networksetup",
|
||||||
|
[
|
||||||
|
"-setproxybypassdomains",
|
||||||
|
dev,
|
||||||
|
bypassDomain.join(" "),
|
||||||
|
],
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -154,13 +227,25 @@ class Proxy extends ProxyPlatform {
|
|||||||
for (final dev in devices) {
|
for (final dev in devices) {
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
Process.run(
|
Process.run(
|
||||||
"/usr/sbin/networksetup", ["-setautoproxystate", dev, "off"]),
|
"/usr/sbin/networksetup",
|
||||||
|
["-setautoproxystate", dev, "off"],
|
||||||
|
),
|
||||||
Process.run(
|
Process.run(
|
||||||
"/usr/sbin/networksetup", ["-setwebproxystate", dev, "off"]),
|
"/usr/sbin/networksetup",
|
||||||
Process.run("/usr/sbin/networksetup",
|
["-setwebproxystate", dev, "off"],
|
||||||
["-setsecurewebproxystate", dev, "off"]),
|
),
|
||||||
Process.run("/usr/sbin/networksetup",
|
Process.run(
|
||||||
["-setsocksfirewallproxystate", dev, "off"]),
|
"/usr/sbin/networksetup",
|
||||||
|
["-setsecurewebproxystate", dev, "off"],
|
||||||
|
),
|
||||||
|
Process.run(
|
||||||
|
"/usr/sbin/networksetup",
|
||||||
|
["-setsocksfirewallproxystate", dev, "off"],
|
||||||
|
),
|
||||||
|
Process.run(
|
||||||
|
"/usr/sbin/networksetup",
|
||||||
|
["-setproxybypassdomains", dev, ""],
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -12,12 +12,15 @@ class MethodChannelProxy extends ProxyPlatform {
|
|||||||
MethodChannelProxy();
|
MethodChannelProxy();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool?> startProxy(int port) async {
|
Future<bool?> startProxy(int port, List<String> bypassDomain) async {
|
||||||
return await methodChannel.invokeMethod<bool>("StartProxy", {'port': port});
|
return await methodChannel.invokeMethod<bool>("StartProxy", {
|
||||||
|
'port': port,
|
||||||
|
'bypassDomain': bypassDomain,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool?> stopProxy() async {
|
Future<bool?> stopProxy() async {
|
||||||
return await methodChannel.invokeMethod<bool>("StopProxy");
|
return await methodChannel.invokeMethod<bool>("StopProxy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ abstract class ProxyPlatform extends PlatformInterface {
|
|||||||
_instance = instance;
|
_instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool?> startProxy(int port) {
|
Future<bool?> startProxy(int port, List<String> bypassDomain) {
|
||||||
throw UnimplementedError('startProxy() has not been implemented.');
|
throw UnimplementedError('startProxy() has not been implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,18 +22,32 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
void startProxy(const int port)
|
void startProxy(const int port, const flutter::EncodableList& bypassDomain)
|
||||||
{
|
{
|
||||||
INTERNET_PER_CONN_OPTION_LIST list;
|
INTERNET_PER_CONN_OPTION_LIST list;
|
||||||
DWORD dwBufSize = sizeof(list);
|
DWORD dwBufSize = sizeof(list);
|
||||||
list.dwSize = sizeof(list);
|
list.dwSize = sizeof(list);
|
||||||
list.pszConnection = nullptr;
|
list.pszConnection = nullptr;
|
||||||
|
|
||||||
auto url = "127.0.0.1:" + std::to_string(port);
|
auto url = "127.0.0.1:" + std::to_string(port);
|
||||||
auto wUrl = std::wstring(url.begin(), url.end());
|
auto wUrl = std::wstring(url.begin(), url.end());
|
||||||
auto fullAddr = new WCHAR[url.length() + 1];
|
auto fullAddr = new WCHAR[url.length() + 1];
|
||||||
wcscpy_s(fullAddr, url.length() + 1, wUrl.c_str());
|
wcscpy_s(fullAddr, url.length() + 1, wUrl.c_str());
|
||||||
list.dwOptionCount = 2;
|
|
||||||
list.pOptions = new INTERNET_PER_CONN_OPTION[2];
|
std::wstring wBypassList;
|
||||||
|
|
||||||
|
for (const auto& domain : bypassDomain) {
|
||||||
|
if (!wBypassList.empty()) {
|
||||||
|
wBypassList += L";";
|
||||||
|
}
|
||||||
|
wBypassList += std::wstring(std::get<std::string>(domain).begin(), std::get<std::string>(domain).end());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bypassAddr = new WCHAR[wBypassList.length() + 1];
|
||||||
|
wcscpy_s(bypassAddr, wBypassList.length() + 1, wBypassList.c_str());
|
||||||
|
|
||||||
|
list.dwOptionCount = 3;
|
||||||
|
list.pOptions = new INTERNET_PER_CONN_OPTION[3];
|
||||||
|
|
||||||
if (!list.pOptions)
|
if (!list.pOptions)
|
||||||
{
|
{
|
||||||
@@ -46,6 +60,9 @@ void startProxy(const int port)
|
|||||||
list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
|
list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
|
||||||
list.pOptions[1].Value.pszValue = fullAddr;
|
list.pOptions[1].Value.pszValue = fullAddr;
|
||||||
|
|
||||||
|
list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
|
||||||
|
list.pOptions[2].Value.pszValue = bypassAddr;
|
||||||
|
|
||||||
InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
|
InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
|
||||||
|
|
||||||
RASENTRYNAME entry;
|
RASENTRYNAME entry;
|
||||||
@@ -70,7 +87,11 @@ void startProxy(const int port)
|
|||||||
list.pszConnection = entryAddr[i].szEntryName;
|
list.pszConnection = entryAddr[i].szEntryName;
|
||||||
InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
|
InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] fullAddr;
|
||||||
|
delete[] bypassAddr;
|
||||||
delete[] list.pOptions;
|
delete[] list.pOptions;
|
||||||
|
|
||||||
InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
|
InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
|
||||||
InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
|
InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0);
|
||||||
}
|
}
|
||||||
@@ -160,7 +181,8 @@ namespace proxy
|
|||||||
{
|
{
|
||||||
auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
|
auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
|
||||||
auto port = std::get<int>(arguments->at(flutter::EncodableValue("port")));
|
auto port = std::get<int>(arguments->at(flutter::EncodableValue("port")));
|
||||||
startProxy(port);
|
auto bypassDomain = std::get<flutter::EncodableList>(arguments->at(flutter::EncodableValue("bypassDomain")));
|
||||||
|
startProxy(port, bypassDomain);
|
||||||
result->Success(true);
|
result->Success(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: "b0850beeb25f6d5b10426284f506557f66181b36"
|
revision: "603104015dd692ea3403755b55d07813d5cf8965"
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
|
||||||
project_type: plugin
|
project_type: plugin
|
||||||
@@ -13,11 +13,14 @@ project_type: plugin
|
|||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: b0850beeb25f6d5b10426284f506557f66181b36
|
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||||
base_revision: b0850beeb25f6d5b10426284f506557f66181b36
|
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||||
|
- platform: macos
|
||||||
|
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||||
|
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||||
- platform: windows
|
- platform: windows
|
||||||
create_revision: b0850beeb25f6d5b10426284f506557f66181b36
|
create_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||||
base_revision: b0850beeb25f6d5b10426284f506557f66181b36
|
base_revision: 603104015dd692ea3403755b55d07813d5cf8965
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|||||||
43
plugins/window_ext/example/.gitignore
vendored
43
plugins/window_ext/example/.gitignore
vendored
@@ -1,43 +0,0 @@
|
|||||||
# Miscellaneous
|
|
||||||
*.class
|
|
||||||
*.log
|
|
||||||
*.pyc
|
|
||||||
*.swp
|
|
||||||
.DS_Store
|
|
||||||
.atom/
|
|
||||||
.buildlog/
|
|
||||||
.history
|
|
||||||
.svn/
|
|
||||||
migrate_working_dir/
|
|
||||||
|
|
||||||
# IntelliJ related
|
|
||||||
*.iml
|
|
||||||
*.ipr
|
|
||||||
*.iws
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# The .vscode folder contains launch configuration and tasks you configure in
|
|
||||||
# VS Code which you may wish to be included in version control, so this line
|
|
||||||
# is commented out by default.
|
|
||||||
#.vscode/
|
|
||||||
|
|
||||||
# Flutter/Dart/Pub related
|
|
||||||
**/doc/api/
|
|
||||||
**/ios/Flutter/.last_build_id
|
|
||||||
.dart_tool/
|
|
||||||
.flutter-plugins
|
|
||||||
.flutter-plugins-dependencies
|
|
||||||
.pub-cache/
|
|
||||||
.pub/
|
|
||||||
/build/
|
|
||||||
|
|
||||||
# Symbolication related
|
|
||||||
app.*.symbols
|
|
||||||
|
|
||||||
# Obfuscation related
|
|
||||||
app.*.map.json
|
|
||||||
|
|
||||||
# Android Studio will place build artifacts here
|
|
||||||
/android/app/debug
|
|
||||||
/android/app/profile
|
|
||||||
/android/app/release
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# window_ext_example
|
|
||||||
|
|
||||||
Demonstrates how to use the window_ext plugin.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
This project is a starting point for a Flutter application.
|
|
||||||
|
|
||||||
A few resources to get you started if this is your first Flutter project:
|
|
||||||
|
|
||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
|
||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
|
||||||
|
|
||||||
For help getting started with Flutter development, view the
|
|
||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
|
||||||
samples, guidance on mobile development, and a full API reference.
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# This file configures the analyzer, which statically analyzes Dart code to
|
|
||||||
# check for errors, warnings, and lints.
|
|
||||||
#
|
|
||||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
|
||||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
|
||||||
# invoked from the command line by running `flutter analyze`.
|
|
||||||
|
|
||||||
# The following line activates a set of recommended lints for Flutter apps,
|
|
||||||
# packages, and plugins designed to encourage good coding practices.
|
|
||||||
include: package:flutter_lints/flutter.yaml
|
|
||||||
|
|
||||||
linter:
|
|
||||||
# The lint rules applied to this project can be customized in the
|
|
||||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
|
||||||
# included above or to enable additional rules. A list of all available lints
|
|
||||||
# and their documentation is published at https://dart.dev/lints.
|
|
||||||
#
|
|
||||||
# Instead of disabling a lint rule for the entire project in the
|
|
||||||
# section below, it can also be suppressed for a single line of code
|
|
||||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
|
||||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
|
||||||
# producing the lint.
|
|
||||||
rules:
|
|
||||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
|
||||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
|
||||||
|
|
||||||
# Additional information about this file can be found at
|
|
||||||
# https://dart.dev/guides/language/analysis-options
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
// This is a basic Flutter integration test.
|
|
||||||
//
|
|
||||||
// Since integration tests run in a full Flutter application, they can interact
|
|
||||||
// with the host side of a plugin implementation, unlike Dart unit tests.
|
|
||||||
//
|
|
||||||
// For more information about Flutter integration tests, please see
|
|
||||||
// https://docs.flutter.dev/cookbook/testing/integration/introduction
|
|
||||||
|
|
||||||
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:integration_test/integration_test.dart';
|
|
||||||
|
|
||||||
import 'package:window_ext/window_ext.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
testWidgets('getPlatformVersion test', (WidgetTester tester) async {
|
|
||||||
final WindowExt plugin = WindowExt();
|
|
||||||
final String? version = await plugin.getPlatformVersion();
|
|
||||||
// The version string depends on the host platform running the test, so
|
|
||||||
// just assert that some non-empty string is returned.
|
|
||||||
expect(version?.isNotEmpty, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:window_ext/window_ext.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
runApp(const MyApp());
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyApp extends StatefulWidget {
|
|
||||||
const MyApp({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MyApp> createState() => _MyAppState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
|
||||||
String _platformVersion = 'Unknown';
|
|
||||||
final _windowExtPlugin = WindowExt();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
initPlatformState();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Platform messages are asynchronous, so we initialize in an async method.
|
|
||||||
Future<void> initPlatformState() async {
|
|
||||||
String platformVersion;
|
|
||||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
|
||||||
// We also handle the message potentially returning null.
|
|
||||||
try {
|
|
||||||
platformVersion =
|
|
||||||
await _windowExtPlugin.getPlatformVersion() ?? 'Unknown platform version';
|
|
||||||
} on PlatformException {
|
|
||||||
platformVersion = 'Failed to get platform version.';
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the widget was removed from the tree while the asynchronous platform
|
|
||||||
// message was in flight, we want to discard the reply rather than calling
|
|
||||||
// setState to update our non-existent appearance.
|
|
||||||
if (!mounted) return;
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
_platformVersion = platformVersion;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return MaterialApp(
|
|
||||||
home: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Text('Plugin example app'),
|
|
||||||
),
|
|
||||||
body: Center(
|
|
||||||
child: Text('Running on: $_platformVersion\n'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,283 +0,0 @@
|
|||||||
# Generated by pub
|
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
|
||||||
packages:
|
|
||||||
async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: async
|
|
||||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.11.0"
|
|
||||||
boolean_selector:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: boolean_selector
|
|
||||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.1"
|
|
||||||
characters:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: characters
|
|
||||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.0"
|
|
||||||
clock:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: clock
|
|
||||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.1"
|
|
||||||
collection:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: collection
|
|
||||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.18.0"
|
|
||||||
cupertino_icons:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: cupertino_icons
|
|
||||||
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.8"
|
|
||||||
fake_async:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fake_async
|
|
||||||
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
file:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: file
|
|
||||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.0.0"
|
|
||||||
flutter:
|
|
||||||
dependency: "direct main"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_driver:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
flutter_lints:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_lints
|
|
||||||
sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.2"
|
|
||||||
flutter_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
fuchsia_remote_debug_protocol:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
integration_test:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.0"
|
|
||||||
leak_tracker:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: leak_tracker
|
|
||||||
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "10.0.4"
|
|
||||||
leak_tracker_flutter_testing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: leak_tracker_flutter_testing
|
|
||||||
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.3"
|
|
||||||
leak_tracker_testing:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: leak_tracker_testing
|
|
||||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.1"
|
|
||||||
lints:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lints
|
|
||||||
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
matcher:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: matcher
|
|
||||||
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.12.16+1"
|
|
||||||
material_color_utilities:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: material_color_utilities
|
|
||||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.8.0"
|
|
||||||
meta:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: meta
|
|
||||||
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.12.0"
|
|
||||||
path:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path
|
|
||||||
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.9.0"
|
|
||||||
platform:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: platform
|
|
||||||
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.4"
|
|
||||||
plugin_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: plugin_platform_interface
|
|
||||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.8"
|
|
||||||
process:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: process
|
|
||||||
sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "5.0.2"
|
|
||||||
sky_engine:
|
|
||||||
dependency: transitive
|
|
||||||
description: flutter
|
|
||||||
source: sdk
|
|
||||||
version: "0.0.99"
|
|
||||||
source_span:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: source_span
|
|
||||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.10.0"
|
|
||||||
stack_trace:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stack_trace
|
|
||||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.11.1"
|
|
||||||
stream_channel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: stream_channel
|
|
||||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.2"
|
|
||||||
string_scanner:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: string_scanner
|
|
||||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
sync_http:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sync_http
|
|
||||||
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.1"
|
|
||||||
term_glyph:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: term_glyph
|
|
||||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.1"
|
|
||||||
test_api:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: test_api
|
|
||||||
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.7.0"
|
|
||||||
vector_math:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vector_math
|
|
||||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.4"
|
|
||||||
vm_service:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: vm_service
|
|
||||||
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "14.2.1"
|
|
||||||
webdriver:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: webdriver
|
|
||||||
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.3"
|
|
||||||
window_ext:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: ".."
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
sdks:
|
|
||||||
dart: ">=3.4.4 <4.0.0"
|
|
||||||
flutter: ">=3.18.0-18.0.pre.54"
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
name: window_ext_example
|
|
||||||
description: "Demonstrates how to use the window_ext plugin."
|
|
||||||
# The following line prevents the package from being accidentally published to
|
|
||||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|
||||||
|
|
||||||
environment:
|
|
||||||
sdk: '>=3.4.4 <4.0.0'
|
|
||||||
|
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
|
||||||
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
|
||||||
# dependencies can be manually updated by changing the version numbers below to
|
|
||||||
# the latest version available on pub.dev. To see which dependencies have newer
|
|
||||||
# versions available, run `flutter pub outdated`.
|
|
||||||
dependencies:
|
|
||||||
flutter:
|
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
window_ext:
|
|
||||||
# When depending on this package from a real application you should use:
|
|
||||||
# window_ext: ^x.y.z
|
|
||||||
# See https://dart.dev/tools/pub/dependencies#version-constraints
|
|
||||||
# The example app is bundled with the plugin so we use a path dependency on
|
|
||||||
# the parent directory to use the current plugin's version.
|
|
||||||
path: ../
|
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
|
||||||
cupertino_icons: ^1.0.6
|
|
||||||
|
|
||||||
dev_dependencies:
|
|
||||||
integration_test:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_test:
|
|
||||||
sdk: flutter
|
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
|
||||||
# activated in the `analysis_options.yaml` file located at the root of your
|
|
||||||
# package. See that file for information about deactivating specific lint
|
|
||||||
# rules and activating additional ones.
|
|
||||||
flutter_lints: ^3.0.0
|
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
|
||||||
|
|
||||||
# The following section is specific to Flutter packages.
|
|
||||||
flutter:
|
|
||||||
|
|
||||||
# The following line ensures that the Material Icons font is
|
|
||||||
# included with your application, so that you can use the icons in
|
|
||||||
# the material Icons class.
|
|
||||||
uses-material-design: true
|
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
|
||||||
# assets:
|
|
||||||
# - images/a_dot_burr.jpeg
|
|
||||||
# - images/a_dot_ham.jpeg
|
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
|
||||||
|
|
||||||
# For details regarding adding assets from package dependencies, see
|
|
||||||
# https://flutter.dev/assets-and-images/#from-packages
|
|
||||||
|
|
||||||
# To add custom fonts to your application, add a fonts section here,
|
|
||||||
# in this "flutter" section. Each entry in this list should have a
|
|
||||||
# "family" key with the font family name, and a "fonts" key with a
|
|
||||||
# list giving the asset and other descriptors for the font. For
|
|
||||||
# example:
|
|
||||||
# fonts:
|
|
||||||
# - family: Schyler
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/Schyler-Regular.ttf
|
|
||||||
# - asset: fonts/Schyler-Italic.ttf
|
|
||||||
# style: italic
|
|
||||||
# - family: Trajan Pro
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/TrajanPro.ttf
|
|
||||||
# - asset: fonts/TrajanPro_Bold.ttf
|
|
||||||
# weight: 700
|
|
||||||
#
|
|
||||||
# For details regarding fonts from package dependencies,
|
|
||||||
# see https://flutter.dev/custom-fonts/#from-packages
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// This is a basic Flutter widget test.
|
|
||||||
//
|
|
||||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
|
||||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
|
||||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
|
||||||
// tree, read text, and verify that the values of widget properties are correct.
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
import 'package:window_ext_example/main.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('Verify Platform version', (WidgetTester tester) async {
|
|
||||||
// Build our app and trigger a frame.
|
|
||||||
await tester.pumpWidget(const MyApp());
|
|
||||||
|
|
||||||
// Verify that platform version is retrieved.
|
|
||||||
expect(
|
|
||||||
find.byWidgetPredicate(
|
|
||||||
(Widget widget) => widget is Text &&
|
|
||||||
widget.data!.startsWith('Running on:'),
|
|
||||||
),
|
|
||||||
findsOneWidget,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
17
plugins/window_ext/example/windows/.gitignore
vendored
17
plugins/window_ext/example/windows/.gitignore
vendored
@@ -1,17 +0,0 @@
|
|||||||
flutter/ephemeral/
|
|
||||||
|
|
||||||
# Visual Studio user-specific files.
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
*.userosscache
|
|
||||||
*.sln.docstates
|
|
||||||
|
|
||||||
# Visual Studio build-related files.
|
|
||||||
x64/
|
|
||||||
x86/
|
|
||||||
|
|
||||||
# Visual Studio cache files
|
|
||||||
# files ending in .cache can be ignored
|
|
||||||
*.[Cc]ache
|
|
||||||
# but keep track of directories ending in .cache
|
|
||||||
!*.[Cc]ache/
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
# Project-level configuration.
|
|
||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
project(window_ext_example LANGUAGES CXX)
|
|
||||||
|
|
||||||
# The name of the executable created for the application. Change this to change
|
|
||||||
# the on-disk name of your application.
|
|
||||||
set(BINARY_NAME "window_ext_example")
|
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
|
||||||
# versions of CMake.
|
|
||||||
cmake_policy(VERSION 3.14...3.25)
|
|
||||||
|
|
||||||
# Define build configuration option.
|
|
||||||
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
||||||
if(IS_MULTICONFIG)
|
|
||||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
|
|
||||||
CACHE STRING "" FORCE)
|
|
||||||
else()
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
||||||
set(CMAKE_BUILD_TYPE "Debug" CACHE
|
|
||||||
STRING "Flutter build mode" FORCE)
|
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
|
||||||
"Debug" "Profile" "Release")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
# Define settings for the Profile build mode.
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
|
|
||||||
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
|
|
||||||
set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
|
|
||||||
|
|
||||||
# Use Unicode for all projects.
|
|
||||||
add_definitions(-DUNICODE -D_UNICODE)
|
|
||||||
|
|
||||||
# Compilation settings that should be applied to most targets.
|
|
||||||
#
|
|
||||||
# Be cautious about adding new options here, as plugins use this function by
|
|
||||||
# default. In most cases, you should add new options to specific targets instead
|
|
||||||
# of modifying this function.
|
|
||||||
function(APPLY_STANDARD_SETTINGS TARGET)
|
|
||||||
target_compile_features(${TARGET} PUBLIC cxx_std_17)
|
|
||||||
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
|
|
||||||
target_compile_options(${TARGET} PRIVATE /EHsc)
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Flutter library and tool build rules.
|
|
||||||
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
|
|
||||||
add_subdirectory(${FLUTTER_MANAGED_DIR})
|
|
||||||
|
|
||||||
# Application build; see runner/CMakeLists.txt.
|
|
||||||
add_subdirectory("runner")
|
|
||||||
|
|
||||||
# Enable the test target.
|
|
||||||
set(include_window_ext_tests TRUE)
|
|
||||||
|
|
||||||
# Generated plugin build rules, which manage building the plugins and adding
|
|
||||||
# them to the application.
|
|
||||||
include(flutter/generated_plugins.cmake)
|
|
||||||
|
|
||||||
|
|
||||||
# === Installation ===
|
|
||||||
# Support files are copied into place next to the executable, so that it can
|
|
||||||
# run in place. This is done instead of making a separate bundle (as on Linux)
|
|
||||||
# so that building and running from within Visual Studio will work.
|
|
||||||
set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>")
|
|
||||||
# Make the "install" step default, as it's required to run.
|
|
||||||
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
|
|
||||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
|
||||||
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
|
|
||||||
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
|
|
||||||
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
if(PLUGIN_BUNDLED_LIBRARIES)
|
|
||||||
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
|
|
||||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Copy the native assets provided by the build.dart from all packages.
|
|
||||||
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/")
|
|
||||||
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
|
|
||||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
# Fully re-copy the assets directory on each build to avoid having stale files
|
|
||||||
# from a previous install.
|
|
||||||
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
|
|
||||||
install(CODE "
|
|
||||||
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
|
|
||||||
" COMPONENT Runtime)
|
|
||||||
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
|
|
||||||
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
|
|
||||||
|
|
||||||
# Install the AOT library on non-Debug builds only.
|
|
||||||
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
|
||||||
CONFIGURATIONS Profile;Release
|
|
||||||
COMPONENT Runtime)
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
# This file controls Flutter-level build steps. It should not be edited.
|
|
||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
|
|
||||||
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
|
||||||
|
|
||||||
# Configuration provided via flutter tool.
|
|
||||||
include(${EPHEMERAL_DIR}/generated_config.cmake)
|
|
||||||
|
|
||||||
# TODO: Move the rest of this into files in ephemeral. See
|
|
||||||
# https://github.com/flutter/flutter/issues/57146.
|
|
||||||
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
|
|
||||||
|
|
||||||
# Set fallback configurations for older versions of the flutter tool.
|
|
||||||
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
|
|
||||||
set(FLUTTER_TARGET_PLATFORM "windows-x64")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# === Flutter Library ===
|
|
||||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
|
|
||||||
|
|
||||||
# Published to parent scope for install step.
|
|
||||||
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
|
|
||||||
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
|
|
||||||
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
|
|
||||||
set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_LIBRARY_HEADERS
|
|
||||||
"flutter_export.h"
|
|
||||||
"flutter_windows.h"
|
|
||||||
"flutter_messenger.h"
|
|
||||||
"flutter_plugin_registrar.h"
|
|
||||||
"flutter_texture_registrar.h"
|
|
||||||
)
|
|
||||||
list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
|
|
||||||
add_library(flutter INTERFACE)
|
|
||||||
target_include_directories(flutter INTERFACE
|
|
||||||
"${EPHEMERAL_DIR}"
|
|
||||||
)
|
|
||||||
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
|
|
||||||
add_dependencies(flutter flutter_assemble)
|
|
||||||
|
|
||||||
# === Wrapper ===
|
|
||||||
list(APPEND CPP_WRAPPER_SOURCES_CORE
|
|
||||||
"core_implementations.cc"
|
|
||||||
"standard_codec.cc"
|
|
||||||
)
|
|
||||||
list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
|
|
||||||
list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
|
|
||||||
"plugin_registrar.cc"
|
|
||||||
)
|
|
||||||
list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
|
|
||||||
list(APPEND CPP_WRAPPER_SOURCES_APP
|
|
||||||
"flutter_engine.cc"
|
|
||||||
"flutter_view_controller.cc"
|
|
||||||
)
|
|
||||||
list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
|
|
||||||
|
|
||||||
# Wrapper sources needed for a plugin.
|
|
||||||
add_library(flutter_wrapper_plugin STATIC
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE}
|
|
||||||
${CPP_WRAPPER_SOURCES_PLUGIN}
|
|
||||||
)
|
|
||||||
apply_standard_settings(flutter_wrapper_plugin)
|
|
||||||
set_target_properties(flutter_wrapper_plugin PROPERTIES
|
|
||||||
POSITION_INDEPENDENT_CODE ON)
|
|
||||||
set_target_properties(flutter_wrapper_plugin PROPERTIES
|
|
||||||
CXX_VISIBILITY_PRESET hidden)
|
|
||||||
target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
|
|
||||||
target_include_directories(flutter_wrapper_plugin PUBLIC
|
|
||||||
"${WRAPPER_ROOT}/include"
|
|
||||||
)
|
|
||||||
add_dependencies(flutter_wrapper_plugin flutter_assemble)
|
|
||||||
|
|
||||||
# Wrapper sources needed for the runner.
|
|
||||||
add_library(flutter_wrapper_app STATIC
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE}
|
|
||||||
${CPP_WRAPPER_SOURCES_APP}
|
|
||||||
)
|
|
||||||
apply_standard_settings(flutter_wrapper_app)
|
|
||||||
target_link_libraries(flutter_wrapper_app PUBLIC flutter)
|
|
||||||
target_include_directories(flutter_wrapper_app PUBLIC
|
|
||||||
"${WRAPPER_ROOT}/include"
|
|
||||||
)
|
|
||||||
add_dependencies(flutter_wrapper_app flutter_assemble)
|
|
||||||
|
|
||||||
# === Flutter tool backend ===
|
|
||||||
# _phony_ is a non-existent file to force this command to run every time,
|
|
||||||
# since currently there's no way to get a full input/output list from the
|
|
||||||
# flutter tool.
|
|
||||||
set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
|
|
||||||
set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
|
|
||||||
${CPP_WRAPPER_SOURCES_APP}
|
|
||||||
${PHONY_OUTPUT}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E env
|
|
||||||
${FLUTTER_TOOL_ENVIRONMENT}
|
|
||||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
|
||||||
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
|
|
||||||
VERBATIM
|
|
||||||
)
|
|
||||||
add_custom_target(flutter_assemble DEPENDS
|
|
||||||
"${FLUTTER_LIBRARY}"
|
|
||||||
${FLUTTER_LIBRARY_HEADERS}
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE}
|
|
||||||
${CPP_WRAPPER_SOURCES_PLUGIN}
|
|
||||||
${CPP_WRAPPER_SOURCES_APP}
|
|
||||||
)
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
project(runner LANGUAGES CXX)
|
|
||||||
|
|
||||||
# Define the application target. To change its name, change BINARY_NAME in the
|
|
||||||
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
|
|
||||||
# work.
|
|
||||||
#
|
|
||||||
# Any new source files that you add to the application should be added here.
|
|
||||||
add_executable(${BINARY_NAME} WIN32
|
|
||||||
"flutter_window.cpp"
|
|
||||||
"main.cpp"
|
|
||||||
"utils.cpp"
|
|
||||||
"win32_window.cpp"
|
|
||||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
|
||||||
"Runner.rc"
|
|
||||||
"runner.exe.manifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Apply the standard set of build settings. This can be removed for applications
|
|
||||||
# that need different build settings.
|
|
||||||
apply_standard_settings(${BINARY_NAME})
|
|
||||||
|
|
||||||
# Add preprocessor definitions for the build version.
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
|
|
||||||
|
|
||||||
# Disable Windows macros that collide with C++ standard library functions.
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
|
|
||||||
|
|
||||||
# Add dependency libraries and include directories. Add any application-specific
|
|
||||||
# dependencies here.
|
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
|
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
|
|
||||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
|
||||||
|
|
||||||
# Run the Flutter tool portions of the build. This must not be removed.
|
|
||||||
add_dependencies(${BINARY_NAME} flutter_assemble)
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
#pragma code_page(65001)
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "winres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (United States) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"#include ""winres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_APP_ICON ICON "resources\\app_icon.ico"
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
|
|
||||||
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
|
|
||||||
#else
|
|
||||||
#define VERSION_AS_NUMBER 1,0,0,0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(FLUTTER_VERSION)
|
|
||||||
#define VERSION_AS_STRING FLUTTER_VERSION
|
|
||||||
#else
|
|
||||||
#define VERSION_AS_STRING "1.0.0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION VERSION_AS_NUMBER
|
|
||||||
PRODUCTVERSION VERSION_AS_NUMBER
|
|
||||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS VS_FF_DEBUG
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS VOS__WINDOWS32
|
|
||||||
FILETYPE VFT_APP
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904e4"
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", "com.example" "\0"
|
|
||||||
VALUE "FileDescription", "window_ext_example" "\0"
|
|
||||||
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
|
||||||
VALUE "InternalName", "window_ext_example" "\0"
|
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0"
|
|
||||||
VALUE "OriginalFilename", "window_ext_example.exe" "\0"
|
|
||||||
VALUE "ProductName", "window_ext_example" "\0"
|
|
||||||
VALUE "ProductVersion", VERSION_AS_STRING "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1252
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // English (United States) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#include "flutter_window.h"
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "flutter/generated_plugin_registrant.h"
|
|
||||||
|
|
||||||
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
|
|
||||||
: project_(project) {}
|
|
||||||
|
|
||||||
FlutterWindow::~FlutterWindow() {}
|
|
||||||
|
|
||||||
bool FlutterWindow::OnCreate() {
|
|
||||||
if (!Win32Window::OnCreate()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT frame = GetClientArea();
|
|
||||||
|
|
||||||
// The size here must match the window dimensions to avoid unnecessary surface
|
|
||||||
// creation / destruction in the startup path.
|
|
||||||
flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
|
|
||||||
frame.right - frame.left, frame.bottom - frame.top, project_);
|
|
||||||
// Ensure that basic setup of the controller was successful.
|
|
||||||
if (!flutter_controller_->engine() || !flutter_controller_->view()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
RegisterPlugins(flutter_controller_->engine());
|
|
||||||
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
|
||||||
|
|
||||||
flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
|
||||||
this->Show();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Flutter can complete the first frame before the "show window" callback is
|
|
||||||
// registered. The following call ensures a frame is pending to ensure the
|
|
||||||
// window is shown. It is a no-op if the first frame hasn't completed yet.
|
|
||||||
flutter_controller_->ForceRedraw();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlutterWindow::OnDestroy() {
|
|
||||||
if (flutter_controller_) {
|
|
||||||
flutter_controller_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window::OnDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT
|
|
||||||
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept {
|
|
||||||
// Give Flutter, including plugins, an opportunity to handle window messages.
|
|
||||||
if (flutter_controller_) {
|
|
||||||
std::optional<LRESULT> result =
|
|
||||||
flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
|
|
||||||
lparam);
|
|
||||||
if (result) {
|
|
||||||
return *result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message) {
|
|
||||||
case WM_FONTCHANGE:
|
|
||||||
flutter_controller_->engine()->ReloadSystemFonts();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#ifndef RUNNER_FLUTTER_WINDOW_H_
|
|
||||||
#define RUNNER_FLUTTER_WINDOW_H_
|
|
||||||
|
|
||||||
#include <flutter/dart_project.h>
|
|
||||||
#include <flutter/flutter_view_controller.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "win32_window.h"
|
|
||||||
|
|
||||||
// A window that does nothing but host a Flutter view.
|
|
||||||
class FlutterWindow : public Win32Window {
|
|
||||||
public:
|
|
||||||
// Creates a new FlutterWindow hosting a Flutter view running |project|.
|
|
||||||
explicit FlutterWindow(const flutter::DartProject& project);
|
|
||||||
virtual ~FlutterWindow();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Win32Window:
|
|
||||||
bool OnCreate() override;
|
|
||||||
void OnDestroy() override;
|
|
||||||
LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The project to run.
|
|
||||||
flutter::DartProject project_;
|
|
||||||
|
|
||||||
// The Flutter instance hosted by this window.
|
|
||||||
std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RUNNER_FLUTTER_WINDOW_H_
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#include <flutter/dart_project.h>
|
|
||||||
#include <flutter/flutter_view_controller.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "flutter_window.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
|
||||||
_In_ wchar_t *command_line, _In_ int show_command) {
|
|
||||||
// Attach to console when present (e.g., 'flutter run') or create a
|
|
||||||
// new console when running with a debugger.
|
|
||||||
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
|
|
||||||
CreateAndAttachConsole();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize COM, so that it is available for use in the library and/or
|
|
||||||
// plugins.
|
|
||||||
::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
|
||||||
|
|
||||||
flutter::DartProject project(L"data");
|
|
||||||
|
|
||||||
std::vector<std::string> command_line_arguments =
|
|
||||||
GetCommandLineArguments();
|
|
||||||
|
|
||||||
project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
|
|
||||||
|
|
||||||
FlutterWindow window(project);
|
|
||||||
Win32Window::Point origin(10, 10);
|
|
||||||
Win32Window::Size size(1280, 720);
|
|
||||||
if (!window.Create(L"window_ext_example", origin, size)) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
window.SetQuitOnClose(true);
|
|
||||||
|
|
||||||
::MSG msg;
|
|
||||||
while (::GetMessage(&msg, nullptr, 0, 0)) {
|
|
||||||
::TranslateMessage(&msg);
|
|
||||||
::DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
::CoUninitialize();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by Runner.rc
|
|
||||||
//
|
|
||||||
#define IDI_APP_ICON 101
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB |
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<windowsSettings>
|
|
||||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
|
||||||
</windowsSettings>
|
|
||||||
</application>
|
|
||||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
|
||||||
<application>
|
|
||||||
<!-- Windows 10 and Windows 11 -->
|
|
||||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
|
||||||
<!-- Windows 8.1 -->
|
|
||||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
|
||||||
<!-- Windows 8 -->
|
|
||||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
|
||||||
<!-- Windows 7 -->
|
|
||||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
|
||||||
</application>
|
|
||||||
</compatibility>
|
|
||||||
</assembly>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
void CreateAndAttachConsole() {
|
|
||||||
if (::AllocConsole()) {
|
|
||||||
FILE *unused;
|
|
||||||
if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
|
|
||||||
_dup2(_fileno(stdout), 1);
|
|
||||||
}
|
|
||||||
if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
|
|
||||||
_dup2(_fileno(stdout), 2);
|
|
||||||
}
|
|
||||||
std::ios::sync_with_stdio();
|
|
||||||
FlutterDesktopResyncOutputStreams();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> GetCommandLineArguments() {
|
|
||||||
// Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
|
|
||||||
int argc;
|
|
||||||
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
|
||||||
if (argv == nullptr) {
|
|
||||||
return std::vector<std::string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> command_line_arguments;
|
|
||||||
|
|
||||||
// Skip the first argument as it's the binary name.
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
::LocalFree(argv);
|
|
||||||
|
|
||||||
return command_line_arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Utf8FromUtf16(const wchar_t* utf16_string) {
|
|
||||||
if (utf16_string == nullptr) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
unsigned int target_length = ::WideCharToMultiByte(
|
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
|
||||||
-1, nullptr, 0, nullptr, nullptr)
|
|
||||||
-1; // remove the trailing null character
|
|
||||||
int input_length = (int)wcslen(utf16_string);
|
|
||||||
std::string utf8_string;
|
|
||||||
if (target_length == 0 || target_length > utf8_string.max_size()) {
|
|
||||||
return utf8_string;
|
|
||||||
}
|
|
||||||
utf8_string.resize(target_length);
|
|
||||||
int converted_length = ::WideCharToMultiByte(
|
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
|
||||||
input_length, utf8_string.data(), target_length, nullptr, nullptr);
|
|
||||||
if (converted_length == 0) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
return utf8_string;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#ifndef RUNNER_UTILS_H_
|
|
||||||
#define RUNNER_UTILS_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Creates a console for the process, and redirects stdout and stderr to
|
|
||||||
// it for both the runner and the Flutter library.
|
|
||||||
void CreateAndAttachConsole();
|
|
||||||
|
|
||||||
// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
|
|
||||||
// encoded in UTF-8. Returns an empty std::string on failure.
|
|
||||||
std::string Utf8FromUtf16(const wchar_t* utf16_string);
|
|
||||||
|
|
||||||
// Gets the command line arguments passed in as a std::vector<std::string>,
|
|
||||||
// encoded in UTF-8. Returns an empty std::vector<std::string> on failure.
|
|
||||||
std::vector<std::string> GetCommandLineArguments();
|
|
||||||
|
|
||||||
#endif // RUNNER_UTILS_H_
|
|
||||||
@@ -1,288 +0,0 @@
|
|||||||
#include "win32_window.h"
|
|
||||||
|
|
||||||
#include <dwmapi.h>
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
/// Window attribute that enables dark mode window decorations.
|
|
||||||
///
|
|
||||||
/// Redefined in case the developer's machine has a Windows SDK older than
|
|
||||||
/// version 10.0.22000.0.
|
|
||||||
/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
|
||||||
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
|
||||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
|
|
||||||
|
|
||||||
/// Registry key for app theme preference.
|
|
||||||
///
|
|
||||||
/// A value of 0 indicates apps should use dark mode. A non-zero or missing
|
|
||||||
/// value indicates apps should use light mode.
|
|
||||||
constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
|
|
||||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
|
||||||
constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
|
|
||||||
|
|
||||||
// The number of Win32Window objects that currently exist.
|
|
||||||
static int g_active_window_count = 0;
|
|
||||||
|
|
||||||
using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
|
|
||||||
|
|
||||||
// Scale helper to convert logical scaler values to physical using passed in
|
|
||||||
// scale factor
|
|
||||||
int Scale(int source, double scale_factor) {
|
|
||||||
return static_cast<int>(source * scale_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
|
|
||||||
// This API is only needed for PerMonitor V1 awareness mode.
|
|
||||||
void EnableFullDpiSupportIfAvailable(HWND hwnd) {
|
|
||||||
HMODULE user32_module = LoadLibraryA("User32.dll");
|
|
||||||
if (!user32_module) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto enable_non_client_dpi_scaling =
|
|
||||||
reinterpret_cast<EnableNonClientDpiScaling*>(
|
|
||||||
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
|
|
||||||
if (enable_non_client_dpi_scaling != nullptr) {
|
|
||||||
enable_non_client_dpi_scaling(hwnd);
|
|
||||||
}
|
|
||||||
FreeLibrary(user32_module);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// Manages the Win32Window's window class registration.
|
|
||||||
class WindowClassRegistrar {
|
|
||||||
public:
|
|
||||||
~WindowClassRegistrar() = default;
|
|
||||||
|
|
||||||
// Returns the singleton registrar instance.
|
|
||||||
static WindowClassRegistrar* GetInstance() {
|
|
||||||
if (!instance_) {
|
|
||||||
instance_ = new WindowClassRegistrar();
|
|
||||||
}
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the name of the window class, registering the class if it hasn't
|
|
||||||
// previously been registered.
|
|
||||||
const wchar_t* GetWindowClass();
|
|
||||||
|
|
||||||
// Unregisters the window class. Should only be called if there are no
|
|
||||||
// instances of the window.
|
|
||||||
void UnregisterWindowClass();
|
|
||||||
|
|
||||||
private:
|
|
||||||
WindowClassRegistrar() = default;
|
|
||||||
|
|
||||||
static WindowClassRegistrar* instance_;
|
|
||||||
|
|
||||||
bool class_registered_ = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
|
|
||||||
|
|
||||||
const wchar_t* WindowClassRegistrar::GetWindowClass() {
|
|
||||||
if (!class_registered_) {
|
|
||||||
WNDCLASS window_class{};
|
|
||||||
window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
|
||||||
window_class.lpszClassName = kWindowClassName;
|
|
||||||
window_class.style = CS_HREDRAW | CS_VREDRAW;
|
|
||||||
window_class.cbClsExtra = 0;
|
|
||||||
window_class.cbWndExtra = 0;
|
|
||||||
window_class.hInstance = GetModuleHandle(nullptr);
|
|
||||||
window_class.hIcon =
|
|
||||||
LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
|
|
||||||
window_class.hbrBackground = 0;
|
|
||||||
window_class.lpszMenuName = nullptr;
|
|
||||||
window_class.lpfnWndProc = Win32Window::WndProc;
|
|
||||||
RegisterClass(&window_class);
|
|
||||||
class_registered_ = true;
|
|
||||||
}
|
|
||||||
return kWindowClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowClassRegistrar::UnregisterWindowClass() {
|
|
||||||
UnregisterClass(kWindowClassName, nullptr);
|
|
||||||
class_registered_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window::Win32Window() {
|
|
||||||
++g_active_window_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window::~Win32Window() {
|
|
||||||
--g_active_window_count;
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Win32Window::Create(const std::wstring& title,
|
|
||||||
const Point& origin,
|
|
||||||
const Size& size) {
|
|
||||||
Destroy();
|
|
||||||
|
|
||||||
const wchar_t* window_class =
|
|
||||||
WindowClassRegistrar::GetInstance()->GetWindowClass();
|
|
||||||
|
|
||||||
const POINT target_point = {static_cast<LONG>(origin.x),
|
|
||||||
static_cast<LONG>(origin.y)};
|
|
||||||
HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
|
|
||||||
UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
|
|
||||||
double scale_factor = dpi / 96.0;
|
|
||||||
|
|
||||||
HWND window = CreateWindow(
|
|
||||||
window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
|
|
||||||
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
|
|
||||||
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
|
|
||||||
nullptr, nullptr, GetModuleHandle(nullptr), this);
|
|
||||||
|
|
||||||
if (!window) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateTheme(window);
|
|
||||||
|
|
||||||
return OnCreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Win32Window::Show() {
|
|
||||||
return ShowWindow(window_handle_, SW_SHOWNORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept {
|
|
||||||
if (message == WM_NCCREATE) {
|
|
||||||
auto window_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
|
|
||||||
SetWindowLongPtr(window, GWLP_USERDATA,
|
|
||||||
reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));
|
|
||||||
|
|
||||||
auto that = static_cast<Win32Window*>(window_struct->lpCreateParams);
|
|
||||||
EnableFullDpiSupportIfAvailable(window);
|
|
||||||
that->window_handle_ = window;
|
|
||||||
} else if (Win32Window* that = GetThisFromHandle(window)) {
|
|
||||||
return that->MessageHandler(window, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefWindowProc(window, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT
|
|
||||||
Win32Window::MessageHandler(HWND hwnd,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept {
|
|
||||||
switch (message) {
|
|
||||||
case WM_DESTROY:
|
|
||||||
window_handle_ = nullptr;
|
|
||||||
Destroy();
|
|
||||||
if (quit_on_close_) {
|
|
||||||
PostQuitMessage(0);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case WM_DPICHANGED: {
|
|
||||||
auto newRectSize = reinterpret_cast<RECT*>(lparam);
|
|
||||||
LONG newWidth = newRectSize->right - newRectSize->left;
|
|
||||||
LONG newHeight = newRectSize->bottom - newRectSize->top;
|
|
||||||
|
|
||||||
SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
|
|
||||||
newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case WM_SIZE: {
|
|
||||||
RECT rect = GetClientArea();
|
|
||||||
if (child_content_ != nullptr) {
|
|
||||||
// Size and position the child window.
|
|
||||||
MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
|
|
||||||
rect.bottom - rect.top, TRUE);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_ACTIVATE:
|
|
||||||
if (child_content_ != nullptr) {
|
|
||||||
SetFocus(child_content_);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case WM_DWMCOLORIZATIONCOLORCHANGED:
|
|
||||||
UpdateTheme(hwnd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefWindowProc(window_handle_, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::Destroy() {
|
|
||||||
OnDestroy();
|
|
||||||
|
|
||||||
if (window_handle_) {
|
|
||||||
DestroyWindow(window_handle_);
|
|
||||||
window_handle_ = nullptr;
|
|
||||||
}
|
|
||||||
if (g_active_window_count == 0) {
|
|
||||||
WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
|
|
||||||
return reinterpret_cast<Win32Window*>(
|
|
||||||
GetWindowLongPtr(window, GWLP_USERDATA));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::SetChildContent(HWND content) {
|
|
||||||
child_content_ = content;
|
|
||||||
SetParent(content, window_handle_);
|
|
||||||
RECT frame = GetClientArea();
|
|
||||||
|
|
||||||
MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
|
|
||||||
frame.bottom - frame.top, true);
|
|
||||||
|
|
||||||
SetFocus(child_content_);
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT Win32Window::GetClientArea() {
|
|
||||||
RECT frame;
|
|
||||||
GetClientRect(window_handle_, &frame);
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND Win32Window::GetHandle() {
|
|
||||||
return window_handle_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::SetQuitOnClose(bool quit_on_close) {
|
|
||||||
quit_on_close_ = quit_on_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Win32Window::OnCreate() {
|
|
||||||
// No-op; provided for subclasses.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::OnDestroy() {
|
|
||||||
// No-op; provided for subclasses.
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::UpdateTheme(HWND const window) {
|
|
||||||
DWORD light_mode;
|
|
||||||
DWORD light_mode_size = sizeof(light_mode);
|
|
||||||
LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
|
|
||||||
kGetPreferredBrightnessRegValue,
|
|
||||||
RRF_RT_REG_DWORD, nullptr, &light_mode,
|
|
||||||
&light_mode_size);
|
|
||||||
|
|
||||||
if (result == ERROR_SUCCESS) {
|
|
||||||
BOOL enable_dark_mode = light_mode == 0;
|
|
||||||
DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
|
|
||||||
&enable_dark_mode, sizeof(enable_dark_mode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
#ifndef RUNNER_WIN32_WINDOW_H_
|
|
||||||
#define RUNNER_WIN32_WINDOW_H_
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
// A class abstraction for a high DPI-aware Win32 Window. Intended to be
|
|
||||||
// inherited from by classes that wish to specialize with custom
|
|
||||||
// rendering and input handling
|
|
||||||
class Win32Window {
|
|
||||||
public:
|
|
||||||
struct Point {
|
|
||||||
unsigned int x;
|
|
||||||
unsigned int y;
|
|
||||||
Point(unsigned int x, unsigned int y) : x(x), y(y) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Size {
|
|
||||||
unsigned int width;
|
|
||||||
unsigned int height;
|
|
||||||
Size(unsigned int width, unsigned int height)
|
|
||||||
: width(width), height(height) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
Win32Window();
|
|
||||||
virtual ~Win32Window();
|
|
||||||
|
|
||||||
// Creates a win32 window with |title| that is positioned and sized using
|
|
||||||
// |origin| and |size|. New windows are created on the default monitor. Window
|
|
||||||
// sizes are specified to the OS in physical pixels, hence to ensure a
|
|
||||||
// consistent size this function will scale the inputted width and height as
|
|
||||||
// as appropriate for the default monitor. The window is invisible until
|
|
||||||
// |Show| is called. Returns true if the window was created successfully.
|
|
||||||
bool Create(const std::wstring& title, const Point& origin, const Size& size);
|
|
||||||
|
|
||||||
// Show the current window. Returns true if the window was successfully shown.
|
|
||||||
bool Show();
|
|
||||||
|
|
||||||
// Release OS resources associated with window.
|
|
||||||
void Destroy();
|
|
||||||
|
|
||||||
// Inserts |content| into the window tree.
|
|
||||||
void SetChildContent(HWND content);
|
|
||||||
|
|
||||||
// Returns the backing Window handle to enable clients to set icon and other
|
|
||||||
// window properties. Returns nullptr if the window has been destroyed.
|
|
||||||
HWND GetHandle();
|
|
||||||
|
|
||||||
// If true, closing this window will quit the application.
|
|
||||||
void SetQuitOnClose(bool quit_on_close);
|
|
||||||
|
|
||||||
// Return a RECT representing the bounds of the current client area.
|
|
||||||
RECT GetClientArea();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Processes and route salient window messages for mouse handling,
|
|
||||||
// size change and DPI. Delegates handling of these to member overloads that
|
|
||||||
// inheriting classes can handle.
|
|
||||||
virtual LRESULT MessageHandler(HWND window,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept;
|
|
||||||
|
|
||||||
// Called when CreateAndShow is called, allowing subclass window-related
|
|
||||||
// setup. Subclasses should return false if setup fails.
|
|
||||||
virtual bool OnCreate();
|
|
||||||
|
|
||||||
// Called when Destroy is called.
|
|
||||||
virtual void OnDestroy();
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class WindowClassRegistrar;
|
|
||||||
|
|
||||||
// OS callback called by message pump. Handles the WM_NCCREATE message which
|
|
||||||
// is passed when the non-client area is being created and enables automatic
|
|
||||||
// non-client DPI scaling so that the non-client area automatically
|
|
||||||
// responds to changes in DPI. All other messages are handled by
|
|
||||||
// MessageHandler.
|
|
||||||
static LRESULT CALLBACK WndProc(HWND const window,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept;
|
|
||||||
|
|
||||||
// Retrieves a class instance pointer for |window|
|
|
||||||
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
|
|
||||||
|
|
||||||
// Update the window frame's theme to match the system theme.
|
|
||||||
static void UpdateTheme(HWND const window);
|
|
||||||
|
|
||||||
bool quit_on_close_ = false;
|
|
||||||
|
|
||||||
// window handle for top level window.
|
|
||||||
HWND window_handle_ = nullptr;
|
|
||||||
|
|
||||||
// window handle for hosted content.
|
|
||||||
HWND child_content_ = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RUNNER_WIN32_WINDOW_H_
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
abstract mixin class WindowExtListener {
|
abstract mixin class WindowExtListener {
|
||||||
void onTaskbarCreated() {}
|
void onTaskbarCreated() {}
|
||||||
|
|
||||||
|
void onShouldTerminate() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ class WindowExtManager {
|
|||||||
WindowExtManager._() {
|
WindowExtManager._() {
|
||||||
_channel.setMethodCallHandler(_methodCallHandler);
|
_channel.setMethodCallHandler(_methodCallHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final WindowExtManager instance = WindowExtManager._();
|
static final WindowExtManager instance = WindowExtManager._();
|
||||||
|
|
||||||
final MethodChannel _channel = const MethodChannel('window_ext');
|
final MethodChannel _channel = const MethodChannel('window_ext');
|
||||||
|
|
||||||
final ObserverList<WindowExtListener> _listeners = ObserverList<WindowExtListener>();
|
final ObserverList<WindowExtListener> _listeners =
|
||||||
|
ObserverList<WindowExtListener>();
|
||||||
|
|
||||||
Future<void> _methodCallHandler(MethodCall call) async {
|
Future<void> _methodCallHandler(MethodCall call) async {
|
||||||
for (final WindowExtListener listener in _listeners) {
|
for (final WindowExtListener listener in _listeners) {
|
||||||
@@ -20,6 +21,9 @@ class WindowExtManager {
|
|||||||
case "taskbarCreated":
|
case "taskbarCreated":
|
||||||
listener.onTaskbarCreated();
|
listener.onTaskbarCreated();
|
||||||
break;
|
break;
|
||||||
|
case "shouldTerminate":
|
||||||
|
listener.onShouldTerminate();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,4 +41,4 @@ class WindowExtManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final windowExtManager = WindowExtManager.instance;
|
final windowExtManager = WindowExtManager.instance;
|
||||||
|
|||||||
25
plugins/window_ext/macos/Classes/WindowExtPlugin.swift
Normal file
25
plugins/window_ext/macos/Classes/WindowExtPlugin.swift
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import Cocoa
|
||||||
|
import FlutterMacOS
|
||||||
|
|
||||||
|
public class WindowExtPlugin: NSObject, FlutterPlugin {
|
||||||
|
public static var instance:WindowExtPlugin?
|
||||||
|
|
||||||
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
|
let channel = FlutterMethodChannel(name: "window_ext", binaryMessenger: registrar.messenger)
|
||||||
|
instance = WindowExtPlugin(registrar, channel)
|
||||||
|
registrar.addMethodCallDelegate(instance!, channel: channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var registrar: FlutterPluginRegistrar!
|
||||||
|
private var channel: FlutterMethodChannel!
|
||||||
|
|
||||||
|
public init(_ registrar: FlutterPluginRegistrar, _ channel: FlutterMethodChannel) {
|
||||||
|
super.init()
|
||||||
|
self.registrar = registrar
|
||||||
|
self.channel = channel
|
||||||
|
}
|
||||||
|
|
||||||
|
public func handleShouldTerminate(){
|
||||||
|
channel.invokeMethod("shouldTerminate", arguments: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
23
plugins/window_ext/macos/window_ext.podspec
Normal file
23
plugins/window_ext/macos/window_ext.podspec
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
|
||||||
|
# Run `pod lib lint window_ext.podspec` to validate before publishing.
|
||||||
|
#
|
||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = 'window_ext'
|
||||||
|
s.version = '0.0.1'
|
||||||
|
s.summary = 'A new Flutter plugin project.'
|
||||||
|
s.description = <<-DESC
|
||||||
|
A new Flutter plugin project.
|
||||||
|
DESC
|
||||||
|
s.homepage = 'http://example.com'
|
||||||
|
s.license = { :file => '../LICENSE' }
|
||||||
|
s.author = { 'Your Company' => 'email@example.com' }
|
||||||
|
|
||||||
|
s.source = { :path => '.' }
|
||||||
|
s.source_files = 'Classes/**/*'
|
||||||
|
s.dependency 'FlutterMacOS'
|
||||||
|
|
||||||
|
s.platform = :osx, '10.11'
|
||||||
|
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
|
||||||
|
s.swift_version = '5.0'
|
||||||
|
end
|
||||||
@@ -36,6 +36,8 @@ flutter:
|
|||||||
platforms:
|
platforms:
|
||||||
windows:
|
windows:
|
||||||
pluginClass: WindowExtPluginCApi
|
pluginClass: WindowExtPluginCApi
|
||||||
|
macos:
|
||||||
|
pluginClass: WindowExtPlugin
|
||||||
|
|
||||||
# To add assets to your plugin package, add an assets section, like this:
|
# To add assets to your plugin package, add an assets section, like this:
|
||||||
# assets:
|
# assets:
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:window_ext/window_ext_method_channel.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
MethodChannelWindowExt platform = MethodChannelWindowExt();
|
|
||||||
const MethodChannel channel = MethodChannel('window_ext');
|
|
||||||
|
|
||||||
setUp(() {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
|
|
||||||
channel,
|
|
||||||
(MethodCall methodCall) async {
|
|
||||||
return '42';
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() {
|
|
||||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('getPlatformVersion', () async {
|
|
||||||
expect(await platform.getPlatformVersion(), '42');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:window_ext/window_ext.dart';
|
|
||||||
import 'package:window_ext/window_ext_platform_interface.dart';
|
|
||||||
import 'package:window_ext/window_ext_method_channel.dart';
|
|
||||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
|
||||||
|
|
||||||
class MockWindowExtPlatform
|
|
||||||
with MockPlatformInterfaceMixin
|
|
||||||
implements WindowExtPlatform {
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<String?> getPlatformVersion() => Future.value('42');
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
final WindowExtPlatform initialPlatform = WindowExtPlatform.instance;
|
|
||||||
|
|
||||||
test('$MethodChannelWindowExt is the default instance', () {
|
|
||||||
expect(initialPlatform, isInstanceOf<MethodChannelWindowExt>());
|
|
||||||
});
|
|
||||||
|
|
||||||
test('getPlatformVersion', () async {
|
|
||||||
WindowExt windowExtPlugin = WindowExt();
|
|
||||||
MockWindowExtPlatform fakePlatform = MockWindowExtPlatform();
|
|
||||||
WindowExtPlatform.instance = fakePlatform;
|
|
||||||
|
|
||||||
expect(await windowExtPlugin.getPlatformVersion(), '42');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user