Compare commits

...

3 Commits

Author SHA1 Message Date
b4996d069f 🐛 Fix bugs 2025-09-24 21:03:53 +08:00
bf4892b34d 🐛 Fix bugs 2025-09-24 20:52:56 +08:00
5f84751fd5 🐛 Fix file upload 2025-09-24 20:29:30 +08:00
11 changed files with 159 additions and 166 deletions

View File

@@ -33,17 +33,27 @@ class AppDatabase extends _$AppDatabase {
await _migrateToVersion6(m);
}
if (from < 7) {
// Add new columns from SnChatMessage
await m.addColumn(chatMessages, chatMessages.updatedAt);
await m.addColumn(chatMessages, chatMessages.deletedAt);
await m.addColumn(chatMessages, chatMessages.type);
await m.addColumn(chatMessages, chatMessages.meta);
await m.addColumn(chatMessages, chatMessages.membersMentioned);
await m.addColumn(chatMessages, chatMessages.editedAt);
await m.addColumn(chatMessages, chatMessages.attachments);
await m.addColumn(chatMessages, chatMessages.reactions);
await m.addColumn(chatMessages, chatMessages.repliedMessageId);
await m.addColumn(chatMessages, chatMessages.forwardedMessageId);
// Add new columns from SnChatMessage, ignore if they already exist
final columnsToAdd = [
chatMessages.updatedAt,
chatMessages.deletedAt,
chatMessages.type,
chatMessages.meta,
chatMessages.membersMentioned,
chatMessages.editedAt,
chatMessages.attachments,
chatMessages.reactions,
chatMessages.repliedMessageId,
chatMessages.forwardedMessageId,
];
for (final column in columnsToAdd) {
try {
await m.addColumn(chatMessages, column);
} catch (e) {
// Column already exists, skip
}
}
}
},
);

View File

@@ -23,31 +23,3 @@ sealed class SnFilePool with _$SnFilePool {
factory SnFilePool.fromJson(Map<String, dynamic> 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();
}
}

View File

