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