fix ab tag flashing when refreshing (#7471)

* opt isFull, fix web console menu

Signed-off-by: 21pages <pages21@163.com>

* fix ab tag flashing when refreshing

Signed-off-by: 21pages <pages21@163.com>

---------

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2024-03-22 11:02:22 +08:00 committed by GitHub
parent 57b17b1798
commit 285e298a8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 57 deletions

View File

@ -376,13 +376,14 @@ class _AddressBookState extends State<AddressBook> {
sortMenuItem(),
syncMenuItem(),
filterMenuItem(),
MenuEntryDivider<String>(),
getEntry(translate("ab_web_console_tip"), () async {
final url = await bind.mainGetApiServer();
if (await canLaunchUrlString(url)) {
launchUrlString(url);
}
}),
if (!gFFI.abModel.legacyMode.value) MenuEntryDivider<String>(),
if (!gFFI.abModel.legacyMode.value)
getEntry(translate("ab_web_console_tip"), () async {
final url = await bind.mainGetApiServer();
if (await canLaunchUrlString(url)) {
launchUrlString(url);
}
}),
];
mod_menu.showMenu(

View File

@ -54,16 +54,12 @@ class AbModel {
final sortTags = shouldSortTags().obs;
final filterByIntersection = filterAbTagByIntersection().obs;
// licensedDevices is obtained from personal ab, shared ab restrict it in server
var licensedDevices = 0;
var _syncAllFromRecent = true;
var _syncFromRecentLock = false;
var _allInitialized = false;
var _timerCounter = 0;
var _cacheLoadOnceFlag = false;
var _everPulledProfiles = false;
// ignore: unused_field
var _maxPeerOneAb = 0;
WeakReference<FFI> parent;
@ -88,7 +84,6 @@ class AbModel {
addressbooks.clear();
setCurrentName('');
await bind.mainClearAb();
licensedDevices = 0;
_everPulledProfiles = false;
}
@ -104,6 +99,7 @@ class AbModel {
if (!force && _allInitialized) return;
_allInitialized = false;
try {
final tmpAddressbooks = Map<String, BaseAb>.fromEntries([]).obs;
// Get personal address book guid
_personalAbGuid = null;
await _getPersonalAbGuid();
@ -117,16 +113,21 @@ class AbModel {
// get all address book name
await _getSharedAbProfiles(tmpAbProfiles);
abProfiles = tmpAbProfiles;
addressbooks.clear();
for (int i = 0; i < abProfiles.length; i++) {
AbProfile p = abProfiles[i];
addressbooks[p.name] = Ab(p, p.guid == _personalAbGuid);
tmpAddressbooks[p.name] = Ab(p, p.guid == _personalAbGuid);
}
} else {
// only legacy address book
addressbooks.clear();
addressbooks[_legacyAddressBookName] = LegacyAb();
tmpAddressbooks[_legacyAddressBookName] = LegacyAb();
}
addressbooks
.removeWhere((key, value) => !tmpAddressbooks.containsKey(key));
tmpAddressbooks.forEach((key, value) {
if (!addressbooks.containsKey(key)) {
addressbooks[key] = value;
}
});
// set current address book name
if (!_everPulledProfiles) {
_everPulledProfiles = true;
@ -630,7 +631,12 @@ class AbModel {
}
bool isCurrentAbFull(bool warn) {
return current.isFull(warn);
final res = current.isFull();
if (res && warn) {
BotToast.showText(
contentColor: Colors.red, text: translate('exceed_max_devices'));
}
return res;
}
void _refreshTab() {
@ -646,7 +652,7 @@ class AbModel {
} else if (name != _legacyAddressBookName) {
final ab = addressbooks[name];
if (ab != null) {
return ab.pullAb(force: true, quiet: true);
return await ab.pullAb(force: true, quiet: true);
}
}
}
@ -710,7 +716,7 @@ abstract class BaseAb {
abLoading.value = true;
pullError.value = "";
}
final ret = pullAbImpl(force: force, quiet: quiet);
final ret = await pullAbImpl(force: force, quiet: quiet);
abLoading.value = false;
return ret;
}
@ -748,16 +754,7 @@ abstract class BaseAb {
Future<bool> deleteTag(String tag);
bool isFull(bool warn) {
bool res;
res = gFFI.abModel.licensedDevices > 0 &&
peers.length >= gFFI.abModel.licensedDevices;
if (res && warn) {
BotToast.showText(
contentColor: Colors.red, text: translate("exceed_max_devices"));
}
return res;
}
bool isFull();
AbProfile? sharedProfile();
@ -765,8 +762,6 @@ abstract class BaseAb {
bool fullControl();
bool allowUpdateSettingsOrDelete();
Future<void> syncFromRecent(List<Peer> recents);
}
@ -774,6 +769,8 @@ class LegacyAb extends BaseAb {
final sortTags = shouldSortTags().obs;
final filterByIntersection = filterAbTagByIntersection().obs;
bool get emtpy => peers.isEmpty && tags.isEmpty;
// licensedDevices is obtained from personal ab, shared ab restrict it in server
var licensedDevices = 0;
LegacyAb();
@ -793,8 +790,8 @@ class LegacyAb extends BaseAb {
}
@override
bool allowUpdateSettingsOrDelete() {
return false;
bool isFull() {
return licensedDevices > 0 && peers.length >= licensedDevices;
}
@override
@ -824,7 +821,7 @@ class LegacyAb extends BaseAb {
throw json['error'];
} else if (json.containsKey('data')) {
try {
gFFI.abModel.licensedDevices = json['licensed_devices'];
licensedDevices = json['licensed_devices'];
// ignore: empty_catches
} catch (e) {}
final data = jsonDecode(json['data']);
@ -862,7 +859,7 @@ class LegacyAb extends BaseAb {
final body = jsonEncode({"data": jsonEncode(_serialize())});
http.Response resp;
// support compression
if (gFFI.abModel.licensedDevices > 0 && body.length > 1024) {
if (licensedDevices > 0 && body.length > 1024) {
authHeaders['Content-Encoding'] = "gzip";
resp = await http.post(Uri.parse(api),
headers: authHeaders, body: GZipCodec().encode(utf8.encode(body)));
@ -903,7 +900,7 @@ class LegacyAb extends BaseAb {
Future<String?> addPeers(List<Map<String, dynamic>> ps) async {
bool full = false;
for (var p in ps) {
if (!isFull(false)) {
if (!isFull()) {
p.remove('password'); // legacy ab ignore password
final index = peers.indexWhere((e) => e.id == p['id']);
if (index >= 0) {
@ -981,7 +978,7 @@ class LegacyAb extends BaseAb {
var r = recents[i];
var index = peers.indexWhere((e) => e.id == r.id);
if (index < 0) {
if (!isFull(false)) {
if (!isFull()) {
peers.add(r);
needSync = true;
}
@ -1128,8 +1125,8 @@ class LegacyAb extends BaseAb {
peers.add(Peer.fromJson(peer));
}
}
if (isFull(false)) {
peers.removeRange(gFFI.abModel.licensedDevices, peers.length);
if (isFull()) {
peers.removeRange(licensedDevices, peers.length);
}
// restore online
peers
@ -1172,9 +1169,10 @@ class Ab extends BaseAb {
return profile;
}
bool creatorOrAdmin() {
return profile.owner == gFFI.userModel.userName.value ||
gFFI.userModel.isAdmin.value;
@override
bool isFull() {
return gFFI.abModel._maxPeerOneAb > 0 &&
peers.length >= gFFI.abModel._maxPeerOneAb;
}
@override
@ -1196,15 +1194,6 @@ class Ab extends BaseAb {
}
}
@override
bool allowUpdateSettingsOrDelete() {
if (personal) {
return false;
} else {
return creatorOrAdmin();
}
}
@override
Future<void> pullAbImpl({force = true, quiet = false}) async {
List<Peer> tmpPeers = [];
@ -1322,7 +1311,7 @@ class Ab extends BaseAb {
if (peers.firstWhereOrNull((e) => e.id == p['id']) != null) {
continue;
}
if (isFull(false)) {
if (isFull()) {
return translate("exceed_max_devices");
}
if (personal) {
@ -1624,6 +1613,11 @@ class Ab extends BaseAb {
// DummyAb is for current ab is null
class DummyAb extends BaseAb {
@override
bool isFull() {
return false;
}
@override
Future<String?> addPeers(List<Map<String, dynamic>> ps) async {
return "Unreachable";
@ -1645,11 +1639,6 @@ class DummyAb extends BaseAb {
return false;
}
@override
bool allowUpdateSettingsOrDelete() {
return false;
}
@override
Future<bool> changeAlias({required String id, required String alias}) async {
return false;