Skip to content

Commit

Permalink
Fix notification duplicate creation issue
Browse files Browse the repository at this point in the history
Fix AccessControl click issue
  • Loading branch information
chen08209 committed Jun 3, 2024
1 parent 844ce8f commit 0512d69
Show file tree
Hide file tree
Showing 10 changed files with 560 additions and 321 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import android.os.Binder
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE
import androidx.core.graphics.drawable.IconCompat
import com.follow.clash.GlobalState
import com.follow.clash.MainActivity
import com.follow.clash.models.AccessControl
import com.follow.clash.models.AccessControlMode


@SuppressLint("WrongConstant")
class FlClashVpnService : VpnService() {


Expand Down Expand Up @@ -97,49 +99,57 @@ class FlClashVpnService : VpnService() {
stopForeground()
}


private val notificationBuilder by lazy {
val intent = Intent(this, MainActivity::class.java)

val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
} else {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}

val icon = IconCompat.createWithResource(this, this.applicationInfo.icon)

with(NotificationCompat.Builder(this, CHANNEL)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setSmallIcon(icon)
}
setContentTitle("FlClash")
foregroundServiceBehavior = FOREGROUND_SERVICE_IMMEDIATE
setContentIntent(pendingIntent)
setCategory(NotificationCompat.CATEGORY_SERVICE)
priority = NotificationCompat.PRIORITY_LOW
setOngoing(true)
setShowWhen(false)
setOnlyAlertOnce(true)
}
}

@SuppressLint("ForegroundServiceType", "WrongConstant")
fun startForeground(title: String, content: String) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(CHANNEL, "FlClash", NotificationManager.IMPORTANCE_LOW)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)

val intent = Intent(this, MainActivity::class.java)

val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
} else {
PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}

val icon = IconCompat.createWithResource(this, this.applicationInfo.icon)

val notification = with(NotificationCompat.Builder(this, CHANNEL)) {
setSmallIcon(icon)
setContentTitle(title)
setContentText(content)
foregroundServiceBehavior = NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE
setContentIntent(pendingIntent)
setOngoing(true)
setShowWhen(false)
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)
}
}

Expand Down
1 change: 0 additions & 1 deletion lib/fragments/about.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/common.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
Expand Down
83 changes: 60 additions & 23 deletions lib/fragments/access.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:collection/collection.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/plugins/app.dart';
import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/state.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
Expand All @@ -19,8 +21,10 @@ class _AccessFragmentState extends State<AccessFragment> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
packagesListenable.value = await app?.getPackages() ?? [];
WidgetsBinding.instance.addPostFrameCallback((_) {
Future.delayed(const Duration(milliseconds: 300), () async {
packagesListenable.value = await app?.getPackages() ?? [];
});
});
}

Expand Down Expand Up @@ -91,13 +95,28 @@ class _AccessFragmentState extends State<AccessFragment> {
return IconButton(
tooltip: tooltip,
onPressed: () {
final config = context.read<Config>();
final config = globalState.appController.config;
final isAccept =
config.accessControl.mode == AccessControlMode.acceptSelected;

if (isSelectedAll) {
config.accessControl.currentList = [];
config.accessControl = config.accessControl.copyWith();
config.accessControl = switch (isAccept) {
true => config.accessControl.copyWith(
acceptList: [],
),
false => config.accessControl.copyWith(
rejectList: [],
),
};
} else {
config.accessControl.currentList = allValueList;
config.accessControl = config.accessControl.copyWith();
config.accessControl = switch (isAccept) {
true => config.accessControl.copyWith(
acceptList: allValueList,
),
false => config.accessControl.copyWith(
rejectList: allValueList,
),
};
}
},
icon: isSelectedAll
Expand Down Expand Up @@ -181,7 +200,8 @@ class _AccessFragmentState extends State<AccessFragment> {
children: [
Flexible(
child: _buildSelectedAllButton(
isSelectedAll: valueList.length == packageNameList.length,
isSelectedAll: const ListEquality<String>()
.equals(valueList, packageNameList),
allValueList: packageNameList,
),
),
Expand All @@ -195,13 +215,18 @@ class _AccessFragmentState extends State<AccessFragment> {
);
}

Widget _buildPackageList(bool isAccessControl) {
Widget _buildPackageList() {
return ValueListenableBuilder(
valueListenable: packagesListenable,
builder: (_, packages, ___) {
return Selector<Config, AccessControl>(
selector: (_, config) => config.accessControl,
builder: (context, accessControl, __) {
return Selector<Config, PackageListSelectorState>(
selector: (_, config) => PackageListSelectorState(
accessControl: config.accessControl,
isAccessControl: config.isAccessControl,
),
builder: (context, state, __) {
final accessControl = state.accessControl;
final isAccessControl = state.isAccessControl;
final isFilterSystemApp = accessControl.isFilterSystemApp;
final currentPackages = isFilterSystemApp
? packages
Expand All @@ -211,13 +236,15 @@ class _AccessFragmentState extends State<AccessFragment> {
final packageNameList =
currentPackages.map((e) => e.packageName).toList();
final accessControlMode = accessControl.mode;
final valueList =
accessControl.currentList.intersection(packageNameList);
final currentList =
accessControlMode == AccessControlMode.acceptSelected
? accessControl.acceptList
: accessControl.rejectList;
final valueList = currentList.intersection(packageNameList);
final describe =
accessControlMode == AccessControlMode.acceptSelected
? appLocalizations.accessControlAllowDesc
: appLocalizations.accessControlNotAllowDesc;

return DisabledMask(
status: !isAccessControl,
child: Column(
Expand All @@ -241,7 +268,7 @@ class _AccessFragmentState extends State<AccessFragment> {
itemBuilder: (_, index) {
final package = currentPackages[index];
return PackageListItem(
key: Key(package.label),
key: Key(package.packageName),
package: package,
value:
valueList.contains(package.packageName),
Expand All @@ -252,11 +279,20 @@ class _AccessFragmentState extends State<AccessFragment> {
} else {
valueList.remove(package.packageName);
}
final config = context.read<Config>();
config.accessControl.currentList =
valueList;
config.accessControl =
config.accessControl.copyWith();
final config =
globalState.appController.config;
if (accessControlMode ==
AccessControlMode.acceptSelected) {
config.accessControl =
config.accessControl.copyWith(
acceptList: valueList,
);
} else {
config.accessControl =
config.accessControl.copyWith(
rejectList: valueList,
);
}
},
);
},
Expand All @@ -276,7 +312,7 @@ class _AccessFragmentState extends State<AccessFragment> {
Widget build(BuildContext context) {
return Selector<Config, bool>(
selector: (_, config) => config.isAccessControl,
builder: (_, isAccessControl, __) {
builder: (_, isAccessControl, child) {
return Column(
mainAxisSize: MainAxisSize.max,
children: [
Expand All @@ -300,11 +336,12 @@ class _AccessFragmentState extends State<AccessFragment> {
),
),
Flexible(
child: _buildPackageList(isAccessControl),
child: child!,
),
],
);
},
child: _buildPackageList(),
);
}
}
Expand Down
Loading

0 comments on commit 0512d69

Please sign in to comment.