Compare commits
	
		
			2 Commits
		
	
	
		
			5f84751fd5
			...
			b4996d069f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b4996d069f | |||
| bf4892b34d | 
| @@ -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 | ||||||
|  |           } | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|   ); |   ); | ||||||
|   | |||||||
| @@ -23,15 +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'); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -6,7 +6,10 @@ 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'); | ||||||
|   return response.data.map((e) => SnFilePool.fromJson(e)).toList(); |   return response.data | ||||||
|  |       .map((e) => SnFilePool.fromJson(e)) | ||||||
|  |       .cast<SnFilePool>() | ||||||
|  |       .toList(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| String? resolveDefaultPoolId(WidgetRef ref, List<SnFilePool> pools) { | String? resolveDefaultPoolId(WidgetRef ref, List<SnFilePool> pools) { | ||||||
|   | |||||||
| @@ -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); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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: Text( |                           child: Tooltip( | ||||||
|                             p.name, |                             message: p.name, | ||||||
|                             maxLines: 1, |                             child: Text( | ||||||
|                             overflow: TextOverflow.ellipsis, |                               p.name, | ||||||
|                           ).fontSize(14), |                               maxLines: 1, | ||||||
|  |                               overflow: TextOverflow.ellipsis, | ||||||
|  |                             ).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, | ||||||
|   | |||||||
| @@ -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,98 +381,108 @@ class MessageItemDisplayBubble extends HookConsumerWidget { | |||||||
|               crossAxisAlignment: CrossAxisAlignment.end, |               crossAxisAlignment: CrossAxisAlignment.end, | ||||||
|               children: [ |               children: [ | ||||||
|                 Flexible( |                 Flexible( | ||||||
|                   child: Column( |                   child: Container( | ||||||
|                     crossAxisAlignment: CrossAxisAlignment.start, |                     decoration: BoxDecoration( | ||||||
|                     children: [ |                       color: containerColor, | ||||||
|                       if (remoteMessage.repliedMessageId != null) |                       borderRadius: BorderRadius.circular(16), | ||||||
|                         MessageQuoteWidget( |                     ), | ||||||
|                           message: message, |                     padding: const EdgeInsets.symmetric( | ||||||
|                           textColor: textColor, |                       horizontal: 12, | ||||||
|                           isReply: true, |                       vertical: 6, | ||||||
|                         ).padding(vertical: 4), |                     ), | ||||||
|                       if (remoteMessage.forwardedMessageId != null) |                     child: Column( | ||||||
|                         MessageQuoteWidget( |                       crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|                           message: message, |                       children: [ | ||||||
|                           textColor: textColor, |                         if (remoteMessage.repliedMessageId != null) | ||||||
|                           isReply: false, |                           MessageQuoteWidget( | ||||||
|                         ).padding(vertical: 4), |                             message: message, | ||||||
|                       if (MessageContent.hasContent(remoteMessage)) |                             textColor: textColor, | ||||||
|                         MessageContent( |                             isReply: true, | ||||||
|                           item: remoteMessage, |                           ).padding(vertical: 4), | ||||||
|                           translatedText: translatedText, |                         if (remoteMessage.forwardedMessageId != null) | ||||||
|                         ), |                           MessageQuoteWidget( | ||||||
|                       if (remoteMessage.attachments.isNotEmpty) |                             message: message, | ||||||
|                         LayoutBuilder( |                             textColor: textColor, | ||||||
|                           builder: (context, constraints) { |                             isReply: false, | ||||||
|                             return CloudFileList( |                           ).padding(vertical: 4), | ||||||
|                               files: remoteMessage.attachments, |                         if (MessageContent.hasContent(remoteMessage)) | ||||||
|                               maxWidth: constraints.maxWidth, |                           MessageContent( | ||||||
|                               padding: EdgeInsets.symmetric(vertical: 4), |                             item: remoteMessage, | ||||||
|                             ); |                             translatedText: translatedText, | ||||||
|                           }, |                           ), | ||||||
|                         ), |                         if (remoteMessage.attachments.isNotEmpty) | ||||||
|                       if (remoteMessage.meta['embeds'] != null) |                           LayoutBuilder( | ||||||
|                         ...((remoteMessage.meta['embeds'] as List<dynamic>) |                             builder: (context, constraints) { | ||||||
|                             .map((embed) => convertMapKeysToSnakeCase(embed)) |                               return CloudFileList( | ||||||
|                             .where((embed) => embed['type'] == 'link') |                                 files: remoteMessage.attachments, | ||||||
|                             .map((embed) => SnScrappedLink.fromJson(embed)) |                                 maxWidth: constraints.maxWidth, | ||||||
|                             .map( |                                 padding: EdgeInsets.symmetric(vertical: 4), | ||||||
|                               (link) => LayoutBuilder( |                               ); | ||||||
|                                 builder: (context, constraints) { |                             }, | ||||||
|                                   return EmbedLinkWidget( |                           ), | ||||||
|                                     link: link, |                         if (remoteMessage.meta['embeds'] != null) | ||||||
|                                     maxWidth: math.min( |                           ...((remoteMessage.meta['embeds'] as List<dynamic>) | ||||||
|                                       constraints.maxWidth, |                               .map((embed) => convertMapKeysToSnakeCase(embed)) | ||||||
|                                       480, |                               .where((embed) => embed['type'] == 'link') | ||||||
|  |                               .map((embed) => SnScrappedLink.fromJson(embed)) | ||||||
|  |                               .map( | ||||||
|  |                                 (link) => LayoutBuilder( | ||||||
|  |                                   builder: (context, constraints) { | ||||||
|  |                                     return EmbedLinkWidget( | ||||||
|  |                                       link: link, | ||||||
|  |                                       maxWidth: math.min( | ||||||
|  |                                         constraints.maxWidth, | ||||||
|  |                                         480, | ||||||
|  |                                       ), | ||||||
|  |                                       margin: const EdgeInsets.symmetric( | ||||||
|  |                                         vertical: 4, | ||||||
|  |                                       ), | ||||||
|  |                                     ); | ||||||
|  |                                   }, | ||||||
|  |                                 ), | ||||||
|  |                               ) | ||||||
|  |                               .toList()), | ||||||
|  |                         if (progress != null && progress!.isNotEmpty) | ||||||
|  |                           Column( | ||||||
|  |                             crossAxisAlignment: CrossAxisAlignment.stretch, | ||||||
|  |                             spacing: 8, | ||||||
|  |                             children: [ | ||||||
|  |                               if ((remoteMessage.content?.isNotEmpty ?? false)) | ||||||
|  |                                 const Gap(0), | ||||||
|  |                               for (var entry in progress!.entries) | ||||||
|  |                                 Column( | ||||||
|  |                                   crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                                   children: [ | ||||||
|  |                                     Text( | ||||||
|  |                                       'fileUploadingProgress'.tr( | ||||||
|  |                                         args: [ | ||||||
|  |                                           (entry.key + 1).toString(), | ||||||
|  |                                           entry.value.toStringAsFixed(1), | ||||||
|  |                                         ], | ||||||
|  |                                       ), | ||||||
|  |                                       style: TextStyle( | ||||||
|  |                                         fontSize: 12, | ||||||
|  |                                         color: textColor.withOpacity(0.8), | ||||||
|  |                                       ), | ||||||
|                                     ), |                                     ), | ||||||
|                                     margin: const EdgeInsets.symmetric( |                                     const Gap(4), | ||||||
|                                       vertical: 4, |                                     LinearProgressIndicator( | ||||||
|  |                                       value: entry.value / 100, | ||||||
|  |                                       backgroundColor: | ||||||
|  |                                           Theme.of( | ||||||
|  |                                             context, | ||||||
|  |                                           ).colorScheme.surfaceVariant, | ||||||
|  |                                       valueColor: AlwaysStoppedAnimation<Color>( | ||||||
|  |                                         Theme.of(context).colorScheme.primary, | ||||||
|  |                                       ), | ||||||
|                                     ), |                                     ), | ||||||
|                                   ); |                                   ], | ||||||
|                                 }, |                                 ), | ||||||
|                               ), |  | ||||||
|                             ) |  | ||||||
|                             .toList()), |  | ||||||
|                       if (progress != null && progress!.isNotEmpty) |  | ||||||
|                         Column( |  | ||||||
|                           crossAxisAlignment: CrossAxisAlignment.stretch, |  | ||||||
|                           spacing: 8, |  | ||||||
|                           children: [ |  | ||||||
|                             if ((remoteMessage.content?.isNotEmpty ?? false)) |  | ||||||
|                               const Gap(0), |                               const Gap(0), | ||||||
|                             for (var entry in progress!.entries) |                             ], | ||||||
|                               Column( |                           ), | ||||||
|                                 crossAxisAlignment: CrossAxisAlignment.start, |                       ], | ||||||
|                                 children: [ |                     ), | ||||||
|                                   Text( |  | ||||||
|                                     'fileUploadingProgress'.tr( |  | ||||||
|                                       args: [ |  | ||||||
|                                         (entry.key + 1).toString(), |  | ||||||
|                                         entry.value.toStringAsFixed(1), |  | ||||||
|                                       ], |  | ||||||
|                                     ), |  | ||||||
|                                     style: TextStyle( |  | ||||||
|                                       fontSize: 12, |  | ||||||
|                                       color: textColor.withOpacity(0.8), |  | ||||||
|                                     ), |  | ||||||
|                                   ), |  | ||||||
|                                   const Gap(4), |  | ||||||
|                                   LinearProgressIndicator( |  | ||||||
|                                     value: entry.value / 100, |  | ||||||
|                                     backgroundColor: |  | ||||||
|                                         Theme.of( |  | ||||||
|                                           context, |  | ||||||
|                                         ).colorScheme.surfaceVariant, |  | ||||||
|                                     valueColor: AlwaysStoppedAnimation<Color>( |  | ||||||
|                                       Theme.of(context).colorScheme.primary, |  | ||||||
|                                     ), |  | ||||||
|                                   ), |  | ||||||
|                                 ], |  | ||||||
|                               ), |  | ||||||
|                             const Gap(0), |  | ||||||
|                           ], |  | ||||||
|                         ), |  | ||||||
|                     ], |  | ||||||
|                   ), |                   ), | ||||||
|                 ), |                 ), | ||||||
|                 MessageIndicators( |                 MessageIndicators( | ||||||
|   | |||||||
| @@ -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 | ||||||
| @@ -49,4 +49,4 @@ Filename: "{app}\Solian.exe"; Description: "Launch Solian"; Flags: nowait postin | |||||||
| [UninstallDelete] | [UninstallDelete] | ||||||
| Type: filesandordirs; Name: "{userappdata}\dev.solsynth\Solian" | Type: filesandordirs; Name: "{userappdata}\dev.solsynth\Solian" | ||||||
| Type: files; Name: "{group}\Solian.lnk" ; | Type: files; Name: "{group}\Solian.lnk" ; | ||||||
| Type: files; Name: "{autodesktop}\Solian.lnk" ; | Type: files; Name: "{autodesktop}\Solian.lnk" ; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user