@@ -6,23 +6,19 @@ import 'package:island/pods/network.dart';
final poolsProvider = FutureProvider<List<SnFilePool>>((ref) async {
final dio = ref.watch(apiClientProvider);
final response = await dio.get('/drive/pools');
final pools = SnFilePoolList.listFromResponse(response.data);
return pools.filterValid();
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) {
final settings = ref.watch(appSettingsNotifierProvider);
final validPools = pools.filterValid();
final configuredId = settings.defaultPoolId;
if (configuredId != null && validPools.any((p) => p.id == configuredId)) {
if (configuredId != null && pools.any((p) => p.id == configuredId)) {
return configuredId;
}
if (validPools.isNotEmpty) {
return validPools.first.id;
return pools.firstOrNull?.id;
}
// DEFAULT: Solar Network Driver
return '500e5ed8-bd44-4359-bc0a-ec85e2adf447'; }

View File

@@ -10,17 +10,19 @@ Future<void> resetDatabase(WidgetRef ref) async {
if (kIsWeb) return;
final db = ref.read(databaseProvider);
final basepath = await getApplicationSupportDirectory();
final file = File(join(basepath.path, 'solar_network_data.sqlite'));
// 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()) {
await file.delete();
}
// Force refresh the database provider
// Force refresh the database provider to create a new instance
ref.invalidate(databaseProvider);
}

View File

@@ -935,7 +935,7 @@ class _ChatAttachmentUploaderSheetState
if (snapshot.hasError) {
return Center(child: Text('errorLoadingPools'.tr()));
}
final pools = snapshot.data!.filterValid();
final pools = snapshot.data!;
selectedPoolId ??= resolveDefaultPoolId(widget.ref, pools);
return Column(
@@ -1162,9 +1162,7 @@ class _ChatAttachmentUploaderSheetState
// Get the selected pool to check constraints
final pools = await widget.ref.read(poolsProvider.future);
final selectedPool = pools.filterValid().firstWhere(
(p) => p.id == selectedPoolId,
);
final selectedPool = pools.firstWhere((p) => p.id == selectedPoolId);
// Check constraints
final maxFileSize = selectedPool.policyConfig?['max_file_size'] as int?;

View File

@@ -6,7 +6,7 @@ part of 'file_list.dart';
// RiverpodGenerator
// **************************************************************************
String _$billingUsageHash() => r'270ec8499378ee0c038aa44ad1c2e3ad9025740a';
String _$billingUsageHash() => r'58d8bc774868d60781574c85d6b25869a79c57aa';
/// See also [billingUsage].
@ProviderFor(billingUsage)
@@ -25,7 +25,7 @@ final billingUsageProvider =
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef BillingUsageRef = AutoDisposeFutureProviderRef<Map<String, dynamic>?>;
String _$billingQuotaHash() => r'0696b500fa8bb1270641bcacf262be58caff9b38';
String _$billingQuotaHash() => r'4ec5d728e439015800abb2d0d673b5a7329cc654';
/// See also [billingQuota].
@ProviderFor(billingQuota)
@@ -45,7 +45,7 @@ final billingQuotaProvider =
// ignore: unused_element
typedef BillingQuotaRef = AutoDisposeFutureProviderRef<Map<String, dynamic>?>;
String _$cloudFileListNotifierHash() =>
r'e2c8a076a9e635c7b43a87d00f78775427ba6334';
r'22c45a8ea23147a3835ba870ad2f0bb833f853ea';
/// See also [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:island/pods/config.dart';
import 'package:island/pods/file_pool.dart';
import 'package:island/models/file_pool.dart';
class SettingsScreen extends HookConsumerWidget {
const SettingsScreen({super.key});
@@ -417,7 +416,7 @@ class SettingsScreen extends HookConsumerWidget {
if (user.value != null)
pools.when(
data: (data) {
final validPools = data.filterValid();
final validPools = data;
final currentPoolId = resolveDefaultPoolId(ref, data);
return ListTile(
@@ -437,11 +436,14 @@ class SettingsScreen extends HookConsumerWidget {
validPools.map((p) {
return DropdownMenuItem<String>(
value: p.id,
child: Tooltip(
message: p.name,
child: Text(
p.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
).fontSize(14),
),
);
}).toList(),
value: currentPoolId,

View File

@@ -147,6 +147,7 @@ class AccountProfileCard extends HookConsumerWidget {
if (data.badges.isNotEmpty)
BadgeList(badges: data.badges).padding(top: 12),
LevelingProgressCard(
isCompact: true,
level: data.profile.level,
experience: data.profile.experience,
progress: data.profile.levelingProgress,

View File

@@ -59,7 +59,7 @@ class _AttachmentUploaderSheetState extends State<AttachmentUploaderSheet> {
if (snapshot.hasError) {
return Center(child: Text('errorLoadingPools'.tr()));
}
final pools = snapshot.data!.filterValid();
final pools = snapshot.data!;
selectedPoolId ??= resolveDefaultPoolId(widget.ref, pools);
return Column(
@@ -286,9 +286,7 @@ class _AttachmentUploaderSheetState extends State<AttachmentUploaderSheet> {
// Get the selected pool to check constraints
final pools = await widget.ref.read(poolsProvider.future);
final selectedPool = pools.filterValid().firstWhere(
(p) => p.id == selectedPoolId,
);
final selectedPool = pools.firstWhere((p) => p.id == selectedPoolId);
// Check constraints
final maxFileSize = selectedPool.policyConfig?['max_file_size'] as int?;

View File

@@ -130,7 +130,7 @@ class MessageItem extends HookConsumerWidget {
useEffect(() {
if (flashing) {
if (flashTimer.value != null) return null;
flashTimer.value?.cancel();
isFlashing.value = true;
flashTimer.value = Timer.periodic(
const Duration(milliseconds: kFlashDuration),
@@ -343,6 +343,10 @@ class MessageItemDisplayBubble extends HookConsumerWidget {
isCurrentUser
? Theme.of(context).colorScheme.onPrimaryContainer
: Theme.of(context).colorScheme.onSurfaceVariant;
final containerColor =
isCurrentUser
? Theme.of(context).colorScheme.primaryContainer.withOpacity(0.5)
: Theme.of(context).colorScheme.surfaceContainer;
final hasBackground =
ref.watch(backgroundImageFileProvider).valueOrNull != null;
@@ -377,6 +381,15 @@ class MessageItemDisplayBubble extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Flexible(
child: Container(
decoration: BoxDecoration(
color: containerColor,
borderRadius: BorderRadius.circular(16),
),
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -471,6 +484,7 @@ class MessageItemDisplayBubble extends HookConsumerWidget {
],
),
),
),
MessageIndicators(
editedAt: remoteMessage.editedAt,
status: message.status,

View File

@@ -1,6 +1,6 @@
; ==================================================
#define AppVersion "3.2.0"
#define BuildNumber "132"
#define BuildNumber "134"
; ==================================================
#define FullVersion AppVersion + "." + BuildNumber