Skip to content

Commit 4db53f0

Browse files
committed
webui/exclude: fix uid handling
1 parent ece1675 commit 4db53f0

1 file changed

Lines changed: 59 additions & 24 deletions

File tree

webui/page/exclude.js

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ async function refreshAppList() {
3939
if (import.meta.env.DEV) { // vite debug
4040
allApps = [
4141
{ appLabel: 'Chrome', packageName: 'com.android.chrome', isSystem: false, uid: 10001 },
42+
{ appLabel: 'Chrome', packageName: 'com.android.chrome', isSystem: false, uid: 1010001 },
4243
{ appLabel: 'Google', packageName: 'com.google.android.googlequicksearchbox', isSystem: true, uid: 1010002 },
4344
{ appLabel: 'Settings', packageName: 'com.android.settings', isSystem: true, uid: 10003 },
4445
{ appLabel: 'WhatsApp', packageName: 'com.whatsapp', isSystem: false, uid: 10123 },
@@ -60,7 +61,16 @@ const appItemMap = new Map();
6061

6162
async function saveExcludedList(excludedApps) {
6263
const header = 'pkg,exclude,allow,uid';
63-
const lines = excludedApps.map(app => `${app.packageName},1,0,${app.uid % 100000}`);
64+
const seen = new Set();
65+
const uniqueList = [];
66+
excludedApps.forEach(app => {
67+
const key = `${app.packageName}:${app.uid % 100000}`;
68+
if (!seen.has(key)) {
69+
seen.add(key);
70+
uniqueList.push(app);
71+
}
72+
});
73+
const lines = uniqueList.map(app => `${app.packageName},1,0,${app.uid % 100000}`);
6474
const csvContent = [header, ...lines].join('\n');
6575
if (import.meta.env.DEV) {
6676
localStorage.setItem('kp-next_excluded_mock', csvContent);
@@ -105,18 +115,26 @@ async function renderAppList() {
105115

106116
// Consistency check
107117
if (allApps.length > 0) {
108-
const currentAppsMap = new Map(allApps.map(app => [(app.packageName || '').trim(), app]));
118+
const appByRealUid = new Map();
119+
allApps.forEach(app => {
120+
const rUid = app.uid % 100000;
121+
const key = `${(app.packageName || '').trim()}:${rUid}`;
122+
if (!appByRealUid.has(key)) appByRealUid.set(key, []);
123+
appByRealUid.get(key).push(app);
124+
});
109125

126+
excludedApps = [];
110127
let changed = false;
111-
excludedApps = list.map(item => {
112-
const app = currentAppsMap.get(item.packageName);
113-
if (!app) return item;
114-
const realUid = app.uid % 100000;
115-
if (realUid !== item.uid) {
116-
changed = true;
117-
return { packageName: item.packageName, uid: realUid };
128+
list.forEach(item => {
129+
const key = `${item.packageName}:${item.uid}`;
130+
const matches = appByRealUid.get(key);
131+
if (matches) {
132+
matches.forEach(app => {
133+
excludedApps.push({ packageName: app.packageName, uid: app.uid });
134+
});
135+
} else {
136+
excludedApps.push({ packageName: item.packageName, uid: item.uid });
118137
}
119-
return item;
120138
});
121139

122140
if (changed) {
@@ -127,19 +145,20 @@ async function renderAppList() {
127145
}
128146
}
129147

130-
const excludedPkgNames = new Set(excludedApps.map(app => app.packageName));
148+
const excludedAppKeys = new Set(excludedApps.map(app => `${app.packageName}:${app.uid}`));
131149

132150
const sortedApps = [...allApps].sort((a, b) => {
133-
const aExcluded = excludedPkgNames.has(a.packageName);
134-
const bExcluded = excludedPkgNames.has(b.packageName);
151+
const aExcluded = excludedAppKeys.has(`${a.packageName}:${a.uid}`);
152+
const bExcluded = excludedAppKeys.has(`${b.packageName}:${b.uid}`);
135153
if (aExcluded !== bExcluded) return aExcluded ? -1 : 1;
136154
return (a.appLabel || '').localeCompare(b.appLabel || '');
137155
});
138156

139157
emptyMsg.classList.add('hidden');
140158

141159
sortedApps.forEach(app => {
142-
let item = appItemMap.get(app.packageName);
160+
const appKey = `${app.packageName}:${app.uid}`;
161+
let item = appItemMap.get(appKey);
143162
if (!item) {
144163
item = document.createElement('label');
145164
item.className = 'app-item';
@@ -171,27 +190,43 @@ async function renderAppList() {
171190
let saveTimeout = null;
172191
toggle.addEventListener('change', () => {
173192
const realUid = app.uid % 100000;
174-
if (toggle.selected) {
175-
if (!excludedApps.some(e => e.packageName === app.packageName)) {
176-
excludedApps.push({ packageName: app.packageName, uid: realUid });
193+
const isSelected = toggle.selected;
194+
195+
// Sync state across all instances of the same app
196+
allApps.forEach(a => {
197+
if (a.packageName === app.packageName && (a.uid % 100000) === realUid) {
198+
if (isSelected) {
199+
if (!excludedApps.some(e => e.packageName === a.packageName && e.uid === a.uid)) {
200+
excludedApps.push({ packageName: a.packageName, uid: a.uid });
201+
}
202+
} else {
203+
excludedApps = excludedApps.filter(e => !(e.packageName === a.packageName && e.uid === a.uid));
204+
}
205+
206+
const otherItem = appItemMap.get(`${a.packageName}:${a.uid}`);
207+
if (otherItem) {
208+
const otherToggle = otherItem.querySelector('md-switch');
209+
if (otherToggle && otherToggle !== toggle) {
210+
otherToggle.selected = isSelected;
211+
}
212+
}
177213
}
178-
} else {
179-
excludedApps = excludedApps.filter(e => e.packageName !== app.packageName);
180-
}
214+
});
215+
181216
if (saveTimeout) clearTimeout(saveTimeout);
182217
saveTimeout = setTimeout(() => {
183218
saveExcludedList(excludedApps);
184219
}, 500);
185-
exec(`kpatch ${superkey} exclude_set ${realUid} ${toggle.selected ? 1 : 0}`, { env: { PATH: `${modDir}/bin` } });
220+
exec(`kpatch ${superkey} exclude_set ${realUid} ${isSelected ? 1 : 0}`, { env: { PATH: `${modDir}/bin` } });
186221
});
187222

188-
appItemMap.set(app.packageName, item);
223+
appItemMap.set(appKey, item);
189224
iconObserver.observe(item);
190225
}
191226

192227
// Update state
193228
const toggle = item.querySelector('md-switch');
194-
toggle.selected = excludedPkgNames.has(app.packageName);
229+
toggle.selected = excludedAppKeys.has(`${app.packageName}:${app.uid}`);
195230

196231
appList.appendChild(item);
197232
});
@@ -208,7 +243,7 @@ function applyFilters() {
208243
let visibleCount = 0;
209244

210245
allApps.forEach(app => {
211-
const item = appItemMap.get(app.packageName);
246+
const item = appItemMap.get(`${app.packageName}:${app.uid}`);
212247
if (!item) return;
213248

214249
const matchesSearch = (app.appLabel || '').toLowerCase().includes(query) ||

0 commit comments

Comments
 (0)