Compare commits
	
		
			5 Commits
		
	
	
		
			3.2.0+133
			...
			1c2f25a152
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1c2f25a152 | |||
| be26ea280e | |||
| b4996d069f | |||
| bf4892b34d | |||
| 5f84751fd5 | 
| @@ -264,14 +264,14 @@ | |||||||
|   "createStickerPack": "Create a Sticker Pack", |   "createStickerPack": "Create a Sticker Pack", | ||||||
|   "editStickerPack": "Edit Sticker Pack", |   "editStickerPack": "Edit Sticker Pack", | ||||||
|   "deleteStickerPack": "Delete Sticker Pack", |   "deleteStickerPack": "Delete Sticker Pack", | ||||||
|   "deleteStickerPackHint": "Are you sure to delete this sticker pack? This action cannot be undone.", |   "deleteStickerPackHint": "Are you sure you want to delete this sticker pack? This action cannot be undone.", | ||||||
|   "stickerPackPrefix": "Prefix", |   "stickerPackPrefix": "Prefix", | ||||||
|   "stickerPackPrefixHint": "The prefix will be added before each stickers' slug in this pack.", |   "stickerPackPrefixHint": "The prefix will be added before each stickers' slug in this pack.", | ||||||
|   "stickers": "Stickers", |   "stickers": "Stickers", | ||||||
|   "createSticker": "Create a Sticker", |   "createSticker": "Create a Sticker", | ||||||
|   "editSticker": "Edit Sticker", |   "editSticker": "Edit Sticker", | ||||||
|   "deleteSticker": "Delete Sticker", |   "deleteSticker": "Delete Sticker", | ||||||
|   "deleteStickerHint": "Are you sure to delete this sticker? This action cannot be undone.", |   "deleteStickerHint": "Are you sure you want to delete this sticker? This action cannot be undone.", | ||||||
|   "stickerImage": "Image", |   "stickerImage": "Image", | ||||||
|   "stickerSlug": "Slug", |   "stickerSlug": "Slug", | ||||||
|   "stickerSlugHint": "The slug will be combined with the prefix to form the sticker's unique identifier.", |   "stickerSlugHint": "The slug will be combined with the prefix to form the sticker's unique identifier.", | ||||||
| @@ -350,11 +350,11 @@ | |||||||
|   "levelingStage12": "Transcendent", |   "levelingStage12": "Transcendent", | ||||||
|   "fileUploadingProgress": "Uploading file #{}: {}%", |   "fileUploadingProgress": "Uploading file #{}: {}%", | ||||||
|   "removeChatMember": "Remove Chat Room Member", |   "removeChatMember": "Remove Chat Room Member", | ||||||
|   "removeChatMemberHint": "Are you sure to remove this member from the room?", |   "removeChatMemberHint": "Are you sure you want to remove this member from the room?", | ||||||
|   "removeRealmMember": "Remove Realm Member", |   "removeRealmMember": "Remove Realm Member", | ||||||
|   "removeRealmMemberHint": "Are you sure to remove this member from the realm?", |   "removeRealmMemberHint": "Are you sure you want to remove this member from the realm?", | ||||||
|   "removePublisherMember": "Remove Publisher Member", |   "removePublisherMember": "Remove Publisher Member", | ||||||
|   "removePublisherMemberHint": "Are you sure to remove this member from the publisher?", |   "removePublisherMemberHint": "Are you sure you want to remove this member from the publisher?", | ||||||
|   "memberRole": "Member Role", |   "memberRole": "Member Role", | ||||||
|   "memberRoleHint": "Greater number has higher permission.", |   "memberRoleHint": "Greater number has higher permission.", | ||||||
|   "memberRoleEdit": "Edit role for @{}", |   "memberRoleEdit": "Edit role for @{}", | ||||||
| @@ -363,9 +363,9 @@ | |||||||
|   "brokenLink": "Unable open link {}... It might be broken or missing uri parts...", |   "brokenLink": "Unable open link {}... It might be broken or missing uri parts...", | ||||||
|   "copyToClipboard": "Copy to clipboard", |   "copyToClipboard": "Copy to clipboard", | ||||||
|   "leaveChatRoom": "Leave Chat Room", |   "leaveChatRoom": "Leave Chat Room", | ||||||
|   "leaveChatRoomHint": "Are you sure to leave this chat room?", |   "leaveChatRoomHint": "Are you sure you want to leave this chat room?", | ||||||
|   "leaveRealm": "Leave Realm", |   "leaveRealm": "Leave Realm", | ||||||
|   "leaveRealmHint": "Are you sure to leave this realm?", |   "leaveRealmHint": "Are you sure you want to leave this realm?", | ||||||
|   "walletNotFound": "Wallet not found", |   "walletNotFound": "Wallet not found", | ||||||
|   "walletCreateHint": "You don't have a wallet yet. Create one to start using the Solar Network eWallet.", |   "walletCreateHint": "You don't have a wallet yet. Create one to start using the Solar Network eWallet.", | ||||||
|   "walletCreate": "Create a Wallet", |   "walletCreate": "Create a Wallet", | ||||||
| @@ -468,7 +468,7 @@ | |||||||
|     "one": "{} is typing...", |     "one": "{} is typing...", | ||||||
|     "other": "{} are typing..." |     "other": "{} are typing..." | ||||||
|   }, |   }, | ||||||
|   "authDeviceEditLabel": "Edit Label", |   "authDeviceEditLabel": "Edit Device Label", | ||||||
|   "authDeviceLabelTitle": "Edit Device Label", |   "authDeviceLabelTitle": "Edit Device Label", | ||||||
|   "authDeviceLabelHint": "Enter a name for this device", |   "authDeviceLabelHint": "Enter a name for this device", | ||||||
|   "authDeviceSwipeEditHint": "Swipe left to edit label", |   "authDeviceSwipeEditHint": "Swipe left to edit label", | ||||||
| @@ -536,7 +536,7 @@ | |||||||
|   "contactMethodPrimary": "Primary", |   "contactMethodPrimary": "Primary", | ||||||
|   "contactMethodSetPrimary": "Set as Primary", |   "contactMethodSetPrimary": "Set as Primary", | ||||||
|   "contactMethodSetPrimaryHint": "Set this contact method as your primary contact method for account recovery and notifications", |   "contactMethodSetPrimaryHint": "Set this contact method as your primary contact method for account recovery and notifications", | ||||||
|   "contactMethodDeleteHint": "Are you sure to delete this contact method? This action cannot be undone.", |   "contactMethodDeleteHint": "Are you sure you want to delete this contact method? This action cannot be undone.", | ||||||
|   "contactMethodMakePublic": "Make Public", |   "contactMethodMakePublic": "Make Public", | ||||||
|   "contactMethodMakePrivate": "Make Private", |   "contactMethodMakePrivate": "Make Private", | ||||||
|   "contactMethodPublic": "Public", |   "contactMethodPublic": "Public", | ||||||
| @@ -662,8 +662,6 @@ | |||||||
|   "abuseReportSuccess": "Report submitted successfully. Thank you for helping keep our community safe.", |   "abuseReportSuccess": "Report submitted successfully. Thank you for helping keep our community safe.", | ||||||
|   "abuseReportError": "Failed to submit report. Please try again.", |   "abuseReportError": "Failed to submit report. Please try again.", | ||||||
|   "abuseReportReasonRequired": "Please provide details about the issue", |   "abuseReportReasonRequired": "Please provide details about the issue", | ||||||
|   "abuseReportSuccessTitle": "Report Submitted", |  | ||||||
|   "abuseReportErrorTitle": "Error", |  | ||||||
|   "abuseReportTypeSpam": "Spam or Misleading", |   "abuseReportTypeSpam": "Spam or Misleading", | ||||||
|   "abuseReportTypeHarassment": "Harassment or Abuse", |   "abuseReportTypeHarassment": "Harassment or Abuse", | ||||||
|   "abuseReportTypeInappropriate": "Inappropriate Content", |   "abuseReportTypeInappropriate": "Inappropriate Content", | ||||||
| @@ -845,11 +843,6 @@ | |||||||
|   "postCategorySports": "Sports", |   "postCategorySports": "Sports", | ||||||
|   "postCategoryFinance": "Finance", |   "postCategoryFinance": "Finance", | ||||||
|   "postCategoryLife": "Life", |   "postCategoryLife": "Life", | ||||||
|   "postCategoryArt": "Art", |  | ||||||
|   "postCategoryStudy": "Study", |  | ||||||
|   "postCategoryGaming": "Gaming", |  | ||||||
|   "postCategoryProgramming": "Programming", |  | ||||||
|   "postCategoryMusic": "Music", |  | ||||||
|   "links": "Links", |   "links": "Links", | ||||||
|   "addLink": "Add link", |   "addLink": "Add link", | ||||||
|   "linkKey": "Link Name", |   "linkKey": "Link Name", | ||||||
| @@ -1062,5 +1055,12 @@ | |||||||
|   "deleteRecycledFiles": "Delete Recycled Files", |   "deleteRecycledFiles": "Delete Recycled Files", | ||||||
|   "recycledFilesDeleted": "Recycled files deleted successfully", |   "recycledFilesDeleted": "Recycled files deleted successfully", | ||||||
|   "failedToDeleteRecycledFiles": "Failed to delete recycled files", |   "failedToDeleteRecycledFiles": "Failed to delete recycled files", | ||||||
|   "upload": "Upload" |   "upload": "Upload", | ||||||
|  |   "fileInfoTitle": "File Information", | ||||||
|  |   "fileHashCopied": "File hash copied to clipboard", | ||||||
|  |   "fileIdCopied": "File ID copied to clipboard", | ||||||
|  |   "fileNameCopied": "File name copied to clipboard", | ||||||
|  |   "fileMetadata": "File Metadata", | ||||||
|  |   "userMetadata": "User Metadata", | ||||||
|  |   "valueCopied": "Value copied to clipboard" | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,17 +33,27 @@ class AppDatabase extends _$AppDatabase { | |||||||
|         await _migrateToVersion6(m); |         await _migrateToVersion6(m); | ||||||
|       } |       } | ||||||
|       if (from < 7) { |       if (from < 7) { | ||||||
|         // Add new columns from SnChatMessage |         // Add new columns from SnChatMessage, ignore if they already exist | ||||||
|         await m.addColumn(chatMessages, chatMessages.updatedAt); |         final columnsToAdd = [ | ||||||
|         await m.addColumn(chatMessages, chatMessages.deletedAt); |           chatMessages.updatedAt, | ||||||
|         await m.addColumn(chatMessages, chatMessages.type); |           chatMessages.deletedAt, | ||||||
|         await m.addColumn(chatMessages, chatMessages.meta); |           chatMessages.type, | ||||||
|         await m.addColumn(chatMessages, chatMessages.membersMentioned); |           chatMessages.meta, | ||||||
|         await m.addColumn(chatMessages, chatMessages.editedAt); |           chatMessages.membersMentioned, | ||||||
|         await m.addColumn(chatMessages, chatMessages.attachments); |           chatMessages.editedAt, | ||||||
|         await m.addColumn(chatMessages, chatMessages.reactions); |           chatMessages.attachments, | ||||||
|         await m.addColumn(chatMessages, chatMessages.repliedMessageId); |           chatMessages.reactions, | ||||||
|         await m.addColumn(chatMessages, chatMessages.forwardedMessageId); |           chatMessages.repliedMessageId, | ||||||
|  |           chatMessages.forwardedMessageId, | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         for (final column in columnsToAdd) { | ||||||
|  |           try { | ||||||
|  |             await m.addColumn(chatMessages, column); | ||||||
|  |           } catch (e) { | ||||||
|  |             // Column already exists, skip | ||||||
|  |           } | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|   ); |   ); | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import 'package:freezed_annotation/freezed_annotation.dart'; | import 'package:freezed_annotation/freezed_annotation.dart'; | ||||||
|  | import 'package:island/models/file_pool.dart'; | ||||||
|  |  | ||||||
| part 'file.freezed.dart'; | part 'file.freezed.dart'; | ||||||
| part 'file.g.dart'; | part 'file.g.dart'; | ||||||
| @@ -42,6 +43,7 @@ sealed class SnCloudFile with _$SnCloudFile { | |||||||
|     required String? description, |     required String? description, | ||||||
|     required Map<String, dynamic>? fileMeta, |     required Map<String, dynamic>? fileMeta, | ||||||
|     required Map<String, dynamic>? userMeta, |     required Map<String, dynamic>? userMeta, | ||||||
|  |     required SnFilePool? pool, | ||||||
|     @Default([]) List<int> sensitiveMarks, |     @Default([]) List<int> sensitiveMarks, | ||||||
|     required String? mimeType, |     required String? mimeType, | ||||||
|     required String? hash, |     required String? hash, | ||||||
|   | |||||||
| @@ -278,7 +278,7 @@ as bool, | |||||||
| /// @nodoc | /// @nodoc | ||||||
| mixin _$SnCloudFile { | mixin _$SnCloudFile { | ||||||
|  |  | ||||||
|  String get id; String get name; String? get description; Map<String, dynamic>? get fileMeta; Map<String, dynamic>? get userMeta; List<int> get sensitiveMarks; String? get mimeType; String? get hash; int get size; DateTime? get uploadedAt; String? get uploadedTo; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; |  String get id; String get name; String? get description; Map<String, dynamic>? get fileMeta; Map<String, dynamic>? get userMeta; SnFilePool? get pool; List<int> get sensitiveMarks; String? get mimeType; String? get hash; int get size; DateTime? get uploadedAt; String? get uploadedTo; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; | ||||||
| /// Create a copy of SnCloudFile | /// Create a copy of SnCloudFile | ||||||
| /// with the given fields replaced by the non-null parameter values. | /// with the given fields replaced by the non-null parameter values. | ||||||
| @JsonKey(includeFromJson: false, includeToJson: false) | @JsonKey(includeFromJson: false, includeToJson: false) | ||||||
| @@ -291,16 +291,16 @@ $SnCloudFileCopyWith<SnCloudFile> get copyWith => _$SnCloudFileCopyWithImpl<SnCl | |||||||
|  |  | ||||||
| @override | @override | ||||||
| bool operator ==(Object other) { | bool operator ==(Object other) { | ||||||
|   return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&const DeepCollectionEquality().equals(other.sensitiveMarks, sensitiveMarks)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); |   return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&(identical(other.pool, pool) || other.pool == pool)&&const DeepCollectionEquality().equals(other.sensitiveMarks, sensitiveMarks)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @JsonKey(includeFromJson: false, includeToJson: false) | @JsonKey(includeFromJson: false, includeToJson: false) | ||||||
| @override | @override | ||||||
| int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(fileMeta),const DeepCollectionEquality().hash(userMeta),const DeepCollectionEquality().hash(sensitiveMarks),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt); | int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(fileMeta),const DeepCollectionEquality().hash(userMeta),pool,const DeepCollectionEquality().hash(sensitiveMarks),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt); | ||||||
|  |  | ||||||
| @override | @override | ||||||
| String toString() { | String toString() { | ||||||
|   return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; |   return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, pool: $pool, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -311,11 +311,11 @@ abstract mixin class $SnCloudFileCopyWith<$Res>  { | |||||||
|   factory $SnCloudFileCopyWith(SnCloudFile value, $Res Function(SnCloudFile) _then) = _$SnCloudFileCopyWithImpl; |   factory $SnCloudFileCopyWith(SnCloudFile value, $Res Function(SnCloudFile) _then) = _$SnCloudFileCopyWithImpl; | ||||||
| @useResult | @useResult | ||||||
| $Res call({ | $Res call({ | ||||||
|  String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt |  String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, SnFilePool? pool, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | $SnFilePoolCopyWith<$Res>? get pool; | ||||||
|  |  | ||||||
| } | } | ||||||
| /// @nodoc | /// @nodoc | ||||||
| @@ -328,14 +328,15 @@ class _$SnCloudFileCopyWithImpl<$Res> | |||||||
|  |  | ||||||
| /// Create a copy of SnCloudFile | /// Create a copy of SnCloudFile | ||||||
| /// with the given fields replaced by the non-null parameter values. | /// with the given fields replaced by the non-null parameter values. | ||||||
| @pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? sensitiveMarks = null,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { | @pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? pool = freezed,Object? sensitiveMarks = null,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { | ||||||
|   return _then(_self.copyWith( |   return _then(_self.copyWith( | ||||||
| id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable | id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable | ||||||
| as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable | as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable | ||||||
| as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable | as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable | ||||||
| as String?,fileMeta: freezed == fileMeta ? _self.fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable | as String?,fileMeta: freezed == fileMeta ? _self.fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable | ||||||
| as Map<String, dynamic>?,userMeta: freezed == userMeta ? _self.userMeta : userMeta // ignore: cast_nullable_to_non_nullable | as Map<String, dynamic>?,userMeta: freezed == userMeta ? _self.userMeta : userMeta // ignore: cast_nullable_to_non_nullable | ||||||
| as Map<String, dynamic>?,sensitiveMarks: null == sensitiveMarks ? _self.sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable | as Map<String, dynamic>?,pool: freezed == pool ? _self.pool : pool // ignore: cast_nullable_to_non_nullable | ||||||
|  | as SnFilePool?,sensitiveMarks: null == sensitiveMarks ? _self.sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable | ||||||
| as List<int>,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable | as List<int>,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable | ||||||
| as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable | as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable | ||||||
| as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable | as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable | ||||||
| @@ -347,7 +348,19 @@ as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ign | |||||||
| as DateTime?, | as DateTime?, | ||||||
|   )); |   )); | ||||||
| } | } | ||||||
|  | /// Create a copy of SnCloudFile | ||||||
|  | /// with the given fields replaced by the non-null parameter values. | ||||||
|  | @override | ||||||
|  | @pragma('vm:prefer-inline') | ||||||
|  | $SnFilePoolCopyWith<$Res>? get pool { | ||||||
|  |     if (_self.pool == null) { | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return $SnFilePoolCopyWith<$Res>(_self.pool!, (value) { | ||||||
|  |     return _then(_self.copyWith(pool: value)); | ||||||
|  |   }); | ||||||
|  | } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -426,10 +439,10 @@ return $default(_that);case _: | |||||||
| /// } | /// } | ||||||
| /// ``` | /// ``` | ||||||
|  |  | ||||||
| @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id,  String name,  String? description,  Map<String, dynamic>? fileMeta,  Map<String, dynamic>? userMeta,  List<int> sensitiveMarks,  String? mimeType,  String? hash,  int size,  DateTime? uploadedAt,  String? uploadedTo,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this; | @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id,  String name,  String? description,  Map<String, dynamic>? fileMeta,  Map<String, dynamic>? userMeta,  SnFilePool? pool,  List<int> sensitiveMarks,  String? mimeType,  String? hash,  int size,  DateTime? uploadedAt,  String? uploadedTo,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this; | ||||||
| switch (_that) { | switch (_that) { | ||||||
| case _SnCloudFile() when $default != null: | case _SnCloudFile() when $default != null: | ||||||
| return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _: | return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.pool,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _: | ||||||
|   return orElse(); |   return orElse(); | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -447,10 +460,10 @@ return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userM | |||||||
| /// } | /// } | ||||||
| /// ``` | /// ``` | ||||||
|  |  | ||||||
| @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id,  String name,  String? description,  Map<String, dynamic>? fileMeta,  Map<String, dynamic>? userMeta,  List<int> sensitiveMarks,  String? mimeType,  String? hash,  int size,  DateTime? uploadedAt,  String? uploadedTo,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this; | @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id,  String name,  String? description,  Map<String, dynamic>? fileMeta,  Map<String, dynamic>? userMeta,  SnFilePool? pool,  List<int> sensitiveMarks,  String? mimeType,  String? hash,  int size,  DateTime? uploadedAt,  String? uploadedTo,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this; | ||||||
| switch (_that) { | switch (_that) { | ||||||
| case _SnCloudFile(): | case _SnCloudFile(): | ||||||
| return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);} | return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.pool,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);} | ||||||
| } | } | ||||||
| /// A variant of `when` that fallback to returning `null` | /// A variant of `when` that fallback to returning `null` | ||||||
| /// | /// | ||||||
| @@ -464,10 +477,10 @@ return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userM | |||||||
| /// } | /// } | ||||||
| /// ``` | /// ``` | ||||||
|  |  | ||||||
| @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id,  String name,  String? description,  Map<String, dynamic>? fileMeta,  Map<String, dynamic>? userMeta,  List<int> sensitiveMarks,  String? mimeType,  String? hash,  int size,  DateTime? uploadedAt,  String? uploadedTo,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this; | @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id,  String name,  String? description,  Map<String, dynamic>? fileMeta,  Map<String, dynamic>? userMeta,  SnFilePool? pool,  List<int> sensitiveMarks,  String? mimeType,  String? hash,  int size,  DateTime? uploadedAt,  String? uploadedTo,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this; | ||||||
| switch (_that) { | switch (_that) { | ||||||
| case _SnCloudFile() when $default != null: | case _SnCloudFile() when $default != null: | ||||||
| return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _: | return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.pool,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _: | ||||||
|   return null; |   return null; | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -479,7 +492,7 @@ return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userM | |||||||
| @JsonSerializable() | @JsonSerializable() | ||||||
|  |  | ||||||
| class _SnCloudFile implements SnCloudFile { | class _SnCloudFile implements SnCloudFile { | ||||||
|   const _SnCloudFile({required this.id, required this.name, required this.description, required final  Map<String, dynamic>? fileMeta, required final  Map<String, dynamic>? userMeta, final  List<int> sensitiveMarks = const [], required this.mimeType, required this.hash, required this.size, required this.uploadedAt, required this.uploadedTo, required this.createdAt, required this.updatedAt, required this.deletedAt}): _fileMeta = fileMeta,_userMeta = userMeta,_sensitiveMarks = sensitiveMarks; |   const _SnCloudFile({required this.id, required this.name, required this.description, required final  Map<String, dynamic>? fileMeta, required final  Map<String, dynamic>? userMeta, required this.pool, final  List<int> sensitiveMarks = const [], required this.mimeType, required this.hash, required this.size, required this.uploadedAt, required this.uploadedTo, required this.createdAt, required this.updatedAt, required this.deletedAt}): _fileMeta = fileMeta,_userMeta = userMeta,_sensitiveMarks = sensitiveMarks; | ||||||
|   factory _SnCloudFile.fromJson(Map<String, dynamic> json) => _$SnCloudFileFromJson(json); |   factory _SnCloudFile.fromJson(Map<String, dynamic> json) => _$SnCloudFileFromJson(json); | ||||||
|  |  | ||||||
| @override final  String id; | @override final  String id; | ||||||
| @@ -503,6 +516,7 @@ class _SnCloudFile implements SnCloudFile { | |||||||
|   return EqualUnmodifiableMapView(value); |   return EqualUnmodifiableMapView(value); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @override final  SnFilePool? pool; | ||||||
|  final  List<int> _sensitiveMarks; |  final  List<int> _sensitiveMarks; | ||||||
| @override@JsonKey() List<int> get sensitiveMarks { | @override@JsonKey() List<int> get sensitiveMarks { | ||||||
|   if (_sensitiveMarks is EqualUnmodifiableListView) return _sensitiveMarks; |   if (_sensitiveMarks is EqualUnmodifiableListView) return _sensitiveMarks; | ||||||
| @@ -532,16 +546,16 @@ Map<String, dynamic> toJson() { | |||||||
|  |  | ||||||
| @override | @override | ||||||
| bool operator ==(Object other) { | bool operator ==(Object other) { | ||||||
|   return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&const DeepCollectionEquality().equals(other._sensitiveMarks, _sensitiveMarks)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); |   return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&(identical(other.pool, pool) || other.pool == pool)&&const DeepCollectionEquality().equals(other._sensitiveMarks, _sensitiveMarks)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @JsonKey(includeFromJson: false, includeToJson: false) | @JsonKey(includeFromJson: false, includeToJson: false) | ||||||
| @override | @override | ||||||
| int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(_fileMeta),const DeepCollectionEquality().hash(_userMeta),const DeepCollectionEquality().hash(_sensitiveMarks),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt); | int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(_fileMeta),const DeepCollectionEquality().hash(_userMeta),pool,const DeepCollectionEquality().hash(_sensitiveMarks),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt); | ||||||
|  |  | ||||||
| @override | @override | ||||||
| String toString() { | String toString() { | ||||||
|   return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; |   return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, pool: $pool, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -552,11 +566,11 @@ abstract mixin class _$SnCloudFileCopyWith<$Res> implements $SnCloudFileCopyWith | |||||||
|   factory _$SnCloudFileCopyWith(_SnCloudFile value, $Res Function(_SnCloudFile) _then) = __$SnCloudFileCopyWithImpl; |   factory _$SnCloudFileCopyWith(_SnCloudFile value, $Res Function(_SnCloudFile) _then) = __$SnCloudFileCopyWithImpl; | ||||||
| @override @useResult | @override @useResult | ||||||
| $Res call({ | $Res call({ | ||||||
|  String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt |  String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, SnFilePool? pool, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @override $SnFilePoolCopyWith<$Res>? get pool; | ||||||
|  |  | ||||||
| } | } | ||||||
| /// @nodoc | /// @nodoc | ||||||
| @@ -569,14 +583,15 @@ class __$SnCloudFileCopyWithImpl<$Res> | |||||||
|  |  | ||||||
| /// Create a copy of SnCloudFile | /// Create a copy of SnCloudFile | ||||||
| /// with the given fields replaced by the non-null parameter values. | /// with the given fields replaced by the non-null parameter values. | ||||||
| @override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? sensitiveMarks = null,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { | @override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? pool = freezed,Object? sensitiveMarks = null,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { | ||||||
|   return _then(_SnCloudFile( |   return _then(_SnCloudFile( | ||||||
| id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable | id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable | ||||||
| as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable | as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable | ||||||
| as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable | as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable | ||||||
| as String?,fileMeta: freezed == fileMeta ? _self._fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable | as String?,fileMeta: freezed == fileMeta ? _self._fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable | ||||||
| as Map<String, dynamic>?,userMeta: freezed == userMeta ? _self._userMeta : userMeta // ignore: cast_nullable_to_non_nullable | as Map<String, dynamic>?,userMeta: freezed == userMeta ? _self._userMeta : userMeta // ignore: cast_nullable_to_non_nullable | ||||||
| as Map<String, dynamic>?,sensitiveMarks: null == sensitiveMarks ? _self._sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable | as Map<String, dynamic>?,pool: freezed == pool ? _self.pool : pool // ignore: cast_nullable_to_non_nullable | ||||||
|  | as SnFilePool?,sensitiveMarks: null == sensitiveMarks ? _self._sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable | ||||||
| as List<int>,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable | as List<int>,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable | ||||||
| as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable | as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable | ||||||
| as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable | as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable | ||||||
| @@ -589,7 +604,19 @@ as DateTime?, | |||||||
|   )); |   )); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Create a copy of SnCloudFile | ||||||
|  | /// with the given fields replaced by the non-null parameter values. | ||||||
|  | @override | ||||||
|  | @pragma('vm:prefer-inline') | ||||||
|  | $SnFilePoolCopyWith<$Res>? get pool { | ||||||
|  |     if (_self.pool == null) { | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return $SnFilePoolCopyWith<$Res>(_self.pool!, (value) { | ||||||
|  |     return _then(_self.copyWith(pool: value)); | ||||||
|  |   }); | ||||||
|  | } | ||||||
| } | } | ||||||
|  |  | ||||||
| // dart format on | // dart format on | ||||||
|   | |||||||
| @@ -33,6 +33,10 @@ _SnCloudFile _$SnCloudFileFromJson(Map<String, dynamic> json) => _SnCloudFile( | |||||||
|   description: json['description'] as String?, |   description: json['description'] as String?, | ||||||
|   fileMeta: json['file_meta'] as Map<String, dynamic>?, |   fileMeta: json['file_meta'] as Map<String, dynamic>?, | ||||||
|   userMeta: json['user_meta'] as Map<String, dynamic>?, |   userMeta: json['user_meta'] as Map<String, dynamic>?, | ||||||
|  |   pool: | ||||||
|  |       json['pool'] == null | ||||||
|  |           ? null | ||||||
|  |           : SnFilePool.fromJson(json['pool'] as Map<String, dynamic>), | ||||||
|   sensitiveMarks: |   sensitiveMarks: | ||||||
|       (json['sensitive_marks'] as List<dynamic>?) |       (json['sensitive_marks'] as List<dynamic>?) | ||||||
|           ?.map((e) => (e as num).toInt()) |           ?.map((e) => (e as num).toInt()) | ||||||
| @@ -61,6 +65,7 @@ Map<String, dynamic> _$SnCloudFileToJson(_SnCloudFile instance) => | |||||||
|       'description': instance.description, |       'description': instance.description, | ||||||
|       'file_meta': instance.fileMeta, |       'file_meta': instance.fileMeta, | ||||||
|       'user_meta': instance.userMeta, |       'user_meta': instance.userMeta, | ||||||
|  |       'pool': instance.pool?.toJson(), | ||||||
|       'sensitive_marks': instance.sensitiveMarks, |       'sensitive_marks': instance.sensitiveMarks, | ||||||
|       'mime_type': instance.mimeType, |       'mime_type': instance.mimeType, | ||||||
|       'hash': instance.hash, |       'hash': instance.hash, | ||||||
|   | |||||||
| @@ -23,31 +23,3 @@ sealed class SnFilePool with _$SnFilePool { | |||||||
|   factory SnFilePool.fromJson(Map<String, dynamic> json) => |   factory SnFilePool.fromJson(Map<String, dynamic> json) => | ||||||
|       _$SnFilePoolFromJson(json); |       _$SnFilePoolFromJson(json); | ||||||
| } | } | ||||||
|  |  | ||||||
| extension SnFilePoolList on List<SnFilePool> { |  | ||||||
|   static List<SnFilePool> listFromResponse(dynamic data) { |  | ||||||
|     if (data is List) { |  | ||||||
|       return data |  | ||||||
|           .whereType<Map<String, dynamic>>() |  | ||||||
|           .map(SnFilePool.fromJson) |  | ||||||
|           .toList(); |  | ||||||
|     } |  | ||||||
|     throw ArgumentError('Unexpected response format: $data'); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   List<SnFilePool> filterValid() { |  | ||||||
|     return where((p) { |  | ||||||
|       final accept = p.policyConfig?['accept_types']; |  | ||||||
|  |  | ||||||
|       if (accept is List) { |  | ||||||
|         final acceptsOnlyMedia = accept.every((t) => |  | ||||||
|             t is String && |  | ||||||
|             (t.startsWith('image/') || |  | ||||||
|                 t.startsWith('video/') || |  | ||||||
|                 t.startsWith('audio/'))); |  | ||||||
|         if (acceptsOnlyMedia) return false; |  | ||||||
|       } |  | ||||||
|       return true; |  | ||||||
|     }).toList(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -6,23 +6,19 @@ import 'package:island/pods/network.dart'; | |||||||
| final poolsProvider = FutureProvider<List<SnFilePool>>((ref) async { | final poolsProvider = FutureProvider<List<SnFilePool>>((ref) async { | ||||||
|   final dio = ref.watch(apiClientProvider); |   final dio = ref.watch(apiClientProvider); | ||||||
|   final response = await dio.get('/drive/pools'); |   final response = await dio.get('/drive/pools'); | ||||||
|   final pools = SnFilePoolList.listFromResponse(response.data); |   return response.data | ||||||
|   return pools.filterValid(); |       .map((e) => SnFilePool.fromJson(e)) | ||||||
|  |       .cast<SnFilePool>() | ||||||
|  |       .toList(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| String resolveDefaultPoolId(WidgetRef ref, List<SnFilePool> pools) { | String? resolveDefaultPoolId(WidgetRef ref, List<SnFilePool> pools) { | ||||||
|   final settings = ref.watch(appSettingsNotifierProvider); |   final settings = ref.watch(appSettingsNotifierProvider); | ||||||
|   final validPools = pools.filterValid(); |  | ||||||
|  |  | ||||||
|   final configuredId = settings.defaultPoolId; |   final configuredId = settings.defaultPoolId; | ||||||
|   if (configuredId != null && validPools.any((p) => p.id == configuredId)) { |   if (configuredId != null && pools.any((p) => p.id == configuredId)) { | ||||||
|     return configuredId; |     return configuredId; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (validPools.isNotEmpty) { |   return pools.firstOrNull?.id; | ||||||
|     return validPools.first.id; | } | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // DEFAULT: Solar Network Driver |  | ||||||
|   return '500e5ed8-bd44-4359-bc0a-ec85e2adf447'; } |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,17 +10,19 @@ Future<void> resetDatabase(WidgetRef ref) async { | |||||||
|   if (kIsWeb) return; |   if (kIsWeb) return; | ||||||
|  |  | ||||||
|   final db = ref.read(databaseProvider); |   final db = ref.read(databaseProvider); | ||||||
|   final basepath = await getApplicationSupportDirectory(); |  | ||||||
|   final file = File(join(basepath.path, 'solar_network_data.sqlite')); |  | ||||||
|  |  | ||||||
|   // Close current database connection |   // Close current database connection | ||||||
|   db.close(); |   await db.close(); | ||||||
|  |  | ||||||
|   // Delete database file |   // Get the correct database file path | ||||||
|  |   final dbFolder = await getApplicationDocumentsDirectory(); | ||||||
|  |   final file = File(join(dbFolder.path, 'solar_network_data.sqlite')); | ||||||
|  |  | ||||||
|  |   // Delete database file if it exists | ||||||
|   if (await file.exists()) { |   if (await file.exists()) { | ||||||
|     await file.delete(); |     await file.delete(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Force refresh the database provider |   // Force refresh the database provider to create a new instance | ||||||
|   ref.invalidate(databaseProvider); |   ref.invalidate(databaseProvider); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -148,7 +148,6 @@ class LevelingScreen extends HookConsumerWidget { | |||||||
|     return Center( |     return Center( | ||||||
|       child: Container( |       child: Container( | ||||||
|         padding: const EdgeInsets.symmetric(horizontal: 20), |         padding: const EdgeInsets.symmetric(horizontal: 20), | ||||||
|         constraints: const BoxConstraints(maxWidth: 480), |  | ||||||
|         child: CustomScrollView( |         child: CustomScrollView( | ||||||
|           slivers: [ |           slivers: [ | ||||||
|             const SliverGap(20), |             const SliverGap(20), | ||||||
| @@ -180,6 +179,12 @@ class LevelingScreen extends HookConsumerWidget { | |||||||
|                 child: Column( |                 child: Column( | ||||||
|                   crossAxisAlignment: CrossAxisAlignment.stretch, |                   crossAxisAlignment: CrossAxisAlignment.stretch, | ||||||
|                   children: [ |                   children: [ | ||||||
|  |                     Text( | ||||||
|  |                       '${'levelingProgressLevel'.tr(args: [currentLevel.toString()])} / 120', | ||||||
|  |                       textAlign: TextAlign.start, | ||||||
|  |                       style: Theme.of(context).textTheme.bodySmall, | ||||||
|  |                     ), | ||||||
|  |                     const Gap(8), | ||||||
|                     LinearProgressIndicator( |                     LinearProgressIndicator( | ||||||
|                       value: currentLevel / 120, |                       value: currentLevel / 120, | ||||||
|                       minHeight: 10, |                       minHeight: 10, | ||||||
| @@ -190,12 +195,6 @@ class LevelingScreen extends HookConsumerWidget { | |||||||
|                           Theme.of(context).colorScheme.surfaceContainerHigh, |                           Theme.of(context).colorScheme.surfaceContainerHigh, | ||||||
|                       borderRadius: BorderRadius.circular(32), |                       borderRadius: BorderRadius.circular(32), | ||||||
|                     ), |                     ), | ||||||
|                     const Gap(8), |  | ||||||
|                     Text( |  | ||||||
|                       '${'levelingProgressLevel'.tr(args: [currentLevel.toString()])} / 120', |  | ||||||
|                       textAlign: TextAlign.right, |  | ||||||
|                       style: Theme.of(context).textTheme.bodySmall, |  | ||||||
|                     ), |  | ||||||
|                   ], |                   ], | ||||||
|                 ).padding(horizontal: 16, top: 16, bottom: 12), |                 ).padding(horizontal: 16, top: 16, bottom: 12), | ||||||
|               ), |               ), | ||||||
| @@ -272,9 +271,6 @@ class LevelingScreen extends HookConsumerWidget { | |||||||
|  |  | ||||||
|     return SingleChildScrollView( |     return SingleChildScrollView( | ||||||
|       padding: getTabbedPadding(context, horizontal: 20, vertical: 20), |       padding: getTabbedPadding(context, horizontal: 20, vertical: 20), | ||||||
|       child: Center( |  | ||||||
|         child: ConstrainedBox( |  | ||||||
|           constraints: const BoxConstraints(maxWidth: 480), |  | ||||||
|       child: Column( |       child: Column( | ||||||
|         crossAxisAlignment: CrossAxisAlignment.stretch, |         crossAxisAlignment: CrossAxisAlignment.stretch, | ||||||
|         children: [ |         children: [ | ||||||
| @@ -282,8 +278,6 @@ class LevelingScreen extends HookConsumerWidget { | |||||||
|           const Gap(16), |           const Gap(16), | ||||||
|         ], |         ], | ||||||
|       ), |       ), | ||||||
|         ), |  | ||||||
|       ), |  | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -935,7 +935,7 @@ class _ChatAttachmentUploaderSheetState | |||||||
|           if (snapshot.hasError) { |           if (snapshot.hasError) { | ||||||
|             return Center(child: Text('errorLoadingPools'.tr())); |             return Center(child: Text('errorLoadingPools'.tr())); | ||||||
|           } |           } | ||||||
|           final pools = snapshot.data!.filterValid(); |           final pools = snapshot.data!; | ||||||
|           selectedPoolId ??= resolveDefaultPoolId(widget.ref, pools); |           selectedPoolId ??= resolveDefaultPoolId(widget.ref, pools); | ||||||
|  |  | ||||||
|           return Column( |           return Column( | ||||||
| @@ -1162,9 +1162,7 @@ class _ChatAttachmentUploaderSheetState | |||||||
|  |  | ||||||
|     // Get the selected pool to check constraints |     // Get the selected pool to check constraints | ||||||
|     final pools = await widget.ref.read(poolsProvider.future); |     final pools = await widget.ref.read(poolsProvider.future); | ||||||
|     final selectedPool = pools.filterValid().firstWhere( |     final selectedPool = pools.firstWhere((p) => p.id == selectedPoolId); | ||||||
|       (p) => p.id == selectedPoolId, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     // Check constraints |     // Check constraints | ||||||
|     final maxFileSize = selectedPool.policyConfig?['max_file_size'] as int?; |     final maxFileSize = selectedPool.policyConfig?['max_file_size'] as int?; | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ part of 'file_list.dart'; | |||||||
| // RiverpodGenerator | // RiverpodGenerator | ||||||
| // ************************************************************************** | // ************************************************************************** | ||||||
|  |  | ||||||
| String _$billingUsageHash() => r'270ec8499378ee0c038aa44ad1c2e3ad9025740a'; | String _$billingUsageHash() => r'58d8bc774868d60781574c85d6b25869a79c57aa'; | ||||||
|  |  | ||||||
| /// See also [billingUsage]. | /// See also [billingUsage]. | ||||||
| @ProviderFor(billingUsage) | @ProviderFor(billingUsage) | ||||||
| @@ -25,7 +25,7 @@ final billingUsageProvider = | |||||||
| @Deprecated('Will be removed in 3.0. Use Ref instead') | @Deprecated('Will be removed in 3.0. Use Ref instead') | ||||||
| // ignore: unused_element | // ignore: unused_element | ||||||
| typedef BillingUsageRef = AutoDisposeFutureProviderRef<Map<String, dynamic>?>; | typedef BillingUsageRef = AutoDisposeFutureProviderRef<Map<String, dynamic>?>; | ||||||
| String _$billingQuotaHash() => r'0696b500fa8bb1270641bcacf262be58caff9b38'; | String _$billingQuotaHash() => r'4ec5d728e439015800abb2d0d673b5a7329cc654'; | ||||||
|  |  | ||||||
| /// See also [billingQuota]. | /// See also [billingQuota]. | ||||||
| @ProviderFor(billingQuota) | @ProviderFor(billingQuota) | ||||||
| @@ -45,7 +45,7 @@ final billingQuotaProvider = | |||||||
| // ignore: unused_element | // ignore: unused_element | ||||||
| typedef BillingQuotaRef = AutoDisposeFutureProviderRef<Map<String, dynamic>?>; | typedef BillingQuotaRef = AutoDisposeFutureProviderRef<Map<String, dynamic>?>; | ||||||
| String _$cloudFileListNotifierHash() => | String _$cloudFileListNotifierHash() => | ||||||
|     r'e2c8a076a9e635c7b43a87d00f78775427ba6334'; |     r'22c45a8ea23147a3835ba870ad2f0bb833f853ea'; | ||||||
|  |  | ||||||
| /// See also [CloudFileListNotifier]. | /// See also [CloudFileListNotifier]. | ||||||
| @ProviderFor(CloudFileListNotifier) | @ProviderFor(CloudFileListNotifier) | ||||||
|   | |||||||
| @@ -22,7 +22,6 @@ import 'package:path_provider/path_provider.dart'; | |||||||
| import 'package:styled_widget/styled_widget.dart'; | import 'package:styled_widget/styled_widget.dart'; | ||||||
| import 'package:island/pods/config.dart'; | import 'package:island/pods/config.dart'; | ||||||
| import 'package:island/pods/file_pool.dart'; | import 'package:island/pods/file_pool.dart'; | ||||||
| import 'package:island/models/file_pool.dart'; |  | ||||||
|  |  | ||||||
| class SettingsScreen extends HookConsumerWidget { | class SettingsScreen extends HookConsumerWidget { | ||||||
|   const SettingsScreen({super.key}); |   const SettingsScreen({super.key}); | ||||||
| @@ -417,7 +416,7 @@ class SettingsScreen extends HookConsumerWidget { | |||||||
|       if (user.value != null) |       if (user.value != null) | ||||||
|         pools.when( |         pools.when( | ||||||
|           data: (data) { |           data: (data) { | ||||||
|             final validPools = data.filterValid(); |             final validPools = data; | ||||||
|             final currentPoolId = resolveDefaultPoolId(ref, data); |             final currentPoolId = resolveDefaultPoolId(ref, data); | ||||||
|  |  | ||||||
|             return ListTile( |             return ListTile( | ||||||
| @@ -437,11 +436,14 @@ class SettingsScreen extends HookConsumerWidget { | |||||||
|                       validPools.map((p) { |                       validPools.map((p) { | ||||||
|                         return DropdownMenuItem<String>( |                         return DropdownMenuItem<String>( | ||||||
|                           value: p.id, |                           value: p.id, | ||||||
|  |                           child: Tooltip( | ||||||
|  |                             message: p.name, | ||||||
|                             child: Text( |                             child: Text( | ||||||
|                               p.name, |                               p.name, | ||||||
|                               maxLines: 1, |                               maxLines: 1, | ||||||
|                               overflow: TextOverflow.ellipsis, |                               overflow: TextOverflow.ellipsis, | ||||||
|                             ).fontSize(14), |                             ).fontSize(14), | ||||||
|  |                           ), | ||||||
|                         ); |                         ); | ||||||
|                       }).toList(), |                       }).toList(), | ||||||
|                   value: currentPoolId, |                   value: currentPoolId, | ||||||
|   | |||||||
| @@ -147,6 +147,7 @@ class AccountProfileCard extends HookConsumerWidget { | |||||||
|                       if (data.badges.isNotEmpty) |                       if (data.badges.isNotEmpty) | ||||||
|                         BadgeList(badges: data.badges).padding(top: 12), |                         BadgeList(badges: data.badges).padding(top: 12), | ||||||
|                       LevelingProgressCard( |                       LevelingProgressCard( | ||||||
|  |                         isCompact: true, | ||||||
|                         level: data.profile.level, |                         level: data.profile.level, | ||||||
|                         experience: data.profile.experience, |                         experience: data.profile.experience, | ||||||
|                         progress: data.profile.levelingProgress, |                         progress: data.profile.levelingProgress, | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ class _AttachmentUploaderSheetState extends State<AttachmentUploaderSheet> { | |||||||
|           if (snapshot.hasError) { |           if (snapshot.hasError) { | ||||||
|             return Center(child: Text('errorLoadingPools'.tr())); |             return Center(child: Text('errorLoadingPools'.tr())); | ||||||
|           } |           } | ||||||
|           final pools = snapshot.data!.filterValid(); |           final pools = snapshot.data!; | ||||||
|           selectedPoolId ??= resolveDefaultPoolId(widget.ref, pools); |           selectedPoolId ??= resolveDefaultPoolId(widget.ref, pools); | ||||||
|  |  | ||||||
|           return Column( |           return Column( | ||||||
| @@ -286,9 +286,7 @@ class _AttachmentUploaderSheetState extends State<AttachmentUploaderSheet> { | |||||||
|  |  | ||||||
|     // Get the selected pool to check constraints |     // Get the selected pool to check constraints | ||||||
|     final pools = await widget.ref.read(poolsProvider.future); |     final pools = await widget.ref.read(poolsProvider.future); | ||||||
|     final selectedPool = pools.filterValid().firstWhere( |     final selectedPool = pools.firstWhere((p) => p.id == selectedPoolId); | ||||||
|       (p) => p.id == selectedPoolId, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     // Check constraints |     // Check constraints | ||||||
|     final maxFileSize = selectedPool.policyConfig?['max_file_size'] as int?; |     final maxFileSize = selectedPool.policyConfig?['max_file_size'] as int?; | ||||||
|   | |||||||
| @@ -130,7 +130,7 @@ class MessageItem extends HookConsumerWidget { | |||||||
|  |  | ||||||
|     useEffect(() { |     useEffect(() { | ||||||
|       if (flashing) { |       if (flashing) { | ||||||
|         if (flashTimer.value != null) return null; |         flashTimer.value?.cancel(); | ||||||
|         isFlashing.value = true; |         isFlashing.value = true; | ||||||
|         flashTimer.value = Timer.periodic( |         flashTimer.value = Timer.periodic( | ||||||
|           const Duration(milliseconds: kFlashDuration), |           const Duration(milliseconds: kFlashDuration), | ||||||
| @@ -343,6 +343,10 @@ class MessageItemDisplayBubble extends HookConsumerWidget { | |||||||
|         isCurrentUser |         isCurrentUser | ||||||
|             ? Theme.of(context).colorScheme.onPrimaryContainer |             ? Theme.of(context).colorScheme.onPrimaryContainer | ||||||
|             : Theme.of(context).colorScheme.onSurfaceVariant; |             : Theme.of(context).colorScheme.onSurfaceVariant; | ||||||
|  |     final containerColor = | ||||||
|  |         isCurrentUser | ||||||
|  |             ? Theme.of(context).colorScheme.primaryContainer.withOpacity(0.5) | ||||||
|  |             : Theme.of(context).colorScheme.surfaceContainer; | ||||||
|  |  | ||||||
|     final hasBackground = |     final hasBackground = | ||||||
|         ref.watch(backgroundImageFileProvider).valueOrNull != null; |         ref.watch(backgroundImageFileProvider).valueOrNull != null; | ||||||
| @@ -377,6 +381,15 @@ class MessageItemDisplayBubble extends HookConsumerWidget { | |||||||
|               crossAxisAlignment: CrossAxisAlignment.end, |               crossAxisAlignment: CrossAxisAlignment.end, | ||||||
|               children: [ |               children: [ | ||||||
|                 Flexible( |                 Flexible( | ||||||
|  |                   child: Container( | ||||||
|  |                     decoration: BoxDecoration( | ||||||
|  |                       color: containerColor, | ||||||
|  |                       borderRadius: BorderRadius.circular(16), | ||||||
|  |                     ), | ||||||
|  |                     padding: const EdgeInsets.symmetric( | ||||||
|  |                       horizontal: 12, | ||||||
|  |                       vertical: 6, | ||||||
|  |                     ), | ||||||
|                     child: Column( |                     child: Column( | ||||||
|                       crossAxisAlignment: CrossAxisAlignment.start, |                       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|                       children: [ |                       children: [ | ||||||
| @@ -471,6 +484,7 @@ class MessageItemDisplayBubble extends HookConsumerWidget { | |||||||
|                       ], |                       ], | ||||||
|                     ), |                     ), | ||||||
|                   ), |                   ), | ||||||
|  |                 ), | ||||||
|                 MessageIndicators( |                 MessageIndicators( | ||||||
|                   editedAt: remoteMessage.editedAt, |                   editedAt: remoteMessage.editedAt, | ||||||
|                   status: message.status, |                   status: message.status, | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|     final exifData = item.fileMeta?['exif'] as Map<String, dynamic>? ?? {}; |     final exifData = item.fileMeta?['exif'] as Map<String, dynamic>? ?? {}; | ||||||
|  |  | ||||||
|     return SheetScaffold( |     return SheetScaffold( | ||||||
|       titleText: 'File Information', |       titleText: 'fileInfoTitle'.tr(), | ||||||
|       child: SingleChildScrollView( |       child: SingleChildScrollView( | ||||||
|         child: Column( |         child: Column( | ||||||
|           crossAxisAlignment: CrossAxisAlignment.start, |           crossAxisAlignment: CrossAxisAlignment.start, | ||||||
| @@ -81,7 +81,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                       ), |                       ), | ||||||
|                       onLongPress: () { |                       onLongPress: () { | ||||||
|                         Clipboard.setData(ClipboardData(text: item.hash!)); |                         Clipboard.setData(ClipboardData(text: item.hash!)); | ||||||
|                         showSnackBar('File hash copied to clipboard'); |                         showSnackBar('fileHashCopied'.tr()); | ||||||
|                       }, |                       }, | ||||||
|                     ), |                     ), | ||||||
|                   ), |                   ), | ||||||
| @@ -101,7 +101,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                 icon: const Icon(Icons.copy), |                 icon: const Icon(Icons.copy), | ||||||
|                 onPressed: () { |                 onPressed: () { | ||||||
|                   Clipboard.setData(ClipboardData(text: item.id)); |                   Clipboard.setData(ClipboardData(text: item.id)); | ||||||
|                   showSnackBar('File ID copied to clipboard'); |                   showSnackBar('fileIdCopied'.tr()); | ||||||
|                 }, |                 }, | ||||||
|               ), |               ), | ||||||
|             ), |             ), | ||||||
| @@ -118,7 +118,25 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                 icon: const Icon(Icons.copy), |                 icon: const Icon(Icons.copy), | ||||||
|                 onPressed: () { |                 onPressed: () { | ||||||
|                   Clipboard.setData(ClipboardData(text: item.name)); |                   Clipboard.setData(ClipboardData(text: item.name)); | ||||||
|                   showSnackBar('File name copied to clipboard'); |                   showSnackBar('fileNameCopied'.tr()); | ||||||
|  |                 }, | ||||||
|  |               ), | ||||||
|  |             ), | ||||||
|  |             if (item.pool != null) | ||||||
|  |               ListTile( | ||||||
|  |                 leading: const Icon(Symbols.calendar_today), | ||||||
|  |                 title: Text('File Pool').tr(), | ||||||
|  |                 subtitle: Text( | ||||||
|  |                   item.pool!.name, | ||||||
|  |                   maxLines: 1, | ||||||
|  |                   overflow: TextOverflow.ellipsis, | ||||||
|  |                 ), | ||||||
|  |                 contentPadding: EdgeInsets.symmetric(horizontal: 24), | ||||||
|  |                 trailing: IconButton( | ||||||
|  |                   icon: const Icon(Icons.copy), | ||||||
|  |                   onPressed: () { | ||||||
|  |                     Clipboard.setData(ClipboardData(text: item.pool!.id)); | ||||||
|  |                     showSnackBar('fileNameCopied'.tr()); | ||||||
|                   }, |                   }, | ||||||
|                 ), |                 ), | ||||||
|               ), |               ), | ||||||
| @@ -163,7 +181,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                               Clipboard.setData( |                               Clipboard.setData( | ||||||
|                                 ClipboardData(text: '${entry.value}'), |                                 ClipboardData(text: '${entry.value}'), | ||||||
|                               ); |                               ); | ||||||
|                               showSnackBar('Value copied to clipboard'); |                               showSnackBar('valueCopied'.tr()); | ||||||
|                             }, |                             }, | ||||||
|                           ), |                           ), | ||||||
|                         ), |                         ), | ||||||
| @@ -180,7 +198,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                 child: ExpansionTile( |                 child: ExpansionTile( | ||||||
|                   tilePadding: const EdgeInsets.symmetric(horizontal: 24), |                   tilePadding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|                   title: Text( |                   title: Text( | ||||||
|                     'File Metadata', |                     'fileMetadata'.tr(), | ||||||
|                     style: theme.textTheme.titleMedium?.copyWith( |                     style: theme.textTheme.titleMedium?.copyWith( | ||||||
|                       fontWeight: FontWeight.bold, |                       fontWeight: FontWeight.bold, | ||||||
|                     ), |                     ), | ||||||
| @@ -212,7 +230,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                               Clipboard.setData( |                               Clipboard.setData( | ||||||
|                                 ClipboardData(text: jsonEncode(entry.value)), |                                 ClipboardData(text: jsonEncode(entry.value)), | ||||||
|                               ); |                               ); | ||||||
|                               showSnackBar('Value copied to clipboard'); |                               showSnackBar('valueCopied'.tr()); | ||||||
|                             }, |                             }, | ||||||
|                           ), |                           ), | ||||||
|                         ), |                         ), | ||||||
| @@ -229,7 +247,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                 child: ExpansionTile( |                 child: ExpansionTile( | ||||||
|                   tilePadding: const EdgeInsets.symmetric(horizontal: 24), |                   tilePadding: const EdgeInsets.symmetric(horizontal: 24), | ||||||
|                   title: Text( |                   title: Text( | ||||||
|                     'User Metadata', |                     'userMetadata'.tr(), | ||||||
|                     style: theme.textTheme.titleMedium?.copyWith( |                     style: theme.textTheme.titleMedium?.copyWith( | ||||||
|                       fontWeight: FontWeight.bold, |                       fontWeight: FontWeight.bold, | ||||||
|                     ), |                     ), | ||||||
| @@ -261,7 +279,7 @@ class FileInfoSheet extends StatelessWidget { | |||||||
|                               Clipboard.setData( |                               Clipboard.setData( | ||||||
|                                 ClipboardData(text: jsonEncode(entry.value)), |                                 ClipboardData(text: jsonEncode(entry.value)), | ||||||
|                               ); |                               ); | ||||||
|                               showSnackBar('Value copied to clipboard'); |                               showSnackBar('valueCopied'.tr()); | ||||||
|                             }, |                             }, | ||||||
|                           ), |                           ), | ||||||
|                         ), |                         ), | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| ; ================================================== | ; ================================================== | ||||||
| #define AppVersion "3.2.0" | #define AppVersion "3.2.0" | ||||||
| #define BuildNumber "132" | #define BuildNumber "134" | ||||||
| ; ================================================== | ; ================================================== | ||||||
|  |  | ||||||
| #define FullVersion AppVersion + "." + BuildNumber | #define FullVersion AppVersion + "." + BuildNumber | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user