Upgrade hive database version to 14
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -90,28 +90,27 @@ class FileUtils {
|
|||||||
return emailContent;
|
return emailContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isFileExisted({
|
Future<Directory?> getFolder(String folderName) async {
|
||||||
required String nameFile,
|
try {
|
||||||
String? folderPath,
|
String folderPath = (await getApplicationDocumentsDirectory()).absolute.path;
|
||||||
String? extensionFile
|
folderPath = '$folderPath/$folderName';
|
||||||
}) async {
|
log('FileUtils::getFolder(): $folderPath');
|
||||||
final internalStorageDirPath = await _getInternalStorageDirPath(
|
return Directory(folderPath);
|
||||||
nameFile: nameFile,
|
} catch (e) {
|
||||||
folderPath: folderPath,
|
logError('FileUtils::getFolder():EXCEPTION: $e');
|
||||||
extensionFile: extensionFile
|
return null;
|
||||||
);
|
}
|
||||||
|
|
||||||
return File(internalStorageDirPath).exists();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> removeFolder(String folderName) async {
|
Future<void> removeFolder(String folderName) async {
|
||||||
try {
|
try {
|
||||||
String folderPath = (await getApplicationDocumentsDirectory()).absolute.path;
|
final dir = await getFolder(folderName);
|
||||||
folderPath = '$folderPath/$folderName';
|
if (dir == null) return;
|
||||||
log('FileUtils::removeFolder():folderPath: $folderPath');
|
|
||||||
final dir = Directory(folderPath);
|
|
||||||
if (await dir.exists()) {
|
if (await dir.exists()) {
|
||||||
await dir.delete(recursive: true);
|
await dir.delete(recursive: true);
|
||||||
|
await dir.create(); // Re-create folder
|
||||||
|
log('FileUtils::removeFolder: Remove ${dir.path} success');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logError('FileUtils::removeFolder():EXCEPTION: $e');
|
logError('FileUtils::removeFolder():EXCEPTION: $e');
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ void main() {
|
|||||||
final htmlValidate = sanitizeAutolinkFilter.process('See https://linagora.com at Hanoi');
|
final htmlValidate = sanitizeAutolinkFilter.process('See https://linagora.com at Hanoi');
|
||||||
expect(
|
expect(
|
||||||
htmlValidate,
|
htmlValidate,
|
||||||
equals('See <a href="https://linagora.com" target="_blank" rel="noreferrer">linagora.com</a> at Hanoi')
|
equals('See <a href="https://linagora.com" target="_blank" rel="noreferrer" style="white-space: nowrap; word-break: keep-all;">linagora.com</a> at Hanoi')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -25,7 +25,7 @@ void main() {
|
|||||||
final htmlValidate = sanitizeAutolinkFilter.process('See http://linagora.com at Hanoi');
|
final htmlValidate = sanitizeAutolinkFilter.process('See http://linagora.com at Hanoi');
|
||||||
expect(
|
expect(
|
||||||
htmlValidate,
|
htmlValidate,
|
||||||
equals('See <a href="http://linagora.com" target="_blank" rel="noreferrer">linagora.com</a> at Hanoi')
|
equals('See <a href="http://linagora.com" target="_blank" rel="noreferrer" style="white-space: nowrap; word-break: keep-all;">linagora.com</a> at Hanoi')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -36,7 +36,7 @@ void main() {
|
|||||||
final htmlValidate = sanitizeAutolinkFilter.process('See www.linagora.com at Hanoi');
|
final htmlValidate = sanitizeAutolinkFilter.process('See www.linagora.com at Hanoi');
|
||||||
expect(
|
expect(
|
||||||
htmlValidate,
|
htmlValidate,
|
||||||
equals('See <a href="https://www.linagora.com" target="_blank" rel="noreferrer">linagora.com</a> at Hanoi')
|
equals('See <a href="https://www.linagora.com" target="_blank" rel="noreferrer" style="white-space: nowrap; word-break: keep-all;">linagora.com</a> at Hanoi')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -47,7 +47,7 @@ void main() {
|
|||||||
final htmlValidate = sanitizeAutolinkFilter.process('See tdvu@linagora.com at Hanoi');
|
final htmlValidate = sanitizeAutolinkFilter.process('See tdvu@linagora.com at Hanoi');
|
||||||
expect(
|
expect(
|
||||||
htmlValidate,
|
htmlValidate,
|
||||||
equals('See <a href="mailto:tdvu@linagora.com">tdvu@linagora.com</a> at Hanoi')
|
equals('See <a href="mailto:tdvu@linagora.com" style="white-space: nowrap; word-break: keep-all;">tdvu@linagora.com</a> at Hanoi')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,13 +11,15 @@ void main() {
|
|||||||
const fileContent = 'Hello, World!';
|
const fileContent = 'Hello, World!';
|
||||||
|
|
||||||
group('fileUtils test', () {
|
group('fileUtils test', () {
|
||||||
|
final fileUtils = FileUtils();
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
PathProviderPlatform.instance = FakePathProviderPlatform();
|
PathProviderPlatform.instance = FakePathProviderPlatform();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Store private HTLM String to File', () async {
|
test('Store private HTLM String to File', () async {
|
||||||
|
|
||||||
final file = await FileUtils().saveToFile(nameFile: fileName, content: fileContent);
|
final file = await fileUtils.saveToFile(nameFile: fileName, content: fileContent);
|
||||||
|
|
||||||
expect(await file.exists(), equals(true));
|
expect(await file.exists(), equals(true));
|
||||||
|
|
||||||
@@ -29,9 +31,9 @@ void main() {
|
|||||||
test('Get HTML String from File Private', () async {
|
test('Get HTML String from File Private', () async {
|
||||||
|
|
||||||
/// Create a temporary file that will be deleted after `getFromFile` is done
|
/// Create a temporary file that will be deleted after `getFromFile` is done
|
||||||
final file = await FileUtils().saveToFile(nameFile: fileName, content: fileContent);
|
final file = await fileUtils.saveToFile(nameFile: fileName, content: fileContent);
|
||||||
|
|
||||||
final htmlString = await FileUtils().getContentFromFile(nameFile: fileName);
|
final htmlString = await fileUtils.getContentFromFile(nameFile: fileName);
|
||||||
|
|
||||||
expect(htmlString.isNotEmpty, equals(true));
|
expect(htmlString.isNotEmpty, equals(true));
|
||||||
|
|
||||||
@@ -47,10 +49,10 @@ void main() {
|
|||||||
'and Platform is mobile',
|
'and Platform is mobile',
|
||||||
() async {
|
() async {
|
||||||
// arrange
|
// arrange
|
||||||
final file = await FileUtils().saveToFile(nameFile: fileName, content: fileContent);
|
final file = await fileUtils.saveToFile(nameFile: fileName, content: fileContent);
|
||||||
|
|
||||||
// act
|
// act
|
||||||
await FileUtils().deleteCompressedFileOnMobile(file.path, pathContains: fileName);
|
await fileUtils.deleteCompressedFileOnMobile(file.path, pathContains: fileName);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(await file.exists(), equals(false));
|
expect(await file.exists(), equals(false));
|
||||||
@@ -64,11 +66,11 @@ void main() {
|
|||||||
() async {
|
() async {
|
||||||
// arrange
|
// arrange
|
||||||
debugDefaultTargetPlatformOverride = TargetPlatform.macOS;
|
debugDefaultTargetPlatformOverride = TargetPlatform.macOS;
|
||||||
final file = await FileUtils().saveToFile(nameFile: fileName, content: fileContent);
|
final file = await fileUtils.saveToFile(nameFile: fileName, content: fileContent);
|
||||||
expect(await file.exists(), equals(true));
|
expect(await file.exists(), equals(true));
|
||||||
|
|
||||||
// act
|
// act
|
||||||
await FileUtils().deleteCompressedFileOnMobile(file.path, pathContains: fileName);
|
await fileUtils.deleteCompressedFileOnMobile(file.path, pathContains: fileName);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
expect(await file.exists(), equals(true));
|
expect(await file.exists(), equals(true));
|
||||||
|
|||||||
@@ -373,6 +373,14 @@ void main() {
|
|||||||
expect(StringConvert.isTextTable(table), isTrue);
|
expect(StringConvert.isTextTable(table), isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should return true for separator-only Markdown', () {
|
||||||
|
const text = """
|
||||||
|
|----------|----------|
|
||||||
|
|----------|----------|
|
||||||
|
""";
|
||||||
|
expect(StringConvert.isTextTable(text), isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
// Test cases cho ASCII art tables
|
// Test cases cho ASCII art tables
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
@@ -437,14 +445,6 @@ void main() {
|
|||||||
expect(StringConvert.isTextTable(' \n \n '), isFalse);
|
expect(StringConvert.isTextTable(' \n \n '), isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return true for separator-only Markdown', () {
|
|
||||||
const text = """
|
|
||||||
|----------|----------|
|
|
||||||
|----------|----------|
|
|
||||||
""";
|
|
||||||
expect(StringConvert.isTextTable(text), isTrue);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should return false for single-line Markdown', () {
|
test('should return false for single-line Markdown', () {
|
||||||
const text = '| Header 1 | Header 2 |';
|
const text = '| Header 1 | Header 2 |';
|
||||||
expect(StringConvert.isTextTable(text), isFalse);
|
expect(StringConvert.isTextTable(text), isFalse);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class UpgradeHiveDatabaseStepsV11 extends UpgradeDatabaseSteps {
|
|||||||
@override
|
@override
|
||||||
Future<void> onUpgrade(int oldVersion, int newVersion) async {
|
Future<void> onUpgrade(int oldVersion, int newVersion) async {
|
||||||
if (oldVersion > 0 && oldVersion < newVersion && newVersion == 11) {
|
if (oldVersion > 0 && oldVersion < newVersion && newVersion == 11) {
|
||||||
await _cachingManager.clearEmailCacheAndAllStateCache();
|
await _cachingManager.clearAllEmailAndStateCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ class UpgradeHiveDatabaseStepsV12 extends UpgradeDatabaseSteps {
|
|||||||
@override
|
@override
|
||||||
Future<void> onUpgrade(int oldVersion, int newVersion) async {
|
Future<void> onUpgrade(int oldVersion, int newVersion) async {
|
||||||
if (oldVersion > 0 && oldVersion < newVersion && newVersion == 12) {
|
if (oldVersion > 0 && oldVersion < newVersion && newVersion == 12) {
|
||||||
await _cachingManager.clearEmailCacheAndAllStateCache();
|
await _cachingManager.clearAllEmailAndStateCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_database_steps.dart';
|
||||||
|
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
|
||||||
|
|
||||||
|
class UpgradeHiveDatabaseStepsV14 extends UpgradeDatabaseSteps {
|
||||||
|
|
||||||
|
final CachingManager _cachingManager;
|
||||||
|
|
||||||
|
UpgradeHiveDatabaseStepsV14(this._cachingManager);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onUpgrade(int oldVersion, int newVersion) async {
|
||||||
|
if (oldVersion > 0 && oldVersion < newVersion && newVersion == 14) {
|
||||||
|
await _cachingManager.clearAllEmailAndStateCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:core/utils/file_utils.dart';
|
import 'package:core/utils/file_utils.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
|
import 'package:fcm/model/type_name.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||||
|
import 'package:model/extensions/account_id_extensions.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/clients/account_cache_client.dart';
|
import 'package:tmail_ui_user/features/caching/clients/account_cache_client.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/clients/email_cache_client.dart';
|
import 'package:tmail_ui_user/features/caching/clients/email_cache_client.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/clients/fcm_cache_client.dart';
|
import 'package:tmail_ui_user/features/caching/clients/fcm_cache_client.dart';
|
||||||
@@ -17,11 +19,13 @@ import 'package:tmail_ui_user/features/caching/clients/recent_search_cache_clien
|
|||||||
import 'package:tmail_ui_user/features/caching/clients/session_hive_cache_client.dart';
|
import 'package:tmail_ui_user/features/caching/clients/session_hive_cache_client.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/clients/state_cache_client.dart';
|
import 'package:tmail_ui_user/features/caching/clients/state_cache_client.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
|
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
|
||||||
|
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
|
import 'package:tmail_ui_user/features/caching/utils/caching_constants.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
|
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_spam_report_manager.dart';
|
import 'package:tmail_ui_user/features/mailbox_dashboard/data/local/local_spam_report_manager.dart';
|
||||||
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
|
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
|
||||||
import 'package:tmail_ui_user/features/push_notification/data/keychain/keychain_sharing_manager.dart';
|
import 'package:tmail_ui_user/features/push_notification/data/keychain/keychain_sharing_manager.dart';
|
||||||
|
import 'package:tmail_ui_user/features/push_notification/presentation/extensions/type_name_extension.dart';
|
||||||
|
|
||||||
class CachingManager {
|
class CachingManager {
|
||||||
final MailboxCacheClient _mailboxCacheClient;
|
final MailboxCacheClient _mailboxCacheClient;
|
||||||
@@ -102,24 +106,58 @@ class CachingManager {
|
|||||||
], eagerError: true);
|
], eagerError: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> clearEmailCacheAndStateCacheByTupleKey(AccountId accountId, Session session) {
|
Future<void> clearEmailAndStateCache({AccountId? accountId, UserName? userName}) {
|
||||||
return Future.wait([
|
log('CachingManager::clearEmailAndStateCache:userName = $userName');
|
||||||
_stateCacheClient.deleteItem(StateType.email.getTupleKeyStored(accountId, session.username)),
|
if (accountId != null && userName != null) {
|
||||||
_emailCacheClient.clearAllData(),
|
final emailKey = TupleKey(accountId.asString, userName.value).encodeKey;
|
||||||
if (PlatformInfo.isMobile) clearAllFileInStorage(),
|
final stateKey = StateType.email.getTupleKeyStored(accountId, userName);
|
||||||
], eagerError: true);
|
|
||||||
|
return Future.wait([
|
||||||
|
_emailCacheClient.clearAllDataContainKey(emailKey),
|
||||||
|
_stateCacheClient.deleteItem(stateKey),
|
||||||
|
if (PlatformInfo.isMobile)
|
||||||
|
clearFCMEmailStateCache(accountId: accountId, userName: userName),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
final stateKey = StateType.email.getTupleKeyStoredWithoutAccount();
|
||||||
|
return Future.wait([
|
||||||
|
_emailCacheClient.clearAllData(),
|
||||||
|
_stateCacheClient.deleteItem(stateKey),
|
||||||
|
if (PlatformInfo.isMobile) clearFCMEmailStateCache(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> clearEmailCacheAndAllStateCache() {
|
Future<void> clearDetailedEmailCache({AccountId? accountId, UserName? userName}) {
|
||||||
|
log('CachingManager::clearDetailedEmailCache:userName = $userName');
|
||||||
|
if (accountId != null && userName != null) {
|
||||||
|
final emailKey = TupleKey(accountId.asString, userName.value).encodeKey;
|
||||||
|
return Future.wait([
|
||||||
|
_newEmailHiveCacheClient.clearAllDataContainKey(emailKey),
|
||||||
|
_openedEmailHiveCacheClient.clearAllDataContainKey(emailKey),
|
||||||
|
clearAllFileInStorage(),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return Future.wait([
|
||||||
|
_newEmailHiveCacheClient.clearAllData(),
|
||||||
|
_openedEmailHiveCacheClient.clearAllData(),
|
||||||
|
clearAllFileInStorage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> clearAllEmailAndStateCache({AccountId? accountId, UserName? userName}) {
|
||||||
|
log('CachingManager::clearAllEmailAndStateCache:userName = $userName');
|
||||||
return Future.wait([
|
return Future.wait([
|
||||||
_stateCacheClient.clearAllData(),
|
clearEmailAndStateCache(accountId: accountId, userName: userName),
|
||||||
_emailCacheClient.clearAllData(),
|
if (PlatformInfo.isMobile)
|
||||||
if (PlatformInfo.isMobile) clearAllFileInStorage(),
|
clearDetailedEmailCache(accountId: accountId, userName: userName),
|
||||||
], eagerError: true);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> clearMailboxCache() {
|
Future<void> clearMailboxCache() {
|
||||||
return Future.wait([
|
return Future.wait([
|
||||||
|
_stateCacheClient.deleteItem(StateType.mailbox.getTupleKeyStoredWithoutAccount()),
|
||||||
_mailboxCacheClient.clearAllData(),
|
_mailboxCacheClient.clearAllData(),
|
||||||
], eagerError: true);
|
], eagerError: true);
|
||||||
}
|
}
|
||||||
@@ -138,10 +176,22 @@ class CachingManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> clearAllFileInStorage() async {
|
Future<void> clearAllFileInStorage() async {
|
||||||
await Future.wait([
|
await _fileUtils.removeFolder(CachingConstants.openedEmailContentFolderName);
|
||||||
_fileUtils.removeFolder(CachingConstants.newEmailsContentFolderName),
|
await _fileUtils.removeFolder(CachingConstants.newEmailsContentFolderName);
|
||||||
_fileUtils.removeFolder(CachingConstants.openedEmailContentFolderName),
|
}
|
||||||
]);
|
|
||||||
|
Future<void> clearFCMEmailStateCache({AccountId? accountId, UserName? userName}) async {
|
||||||
|
if (accountId != null && userName != null) {
|
||||||
|
await _fcmCacheClient.deleteItem(
|
||||||
|
TypeName.emailDelivery.getTupleKeyStored(accountId, userName));
|
||||||
|
await _fcmCacheClient.deleteItem(
|
||||||
|
TypeName.emailType.getTupleKeyStored(accountId, userName));
|
||||||
|
} else {
|
||||||
|
await _fcmCacheClient.deleteItem(
|
||||||
|
TypeName.emailDelivery.getTupleKeyStoredWithoutAccount());
|
||||||
|
await _fcmCacheClient.deleteItem(
|
||||||
|
TypeName.emailType.getTupleKeyStoredWithoutAccount());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> clearLoginRecentData() async {
|
Future<void> clearLoginRecentData() async {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
class CacheVersion {
|
class CacheVersion {
|
||||||
static const int hiveDBVersion = 12;
|
static const int hiveDBVersion = 14;
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_st
|
|||||||
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v11.dart';
|
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v11.dart';
|
||||||
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v12.dart';
|
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v12.dart';
|
||||||
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v13.dart';
|
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v13.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v14.dart';
|
||||||
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v7.dart';
|
import 'package:tmail_ui_user/features/base/upgradeable/upgrade_hive_database_steps_v7.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
|
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/config/cache_version.dart';
|
import 'package:tmail_ui_user/features/caching/config/cache_version.dart';
|
||||||
@@ -72,6 +73,7 @@ class HiveCacheConfig {
|
|||||||
await UpgradeHiveDatabaseStepsV11(cachingManager).onUpgrade(oldVersion, newVersion);
|
await UpgradeHiveDatabaseStepsV11(cachingManager).onUpgrade(oldVersion, newVersion);
|
||||||
await UpgradeHiveDatabaseStepsV12(cachingManager).onUpgrade(oldVersion, newVersion);
|
await UpgradeHiveDatabaseStepsV12(cachingManager).onUpgrade(oldVersion, newVersion);
|
||||||
await UpgradeHiveDatabaseStepsV13(cachingManager).onUpgrade(oldVersion, newVersion);
|
await UpgradeHiveDatabaseStepsV13(cachingManager).onUpgrade(oldVersion, newVersion);
|
||||||
|
await UpgradeHiveDatabaseStepsV14(cachingManager).onUpgrade(oldVersion, newVersion);
|
||||||
|
|
||||||
if (oldVersion != newVersion) {
|
if (oldVersion != newVersion) {
|
||||||
await cachingManager.storeCacheVersion(newVersion);
|
await cachingManager.storeCacheVersion(newVersion);
|
||||||
|
|||||||
@@ -20,4 +20,8 @@ enum StateType {
|
|||||||
String getTupleKeyStored(AccountId accountId, UserName userName) {
|
String getTupleKeyStored(AccountId accountId, UserName userName) {
|
||||||
return TupleKey(name, accountId.asString, userName.value).encodeKey;
|
return TupleKey(name, accountId.asString, userName.value).encodeKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getTupleKeyStoredWithoutAccount() {
|
||||||
|
return TupleKey(name).encodeKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import 'package:fcm/model/type_name.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||||
|
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||||
|
import 'package:model/extensions/account_id_extensions.dart';
|
||||||
|
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
|
||||||
|
|
||||||
|
extension TypeNameExtension on TypeName {
|
||||||
|
String getTupleKeyStored(AccountId accountId, UserName userName) {
|
||||||
|
return TupleKey(value, accountId.asString, userName.value).encodeKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getTupleKeyStoredWithoutAccount() {
|
||||||
|
return TupleKey(value).encodeKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -457,11 +457,10 @@ class ThreadController extends BaseController with EmailActionController {
|
|||||||
void _handleErrorGetAllOrRefreshChangesEmail(Object error, StackTrace stackTrace) async {
|
void _handleErrorGetAllOrRefreshChangesEmail(Object error, StackTrace stackTrace) async {
|
||||||
logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error');
|
logError('ThreadController::_handleErrorGetAllOrRefreshChangesEmail():Error: $error');
|
||||||
if (error is CannotCalculateChangesMethodResponseException) {
|
if (error is CannotCalculateChangesMethodResponseException) {
|
||||||
if (_accountId != null && _session != null) {
|
await cachingManager.clearAllEmailAndStateCache(
|
||||||
await cachingManager.clearEmailCacheAndStateCacheByTupleKey(_accountId!, _session!);
|
accountId: _accountId,
|
||||||
} else {
|
userName: _session?.username,
|
||||||
await cachingManager.clearEmailCacheAndAllStateCache();
|
);
|
||||||
}
|
|
||||||
_getAllEmailAction();
|
_getAllEmailAction();
|
||||||
} else if (error is MethodLevelErrors) {
|
} else if (error is MethodLevelErrors) {
|
||||||
if (currentOverlayContext != null && error.message != null) {
|
if (currentOverlayContext != null && error.message != null) {
|
||||||
|
|||||||
@@ -346,9 +346,9 @@ void main() {
|
|||||||
const eventDescription = '\nhttps://example1.com\nhttps://example2.com';
|
const eventDescription = '\nhttps://example1.com\nhttps://example2.com';
|
||||||
const expectedEventDescription = '<html><head></head><body>'
|
const expectedEventDescription = '<html><head></head><body>'
|
||||||
'<br>'
|
'<br>'
|
||||||
'<a href="https://example1.com" target="_blank" rel="noreferrer">example1.com</a>'
|
'<a href="https://example1.com" target="_blank" rel="noreferrer" style="white-space: nowrap; word-break: keep-all;">example1.com</a>'
|
||||||
'<br>'
|
'<br>'
|
||||||
'<a href="https://example2.com" target="_blank" rel="noreferrer">example2.com</a>'
|
'<a href="https://example2.com" target="_blank" rel="noreferrer" style="white-space: nowrap; word-break: keep-all;">example2.com</a>'
|
||||||
'</body></html>';
|
'</body></html>';
|
||||||
final blobId = Id('abc123');
|
final blobId = Id('abc123');
|
||||||
final calendarEvent = CalendarEvent(
|
final calendarEvent = CalendarEvent(
|
||||||
@@ -402,9 +402,9 @@ void main() {
|
|||||||
'\n<a href="javascript:alert(1)">href xss</a>';
|
'\n<a href="javascript:alert(1)">href xss</a>';
|
||||||
const expectedEventDescription = '<html><head></head><body>'
|
const expectedEventDescription = '<html><head></head><body>'
|
||||||
'<br>'
|
'<br>'
|
||||||
'<a href="https://example1.com" target="_blank" rel="noreferrer">example1.com</a>'
|
'<a href="https://example1.com" target="_blank" rel="noreferrer" style="white-space: nowrap; word-break: keep-all;">example1.com</a>'
|
||||||
'<br>'
|
'<br>'
|
||||||
'<a href="https://example2.com" target="_blank" rel="noreferrer">example2.com</a>'
|
'<a href="https://example2.com" target="_blank" rel="noreferrer" style="white-space: nowrap; word-break: keep-all;">example2.com</a>'
|
||||||
'<br>'
|
'<br>'
|
||||||
'<br>'
|
'<br>'
|
||||||
'<a>href xss</a>'
|
'<a>href xss</a>'
|
||||||
|
|||||||
Reference in New Issue
Block a user