🐛 Fix bugs

This commit is contained in:
2025-09-24 20:52:56 +08:00
parent 5f84751fd5
commit bf4892b34d
8 changed files with 146 additions and 129 deletions

View File

@@ -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
}
}
} }
}, },
); );

View File

@@ -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');
}
}

View File

@@ -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);
} }

View File

@@ -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)

View File

@@ -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,

View File

@@ -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,

View File

@@ -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(

View File

@@ -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" ;