🔀 Merge pull request '♻️ 使用 Drift 作为本地数据库' (#3) from refactor/drift-as-local-db into master
Reviewed-on: #3
This commit is contained in:
commit
40b885b27b
@ -51,6 +51,14 @@
|
|||||||
to determine the Window background behind the Flutter UI. -->
|
to determine the Window background behind the Flutter UI. -->
|
||||||
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
|
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="solink" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter android:autoVerify="true">
|
<intent-filter android:autoVerify="true">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
@ -61,14 +69,6 @@
|
|||||||
<data android:scheme="https" />
|
<data android:scheme="https" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
<data android:scheme="solink" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
|
@ -2,3 +2,4 @@ description: This file stores settings for Dart & Flutter DevTools.
|
|||||||
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||||
extensions:
|
extensions:
|
||||||
- provider: true
|
- provider: true
|
||||||
|
- drift: true
|
@ -54,22 +54,22 @@ PODS:
|
|||||||
- Firebase/Performance (11.0.0):
|
- Firebase/Performance (11.0.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebasePerformance (~> 11.0.0)
|
- FirebasePerformance (~> 11.0.0)
|
||||||
- firebase_analytics (11.3.0):
|
- firebase_analytics (11.3.1):
|
||||||
- Firebase/Analytics (= 11.0.0)
|
- Firebase/Analytics (= 11.0.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_core (3.4.1):
|
- firebase_core (3.4.1):
|
||||||
- Firebase/CoreOnly (= 11.0.0)
|
- Firebase/CoreOnly (= 11.0.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_crashlytics (4.1.0):
|
- firebase_crashlytics (4.1.1):
|
||||||
- Firebase/Crashlytics (= 11.0.0)
|
- Firebase/Crashlytics (= 11.0.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_messaging (15.1.0):
|
- firebase_messaging (15.1.1):
|
||||||
- Firebase/Messaging (= 11.0.0)
|
- Firebase/Messaging (= 11.0.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_performance (0.10.0-5):
|
- firebase_performance (0.10.0-6):
|
||||||
- Firebase/Performance (= 11.0.0)
|
- Firebase/Performance (= 11.0.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
@ -264,6 +264,24 @@ PODS:
|
|||||||
- sqflite (0.0.3):
|
- sqflite (0.0.3):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- "sqlite3 (3.46.1+1)":
|
||||||
|
- "sqlite3/common (= 3.46.1+1)"
|
||||||
|
- "sqlite3/common (3.46.1+1)"
|
||||||
|
- "sqlite3/dbstatvtab (3.46.1+1)":
|
||||||
|
- sqlite3/common
|
||||||
|
- "sqlite3/fts5 (3.46.1+1)":
|
||||||
|
- sqlite3/common
|
||||||
|
- "sqlite3/perf-threadsafe (3.46.1+1)":
|
||||||
|
- sqlite3/common
|
||||||
|
- "sqlite3/rtree (3.46.1+1)":
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3_flutter_libs (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- "sqlite3 (~> 3.46.0+1)"
|
||||||
|
- sqlite3/dbstatvtab
|
||||||
|
- sqlite3/fts5
|
||||||
|
- sqlite3/perf-threadsafe
|
||||||
|
- sqlite3/rtree
|
||||||
- SwiftyGif (5.4.5)
|
- SwiftyGif (5.4.5)
|
||||||
- TOCropViewController (2.7.4)
|
- TOCropViewController (2.7.4)
|
||||||
- url_launcher_ios (0.0.1):
|
- url_launcher_ios (0.0.1):
|
||||||
@ -305,6 +323,7 @@ DEPENDENCIES:
|
|||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
|
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
|
||||||
|
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
||||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||||
@ -334,6 +353,7 @@ SPEC REPOS:
|
|||||||
- PromisesObjC
|
- PromisesObjC
|
||||||
- PromisesSwift
|
- PromisesSwift
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
|
- sqlite3
|
||||||
- SwiftyGif
|
- SwiftyGif
|
||||||
- TOCropViewController
|
- TOCropViewController
|
||||||
- WebRTC-SDK
|
- WebRTC-SDK
|
||||||
@ -399,6 +419,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||||
sqflite:
|
sqflite:
|
||||||
:path: ".symlinks/plugins/sqflite/darwin"
|
:path: ".symlinks/plugins/sqflite/darwin"
|
||||||
|
sqlite3_flutter_libs:
|
||||||
|
:path: ".symlinks/plugins/sqlite3_flutter_libs/ios"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
volume_controller:
|
volume_controller:
|
||||||
@ -413,11 +435,11 @@ SPEC CHECKSUMS:
|
|||||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
||||||
Firebase: 9f574c08c2396885b5e7e100ed4293d956218af9
|
Firebase: 9f574c08c2396885b5e7e100ed4293d956218af9
|
||||||
firebase_analytics: 1a66fe8d4375eccff44671ea37897683a78b2675
|
firebase_analytics: b8ce6c2c4b245d3c3bb3a147965d09da0f455959
|
||||||
firebase_core: ba84e940cf5cbbc601095f86556560937419195c
|
firebase_core: ba84e940cf5cbbc601095f86556560937419195c
|
||||||
firebase_crashlytics: e4f04180f443d5a8b56fbc0685bdbd7d90dd26f0
|
firebase_crashlytics: 4111f8198b78c99471c955af488cecd8224967e6
|
||||||
firebase_messaging: 15d8b557010f3bb7b98d0302e1c7c8fbcd244425
|
firebase_messaging: c40f84e7a98da956d5262fada373b5c458edcf13
|
||||||
firebase_performance: d373c742649e2d85d92cc223b4511c3d132887ef
|
firebase_performance: 8b7b9ca5adf3a9b3afa12b4eb96b9cabefc2c248
|
||||||
FirebaseABTesting: c2e22c3aab99afa81d0561708b2c1c356c556976
|
FirebaseABTesting: c2e22c3aab99afa81d0561708b2c1c356c556976
|
||||||
FirebaseAnalytics: 27eb78b97880ea4a004839b9bac0b58880f5a92a
|
FirebaseAnalytics: 27eb78b97880ea4a004839b9bac0b58880f5a92a
|
||||||
FirebaseCore: 3cf438f431f18c12cdf2aaf64434648b63f7e383
|
FirebaseCore: 3cf438f431f18c12cdf2aaf64434648b63f7e383
|
||||||
@ -460,6 +482,8 @@ SPEC CHECKSUMS:
|
|||||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
||||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||||
|
sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb
|
||||||
|
sqlite3_flutter_libs: c00457ebd31e59fa6bb830380ddba24d44fbcd3b
|
||||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||||
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
||||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||||
|
@ -2,45 +2,32 @@ import 'package:get/get.dart';
|
|||||||
import 'package:solian/models/channel.dart';
|
import 'package:solian/models/channel.dart';
|
||||||
import 'package:solian/models/event.dart';
|
import 'package:solian/models/event.dart';
|
||||||
import 'package:solian/platform.dart';
|
import 'package:solian/platform.dart';
|
||||||
import 'package:solian/providers/message/adaptor.dart';
|
import 'package:solian/providers/database/database.dart';
|
||||||
import 'package:solian/providers/message/events.dart';
|
import 'package:solian/providers/database/services/messages.dart';
|
||||||
|
|
||||||
class ChatEventController {
|
class ChatEventController {
|
||||||
late final MessageHistoryDb database;
|
late final MessagesFetchingProvider src;
|
||||||
|
|
||||||
final RxList<LocalEvent> currentEvents = RxList.empty(growable: true);
|
final RxList<LocalMessageEventTableData> currentEvents =
|
||||||
|
RxList.empty(growable: true);
|
||||||
final RxInt totalEvents = 0.obs;
|
final RxInt totalEvents = 0.obs;
|
||||||
|
|
||||||
final RxBool isLoading = false.obs;
|
final RxBool isLoading = true.obs;
|
||||||
|
|
||||||
Channel? channel;
|
Channel? channel;
|
||||||
String? scope;
|
String? scope;
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
if (!PlatformInfo.isWeb) {
|
src = Get.find();
|
||||||
database = await createHistoryDb();
|
|
||||||
}
|
|
||||||
currentEvents.clear();
|
currentEvents.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<LocalEvent?> getEvent(int id) async {
|
Future<LocalMessageEventTableData?> getEvent(int id) async {
|
||||||
if (channel == null || scope == null) return null;
|
if (channel == null || scope == null) return null;
|
||||||
|
return await src.getEvent(id, channel!, scope: scope!);
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
final remoteRecord = await getRemoteEvent(id, channel!, scope!);
|
|
||||||
if (remoteRecord == null) return null;
|
|
||||||
return LocalEvent(
|
|
||||||
remoteRecord.id,
|
|
||||||
remoteRecord,
|
|
||||||
remoteRecord.channelId,
|
|
||||||
remoteRecord.createdAt,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return await database.getEvent(id, channel!, scope: scope!);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getEvents(Channel channel, String scope) async {
|
Future<void> getInitialEvents(Channel channel, String scope) async {
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
|
|
||||||
@ -48,24 +35,30 @@ class ChatEventController {
|
|||||||
|
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
if (PlatformInfo.isWeb) {
|
if (PlatformInfo.isWeb) {
|
||||||
final result = await getRemoteEvents(
|
final result = await src.fetchRemoteEvents(
|
||||||
channel,
|
channel,
|
||||||
scope,
|
scope,
|
||||||
remainDepth: 3,
|
depth: 1,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
);
|
);
|
||||||
totalEvents.value = result?.$2 ?? 0;
|
totalEvents.value = result?.$2 ?? 0;
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
for (final x in result.$1.reversed) {
|
for (final x in result.$1.reversed) {
|
||||||
final entry = LocalEvent(x.id, x, x.channelId, x.createdAt);
|
final entry = LocalMessageEventTableData(
|
||||||
|
id: x.id,
|
||||||
|
channelId: x.channelId,
|
||||||
|
createdAt: x.createdAt,
|
||||||
|
data: x,
|
||||||
|
);
|
||||||
insertEvent(entry);
|
insertEvent(entry);
|
||||||
applyEvent(entry);
|
applyEvent(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final result = await database.syncRemoteEvents(
|
final result = await src.pullRemoteEvents(
|
||||||
channel,
|
channel,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
|
depth: 1,
|
||||||
);
|
);
|
||||||
totalEvents.value = result?.$2 ?? 0;
|
totalEvents.value = result?.$2 ?? 0;
|
||||||
await syncLocal(channel);
|
await syncLocal(channel);
|
||||||
@ -76,22 +69,27 @@ class ChatEventController {
|
|||||||
Future<void> loadEvents(Channel channel, String scope) async {
|
Future<void> loadEvents(Channel channel, String scope) async {
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
if (PlatformInfo.isWeb) {
|
if (PlatformInfo.isWeb) {
|
||||||
final result = await getRemoteEvents(
|
final result = await src.fetchRemoteEvents(
|
||||||
channel,
|
channel,
|
||||||
scope,
|
scope,
|
||||||
remainDepth: 3,
|
depth: 3,
|
||||||
offset: currentEvents.length,
|
offset: currentEvents.length,
|
||||||
);
|
);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
totalEvents.value = result.$2;
|
totalEvents.value = result.$2;
|
||||||
for (final x in result.$1.reversed) {
|
for (final x in result.$1.reversed) {
|
||||||
final entry = LocalEvent(x.id, x, x.channelId, x.createdAt);
|
final entry = LocalMessageEventTableData(
|
||||||
|
id: x.id,
|
||||||
|
channelId: x.channelId,
|
||||||
|
createdAt: x.createdAt,
|
||||||
|
data: x,
|
||||||
|
);
|
||||||
currentEvents.add(entry);
|
currentEvents.add(entry);
|
||||||
applyEvent(entry);
|
applyEvent(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final result = await database.syncRemoteEvents(
|
final result = await src.pullRemoteEvents(
|
||||||
channel,
|
channel,
|
||||||
depth: 3,
|
depth: 3,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
@ -105,7 +103,7 @@ class ChatEventController {
|
|||||||
|
|
||||||
Future<bool> syncLocal(Channel channel) async {
|
Future<bool> syncLocal(Channel channel) async {
|
||||||
if (PlatformInfo.isWeb) return false;
|
if (PlatformInfo.isWeb) return false;
|
||||||
final data = await database.localEvents.findAllByChannel(channel.id);
|
final data = await src.listEvents(channel);
|
||||||
currentEvents.replaceRange(0, currentEvents.length, data);
|
currentEvents.replaceRange(0, currentEvents.length, data);
|
||||||
for (final x in data.reversed) {
|
for (final x in data.reversed) {
|
||||||
applyEvent(x);
|
applyEvent(x);
|
||||||
@ -114,26 +112,29 @@ class ChatEventController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
receiveEvent(Event remote) async {
|
receiveEvent(Event remote) async {
|
||||||
LocalEvent entry;
|
LocalMessageEventTableData entry;
|
||||||
if (PlatformInfo.isWeb) {
|
if (PlatformInfo.isWeb) {
|
||||||
entry = LocalEvent(
|
entry = LocalMessageEventTableData(
|
||||||
remote.id,
|
id: remote.id,
|
||||||
remote,
|
channelId: remote.channelId,
|
||||||
remote.channelId,
|
createdAt: remote.createdAt,
|
||||||
remote.createdAt,
|
data: remote,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
entry = await database.receiveEvent(remote);
|
entry = await src.receiveEvent(remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalEvents.value++;
|
||||||
insertEvent(entry);
|
insertEvent(entry);
|
||||||
applyEvent(entry);
|
applyEvent(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
insertEvent(LocalEvent entry) {
|
void insertEvent(LocalMessageEventTableData entry) {
|
||||||
if (entry.channelId != channel?.id) return;
|
if (entry.channelId != channel?.id) return;
|
||||||
|
|
||||||
final idx = currentEvents.indexWhere((x) => x.data.uuid == entry.data.uuid);
|
final idx = currentEvents.indexWhere(
|
||||||
|
(x) => x.data!.uuid == entry.data!.uuid,
|
||||||
|
);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
currentEvents[idx] = entry;
|
currentEvents[idx] = entry;
|
||||||
} else {
|
} else {
|
||||||
@ -141,36 +142,36 @@ class ChatEventController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applyEvent(LocalEvent entry) {
|
void applyEvent(LocalMessageEventTableData entry) {
|
||||||
if (entry.channelId != channel?.id) return;
|
if (entry.channelId != channel?.id) return;
|
||||||
|
|
||||||
switch (entry.data.type) {
|
switch (entry.data!.type) {
|
||||||
case 'messages.edit':
|
case 'messages.edit':
|
||||||
final body = EventMessageBody.fromJson(entry.data.body);
|
final body = EventMessageBody.fromJson(entry.data!.body);
|
||||||
if (body.relatedEvent != null) {
|
if (body.relatedEvent != null) {
|
||||||
final idx =
|
final idx =
|
||||||
currentEvents.indexWhere((x) => x.data.id == body.relatedEvent);
|
currentEvents.indexWhere((x) => x.data!.id == body.relatedEvent);
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
currentEvents[idx].data.body = entry.data.body;
|
currentEvents[idx].data!.body = entry.data!.body;
|
||||||
currentEvents[idx].data.updatedAt = entry.data.updatedAt;
|
currentEvents[idx].data!.updatedAt = entry.data!.updatedAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 'messages.delete':
|
case 'messages.delete':
|
||||||
final body = EventMessageBody.fromJson(entry.data.body);
|
final body = EventMessageBody.fromJson(entry.data!.body);
|
||||||
if (body.relatedEvent != null) {
|
if (body.relatedEvent != null) {
|
||||||
currentEvents.removeWhere((x) => x.id == body.relatedEvent);
|
currentEvents.removeWhere((x) => x.id == body.relatedEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addPendingEvent(Event info) async {
|
Future<void> addPendingEvent(Event info) async {
|
||||||
currentEvents.insert(
|
currentEvents.insert(
|
||||||
0,
|
0,
|
||||||
LocalEvent(
|
LocalMessageEventTableData(
|
||||||
info.id,
|
id: info.id,
|
||||||
info,
|
channelId: info.channelId,
|
||||||
info.channelId,
|
createdAt: DateTime.now(),
|
||||||
DateTime.now(),
|
data: info,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ import 'package:solian/firebase_options.dart';
|
|||||||
import 'package:solian/platform.dart';
|
import 'package:solian/platform.dart';
|
||||||
import 'package:solian/providers/attachment_uploader.dart';
|
import 'package:solian/providers/attachment_uploader.dart';
|
||||||
import 'package:solian/providers/daily_sign.dart';
|
import 'package:solian/providers/daily_sign.dart';
|
||||||
|
import 'package:solian/providers/database/database.dart';
|
||||||
|
import 'package:solian/providers/database/services/messages.dart';
|
||||||
import 'package:solian/providers/last_read.dart';
|
import 'package:solian/providers/last_read.dart';
|
||||||
import 'package:solian/providers/link_expander.dart';
|
import 'package:solian/providers/link_expander.dart';
|
||||||
import 'package:solian/providers/navigation.dart';
|
import 'package:solian/providers/navigation.dart';
|
||||||
@ -43,6 +45,7 @@ void main() async {
|
|||||||
|
|
||||||
GoRouter.optionURLReflectsImperativeAPIs = true;
|
GoRouter.optionURLReflectsImperativeAPIs = true;
|
||||||
|
|
||||||
|
Get.put(DatabaseProvider());
|
||||||
Get.put(AppTranslations());
|
Get.put(AppTranslations());
|
||||||
await AppTranslations.init();
|
await AppTranslations.init();
|
||||||
|
|
||||||
@ -135,6 +138,7 @@ class SolianApp extends StatelessWidget {
|
|||||||
Get.lazyPut(() => StatusProvider());
|
Get.lazyPut(() => StatusProvider());
|
||||||
Get.lazyPut(() => ChannelProvider());
|
Get.lazyPut(() => ChannelProvider());
|
||||||
Get.lazyPut(() => RealmProvider());
|
Get.lazyPut(() => RealmProvider());
|
||||||
|
Get.lazyPut(() => MessagesFetchingProvider());
|
||||||
Get.lazyPut(() => ChatCallProvider());
|
Get.lazyPut(() => ChatCallProvider());
|
||||||
Get.lazyPut(() => AttachmentUploaderController());
|
Get.lazyPut(() => AttachmentUploaderController());
|
||||||
Get.lazyPut(() => LinkExpandProvider());
|
Get.lazyPut(() => LinkExpandProvider());
|
||||||
|
@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/get_connect/http/src/request/request.dart';
|
import 'package:get/get_connect/http/src/request/request.dart';
|
||||||
import 'package:solian/controllers/chat_events_controller.dart';
|
|
||||||
import 'package:solian/exceptions/request.dart';
|
import 'package:solian/exceptions/request.dart';
|
||||||
import 'package:solian/exceptions/unauthorized.dart';
|
import 'package:solian/exceptions/unauthorized.dart';
|
||||||
import 'package:solian/providers/websocket.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
@ -199,11 +198,6 @@ class AuthProvider extends GetConnect {
|
|||||||
Get.find<WebSocketProvider>().notifications.clear();
|
Get.find<WebSocketProvider>().notifications.clear();
|
||||||
Get.find<WebSocketProvider>().notificationUnread.value = 0;
|
Get.find<WebSocketProvider>().notificationUnread.value = 0;
|
||||||
|
|
||||||
final chatHistory = ChatEventController();
|
|
||||||
chatHistory.initialize().then((_) async {
|
|
||||||
await chatHistory.database.localEvents.wipeLocalEvents();
|
|
||||||
});
|
|
||||||
|
|
||||||
storage.deleteAll();
|
storage.deleteAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
lib/providers/database/database.dart
Normal file
24
lib/providers/database/database.dart
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift_flutter/drift_flutter.dart';
|
||||||
|
import 'package:get/get.dart' hide Value;
|
||||||
|
import 'package:solian/providers/database/tables/messages.dart';
|
||||||
|
|
||||||
|
import 'package:solian/models/event.dart';
|
||||||
|
|
||||||
|
part 'database.g.dart';
|
||||||
|
|
||||||
|
@DriftDatabase(tables: [LocalMessageEventTable])
|
||||||
|
class AppDatabase extends _$AppDatabase {
|
||||||
|
AppDatabase() : super(_openConnection());
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get schemaVersion => 1;
|
||||||
|
|
||||||
|
static QueryExecutor _openConnection() {
|
||||||
|
return driftDatabase(name: 'solar_network_local_db');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DatabaseProvider extends GetxController {
|
||||||
|
final database = AppDatabase();
|
||||||
|
}
|
429
lib/providers/database/database.g.dart
Normal file
429
lib/providers/database/database.g.dart
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'database.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
class $LocalMessageEventTableTable extends LocalMessageEventTable
|
||||||
|
with TableInfo<$LocalMessageEventTableTable, LocalMessageEventTableData> {
|
||||||
|
@override
|
||||||
|
final GeneratedDatabase attachedDatabase;
|
||||||
|
final String? _alias;
|
||||||
|
$LocalMessageEventTableTable(this.attachedDatabase, [this._alias]);
|
||||||
|
static const VerificationMeta _idMeta = const VerificationMeta('id');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> id = GeneratedColumn<int>(
|
||||||
|
'id', aliasedName, false,
|
||||||
|
hasAutoIncrement: true,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints:
|
||||||
|
GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
|
||||||
|
static const VerificationMeta _channelIdMeta =
|
||||||
|
const VerificationMeta('channelId');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> channelId = GeneratedColumn<int>(
|
||||||
|
'channel_id', aliasedName, false,
|
||||||
|
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||||
|
static const VerificationMeta _dataMeta = const VerificationMeta('data');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumnWithTypeConverter<Event?, String> data =
|
||||||
|
GeneratedColumn<String>('data', aliasedName, false,
|
||||||
|
type: DriftSqlType.string, requiredDuringInsert: true)
|
||||||
|
.withConverter<Event?>($LocalMessageEventTableTable.$converterdata);
|
||||||
|
static const VerificationMeta _createdAtMeta =
|
||||||
|
const VerificationMeta('createdAt');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||||
|
'created_at', aliasedName, false,
|
||||||
|
type: DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: Constant(DateTime.now()));
|
||||||
|
@override
|
||||||
|
List<GeneratedColumn> get $columns => [id, channelId, data, createdAt];
|
||||||
|
@override
|
||||||
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
@override
|
||||||
|
String get actualTableName => $name;
|
||||||
|
static const String $name = 'local_message_event_table';
|
||||||
|
@override
|
||||||
|
VerificationContext validateIntegrity(
|
||||||
|
Insertable<LocalMessageEventTableData> instance,
|
||||||
|
{bool isInserting = false}) {
|
||||||
|
final context = VerificationContext();
|
||||||
|
final data = instance.toColumns(true);
|
||||||
|
if (data.containsKey('id')) {
|
||||||
|
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
|
||||||
|
}
|
||||||
|
if (data.containsKey('channel_id')) {
|
||||||
|
context.handle(_channelIdMeta,
|
||||||
|
channelId.isAcceptableOrUnknown(data['channel_id']!, _channelIdMeta));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_channelIdMeta);
|
||||||
|
}
|
||||||
|
context.handle(_dataMeta, const VerificationResult.success());
|
||||||
|
if (data.containsKey('created_at')) {
|
||||||
|
context.handle(_createdAtMeta,
|
||||||
|
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta));
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<GeneratedColumn> get $primaryKey => {id};
|
||||||
|
@override
|
||||||
|
LocalMessageEventTableData map(Map<String, dynamic> data,
|
||||||
|
{String? tablePrefix}) {
|
||||||
|
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||||
|
return LocalMessageEventTableData(
|
||||||
|
id: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
|
||||||
|
channelId: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.int, data['${effectivePrefix}channel_id'])!,
|
||||||
|
data: $LocalMessageEventTableTable.$converterdata.fromSql(attachedDatabase
|
||||||
|
.typeMapping
|
||||||
|
.read(DriftSqlType.string, data['${effectivePrefix}data'])!),
|
||||||
|
createdAt: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$LocalMessageEventTableTable createAlias(String alias) {
|
||||||
|
return $LocalMessageEventTableTable(attachedDatabase, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TypeConverter<Event?, String> $converterdata =
|
||||||
|
const MessageEventConverter();
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalMessageEventTableData extends DataClass
|
||||||
|
implements Insertable<LocalMessageEventTableData> {
|
||||||
|
final int id;
|
||||||
|
final int channelId;
|
||||||
|
final Event? data;
|
||||||
|
final DateTime createdAt;
|
||||||
|
const LocalMessageEventTableData(
|
||||||
|
{required this.id,
|
||||||
|
required this.channelId,
|
||||||
|
this.data,
|
||||||
|
required this.createdAt});
|
||||||
|
@override
|
||||||
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, Expression>{};
|
||||||
|
map['id'] = Variable<int>(id);
|
||||||
|
map['channel_id'] = Variable<int>(channelId);
|
||||||
|
if (!nullToAbsent || data != null) {
|
||||||
|
map['data'] = Variable<String>(
|
||||||
|
$LocalMessageEventTableTable.$converterdata.toSql(data));
|
||||||
|
}
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalMessageEventTableCompanion toCompanion(bool nullToAbsent) {
|
||||||
|
return LocalMessageEventTableCompanion(
|
||||||
|
id: Value(id),
|
||||||
|
channelId: Value(channelId),
|
||||||
|
data: data == null && nullToAbsent ? const Value.absent() : Value(data),
|
||||||
|
createdAt: Value(createdAt),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory LocalMessageEventTableData.fromJson(Map<String, dynamic> json,
|
||||||
|
{ValueSerializer? serializer}) {
|
||||||
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
|
return LocalMessageEventTableData(
|
||||||
|
id: serializer.fromJson<int>(json['id']),
|
||||||
|
channelId: serializer.fromJson<int>(json['channelId']),
|
||||||
|
data: serializer.fromJson<Event?>(json['data']),
|
||||||
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||||
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
|
return <String, dynamic>{
|
||||||
|
'id': serializer.toJson<int>(id),
|
||||||
|
'channelId': serializer.toJson<int>(channelId),
|
||||||
|
'data': serializer.toJson<Event?>(data),
|
||||||
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalMessageEventTableData copyWith(
|
||||||
|
{int? id,
|
||||||
|
int? channelId,
|
||||||
|
Value<Event?> data = const Value.absent(),
|
||||||
|
DateTime? createdAt}) =>
|
||||||
|
LocalMessageEventTableData(
|
||||||
|
id: id ?? this.id,
|
||||||
|
channelId: channelId ?? this.channelId,
|
||||||
|
data: data.present ? data.value : this.data,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
);
|
||||||
|
LocalMessageEventTableData copyWithCompanion(
|
||||||
|
LocalMessageEventTableCompanion data) {
|
||||||
|
return LocalMessageEventTableData(
|
||||||
|
id: data.id.present ? data.id.value : this.id,
|
||||||
|
channelId: data.channelId.present ? data.channelId.value : this.channelId,
|
||||||
|
data: data.data.present ? data.data.value : this.data,
|
||||||
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('LocalMessageEventTableData(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('channelId: $channelId, ')
|
||||||
|
..write('data: $data, ')
|
||||||
|
..write('createdAt: $createdAt')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(id, channelId, data, createdAt);
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is LocalMessageEventTableData &&
|
||||||
|
other.id == this.id &&
|
||||||
|
other.channelId == this.channelId &&
|
||||||
|
other.data == this.data &&
|
||||||
|
other.createdAt == this.createdAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalMessageEventTableCompanion
|
||||||
|
extends UpdateCompanion<LocalMessageEventTableData> {
|
||||||
|
final Value<int> id;
|
||||||
|
final Value<int> channelId;
|
||||||
|
final Value<Event?> data;
|
||||||
|
final Value<DateTime> createdAt;
|
||||||
|
const LocalMessageEventTableCompanion({
|
||||||
|
this.id = const Value.absent(),
|
||||||
|
this.channelId = const Value.absent(),
|
||||||
|
this.data = const Value.absent(),
|
||||||
|
this.createdAt = const Value.absent(),
|
||||||
|
});
|
||||||
|
LocalMessageEventTableCompanion.insert({
|
||||||
|
this.id = const Value.absent(),
|
||||||
|
required int channelId,
|
||||||
|
required Event? data,
|
||||||
|
this.createdAt = const Value.absent(),
|
||||||
|
}) : channelId = Value(channelId),
|
||||||
|
data = Value(data);
|
||||||
|
static Insertable<LocalMessageEventTableData> custom({
|
||||||
|
Expression<int>? id,
|
||||||
|
Expression<int>? channelId,
|
||||||
|
Expression<String>? data,
|
||||||
|
Expression<DateTime>? createdAt,
|
||||||
|
}) {
|
||||||
|
return RawValuesInsertable({
|
||||||
|
if (id != null) 'id': id,
|
||||||
|
if (channelId != null) 'channel_id': channelId,
|
||||||
|
if (data != null) 'data': data,
|
||||||
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalMessageEventTableCompanion copyWith(
|
||||||
|
{Value<int>? id,
|
||||||
|
Value<int>? channelId,
|
||||||
|
Value<Event?>? data,
|
||||||
|
Value<DateTime>? createdAt}) {
|
||||||
|
return LocalMessageEventTableCompanion(
|
||||||
|
id: id ?? this.id,
|
||||||
|
channelId: channelId ?? this.channelId,
|
||||||
|
data: data ?? this.data,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, Expression>{};
|
||||||
|
if (id.present) {
|
||||||
|
map['id'] = Variable<int>(id.value);
|
||||||
|
}
|
||||||
|
if (channelId.present) {
|
||||||
|
map['channel_id'] = Variable<int>(channelId.value);
|
||||||
|
}
|
||||||
|
if (data.present) {
|
||||||
|
map['data'] = Variable<String>(
|
||||||
|
$LocalMessageEventTableTable.$converterdata.toSql(data.value));
|
||||||
|
}
|
||||||
|
if (createdAt.present) {
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('LocalMessageEventTableCompanion(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('channelId: $channelId, ')
|
||||||
|
..write('data: $data, ')
|
||||||
|
..write('createdAt: $createdAt')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _$AppDatabase extends GeneratedDatabase {
|
||||||
|
_$AppDatabase(QueryExecutor e) : super(e);
|
||||||
|
$AppDatabaseManager get managers => $AppDatabaseManager(this);
|
||||||
|
late final $LocalMessageEventTableTable localMessageEventTable =
|
||||||
|
$LocalMessageEventTableTable(this);
|
||||||
|
@override
|
||||||
|
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||||
|
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||||
|
@override
|
||||||
|
List<DatabaseSchemaEntity> get allSchemaEntities => [localMessageEventTable];
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$LocalMessageEventTableTableCreateCompanionBuilder
|
||||||
|
= LocalMessageEventTableCompanion Function({
|
||||||
|
Value<int> id,
|
||||||
|
required int channelId,
|
||||||
|
required Event? data,
|
||||||
|
Value<DateTime> createdAt,
|
||||||
|
});
|
||||||
|
typedef $$LocalMessageEventTableTableUpdateCompanionBuilder
|
||||||
|
= LocalMessageEventTableCompanion Function({
|
||||||
|
Value<int> id,
|
||||||
|
Value<int> channelId,
|
||||||
|
Value<Event?> data,
|
||||||
|
Value<DateTime> createdAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
class $$LocalMessageEventTableTableFilterComposer
|
||||||
|
extends FilterComposer<_$AppDatabase, $LocalMessageEventTableTable> {
|
||||||
|
$$LocalMessageEventTableTableFilterComposer(super.$state);
|
||||||
|
ColumnFilters<int> get id => $state.composableBuilder(
|
||||||
|
column: $state.table.id,
|
||||||
|
builder: (column, joinBuilders) =>
|
||||||
|
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||||
|
|
||||||
|
ColumnFilters<int> get channelId => $state.composableBuilder(
|
||||||
|
column: $state.table.channelId,
|
||||||
|
builder: (column, joinBuilders) =>
|
||||||
|
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||||
|
|
||||||
|
ColumnWithTypeConverterFilters<Event?, Event, String> get data =>
|
||||||
|
$state.composableBuilder(
|
||||||
|
column: $state.table.data,
|
||||||
|
builder: (column, joinBuilders) => ColumnWithTypeConverterFilters(
|
||||||
|
column,
|
||||||
|
joinBuilders: joinBuilders));
|
||||||
|
|
||||||
|
ColumnFilters<DateTime> get createdAt => $state.composableBuilder(
|
||||||
|
column: $state.table.createdAt,
|
||||||
|
builder: (column, joinBuilders) =>
|
||||||
|
ColumnFilters(column, joinBuilders: joinBuilders));
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LocalMessageEventTableTableOrderingComposer
|
||||||
|
extends OrderingComposer<_$AppDatabase, $LocalMessageEventTableTable> {
|
||||||
|
$$LocalMessageEventTableTableOrderingComposer(super.$state);
|
||||||
|
ColumnOrderings<int> get id => $state.composableBuilder(
|
||||||
|
column: $state.table.id,
|
||||||
|
builder: (column, joinBuilders) =>
|
||||||
|
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||||
|
|
||||||
|
ColumnOrderings<int> get channelId => $state.composableBuilder(
|
||||||
|
column: $state.table.channelId,
|
||||||
|
builder: (column, joinBuilders) =>
|
||||||
|
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||||
|
|
||||||
|
ColumnOrderings<String> get data => $state.composableBuilder(
|
||||||
|
column: $state.table.data,
|
||||||
|
builder: (column, joinBuilders) =>
|
||||||
|
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||||
|
|
||||||
|
ColumnOrderings<DateTime> get createdAt => $state.composableBuilder(
|
||||||
|
column: $state.table.createdAt,
|
||||||
|
builder: (column, joinBuilders) =>
|
||||||
|
ColumnOrderings(column, joinBuilders: joinBuilders));
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LocalMessageEventTableTableTableManager extends RootTableManager<
|
||||||
|
_$AppDatabase,
|
||||||
|
$LocalMessageEventTableTable,
|
||||||
|
LocalMessageEventTableData,
|
||||||
|
$$LocalMessageEventTableTableFilterComposer,
|
||||||
|
$$LocalMessageEventTableTableOrderingComposer,
|
||||||
|
$$LocalMessageEventTableTableCreateCompanionBuilder,
|
||||||
|
$$LocalMessageEventTableTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
LocalMessageEventTableData,
|
||||||
|
BaseReferences<_$AppDatabase, $LocalMessageEventTableTable,
|
||||||
|
LocalMessageEventTableData>
|
||||||
|
),
|
||||||
|
LocalMessageEventTableData,
|
||||||
|
PrefetchHooks Function()> {
|
||||||
|
$$LocalMessageEventTableTableTableManager(
|
||||||
|
_$AppDatabase db, $LocalMessageEventTableTable table)
|
||||||
|
: super(TableManagerState(
|
||||||
|
db: db,
|
||||||
|
table: table,
|
||||||
|
filteringComposer: $$LocalMessageEventTableTableFilterComposer(
|
||||||
|
ComposerState(db, table)),
|
||||||
|
orderingComposer: $$LocalMessageEventTableTableOrderingComposer(
|
||||||
|
ComposerState(db, table)),
|
||||||
|
updateCompanionCallback: ({
|
||||||
|
Value<int> id = const Value.absent(),
|
||||||
|
Value<int> channelId = const Value.absent(),
|
||||||
|
Value<Event?> data = const Value.absent(),
|
||||||
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
|
}) =>
|
||||||
|
LocalMessageEventTableCompanion(
|
||||||
|
id: id,
|
||||||
|
channelId: channelId,
|
||||||
|
data: data,
|
||||||
|
createdAt: createdAt,
|
||||||
|
),
|
||||||
|
createCompanionCallback: ({
|
||||||
|
Value<int> id = const Value.absent(),
|
||||||
|
required int channelId,
|
||||||
|
required Event? data,
|
||||||
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
|
}) =>
|
||||||
|
LocalMessageEventTableCompanion.insert(
|
||||||
|
id: id,
|
||||||
|
channelId: channelId,
|
||||||
|
data: data,
|
||||||
|
createdAt: createdAt,
|
||||||
|
),
|
||||||
|
withReferenceMapper: (p0) => p0
|
||||||
|
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
|
||||||
|
.toList(),
|
||||||
|
prefetchHooksCallback: null,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$LocalMessageEventTableTableProcessedTableManager
|
||||||
|
= ProcessedTableManager<
|
||||||
|
_$AppDatabase,
|
||||||
|
$LocalMessageEventTableTable,
|
||||||
|
LocalMessageEventTableData,
|
||||||
|
$$LocalMessageEventTableTableFilterComposer,
|
||||||
|
$$LocalMessageEventTableTableOrderingComposer,
|
||||||
|
$$LocalMessageEventTableTableCreateCompanionBuilder,
|
||||||
|
$$LocalMessageEventTableTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
LocalMessageEventTableData,
|
||||||
|
BaseReferences<_$AppDatabase, $LocalMessageEventTableTable,
|
||||||
|
LocalMessageEventTableData>
|
||||||
|
),
|
||||||
|
LocalMessageEventTableData,
|
||||||
|
PrefetchHooks Function()>;
|
||||||
|
|
||||||
|
class $AppDatabaseManager {
|
||||||
|
final _$AppDatabase _db;
|
||||||
|
$AppDatabaseManager(this._db);
|
||||||
|
$$LocalMessageEventTableTableTableManager get localMessageEventTable =>
|
||||||
|
$$LocalMessageEventTableTableTableManager(
|
||||||
|
_db, _db.localMessageEventTable);
|
||||||
|
}
|
203
lib/providers/database/services/messages.dart
Normal file
203
lib/providers/database/services/messages.dart
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:get/get.dart' hide Value;
|
||||||
|
import 'package:solian/exceptions/request.dart';
|
||||||
|
import 'package:solian/models/channel.dart';
|
||||||
|
import 'package:solian/models/event.dart';
|
||||||
|
import 'package:solian/models/pagination.dart';
|
||||||
|
import 'package:solian/providers/auth.dart';
|
||||||
|
import 'package:solian/providers/database/database.dart';
|
||||||
|
|
||||||
|
class MessagesFetchingProvider extends GetxController {
|
||||||
|
Future<(List<Event>, int)?> getWhatsNewEvents(int pivot, {take = 10}) async {
|
||||||
|
final AuthProvider auth = Get.find();
|
||||||
|
if (auth.isAuthorized.isFalse) return null;
|
||||||
|
|
||||||
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
|
final resp = await client.get(
|
||||||
|
'/whats-new?pivot=$pivot&take=$take',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resp.statusCode != 200) {
|
||||||
|
throw RequestException(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
final PaginationResult response = PaginationResult.fromJson(resp.body);
|
||||||
|
final result =
|
||||||
|
response.data?.map((e) => Event.fromJson(e)).toList() ?? List.empty();
|
||||||
|
|
||||||
|
return (result, response.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Event?> fetchRemoteEvent(int id, Channel channel, String scope) async {
|
||||||
|
final AuthProvider auth = Get.find();
|
||||||
|
if (auth.isAuthorized.isFalse) return null;
|
||||||
|
|
||||||
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
|
final resp = await client.get(
|
||||||
|
'/channels/$scope/${channel.alias}/events/$id',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resp.statusCode == 404) {
|
||||||
|
return null;
|
||||||
|
} else if (resp.statusCode != 200) {
|
||||||
|
throw RequestException(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Event.fromJson(resp.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<(List<Event>, int)?> fetchRemoteEvents(
|
||||||
|
Channel channel,
|
||||||
|
String scope, {
|
||||||
|
required int depth,
|
||||||
|
bool Function(List<Event> items)? onBrake,
|
||||||
|
take = 10,
|
||||||
|
offset = 0,
|
||||||
|
}) async {
|
||||||
|
if (depth <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final AuthProvider auth = Get.find();
|
||||||
|
if (auth.isAuthorized.isFalse) return null;
|
||||||
|
|
||||||
|
final client = auth.configureClient('messaging');
|
||||||
|
|
||||||
|
final resp = await client.get(
|
||||||
|
'/channels/$scope/${channel.alias}/events?take=$take&offset=$offset',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resp.statusCode != 200) {
|
||||||
|
throw RequestException(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
final PaginationResult response = PaginationResult.fromJson(resp.body);
|
||||||
|
final result =
|
||||||
|
response.data?.map((e) => Event.fromJson(e)).toList() ?? List.empty();
|
||||||
|
|
||||||
|
if (onBrake != null && onBrake(result)) {
|
||||||
|
return (result, response.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
final expandResult = (await fetchRemoteEvents(
|
||||||
|
channel,
|
||||||
|
scope,
|
||||||
|
depth: depth - 1,
|
||||||
|
take: take,
|
||||||
|
offset: offset + result.length,
|
||||||
|
))
|
||||||
|
?.$1 ??
|
||||||
|
List.empty();
|
||||||
|
|
||||||
|
return ([...result, ...expandResult], response.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<LocalMessageEventTableData> receiveEvent(Event remote) async {
|
||||||
|
// Insert record
|
||||||
|
final database = Get.find<DatabaseProvider>().database;
|
||||||
|
final entry = await database
|
||||||
|
.into(database.localMessageEventTable)
|
||||||
|
.insertReturning(LocalMessageEventTableCompanion.insert(
|
||||||
|
id: Value(remote.id),
|
||||||
|
channelId: remote.channelId,
|
||||||
|
data: remote,
|
||||||
|
createdAt: Value(remote.createdAt),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Handle side-effect like editing and deleting
|
||||||
|
switch (remote.type) {
|
||||||
|
case 'messages.edit':
|
||||||
|
final body = EventMessageBody.fromJson(remote.body);
|
||||||
|
if (body.relatedEvent != null) {
|
||||||
|
final target = await (database.select(database.localMessageEventTable)
|
||||||
|
..where((x) => x.id.equals(body.relatedEvent!)))
|
||||||
|
.getSingleOrNull();
|
||||||
|
if (target != null) {
|
||||||
|
target.data!.body = remote.body;
|
||||||
|
target.data!.updatedAt = remote.updatedAt;
|
||||||
|
await (database.update(database.localMessageEventTable)
|
||||||
|
..where((x) => x.id.equals(target.id)))
|
||||||
|
.write(
|
||||||
|
LocalMessageEventTableCompanion(data: Value(target.data)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'messages.delete':
|
||||||
|
final body = EventMessageBody.fromJson(remote.body);
|
||||||
|
if (body.relatedEvent != null) {
|
||||||
|
await (database.delete(database.localMessageEventTable)
|
||||||
|
..where((x) => x.id.equals(body.relatedEvent!)))
|
||||||
|
.go();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<LocalMessageEventTableData?> getEvent(int id, Channel channel,
|
||||||
|
{String scope = 'global'}) async {
|
||||||
|
final database = Get.find<DatabaseProvider>().database;
|
||||||
|
final localRecord = await (database.select(database.localMessageEventTable)
|
||||||
|
..where((x) => x.id.equals(id)))
|
||||||
|
.getSingleOrNull();
|
||||||
|
if (localRecord != null) return localRecord;
|
||||||
|
|
||||||
|
final remoteRecord = await fetchRemoteEvent(id, channel, scope);
|
||||||
|
if (remoteRecord == null) return null;
|
||||||
|
|
||||||
|
return await receiveEvent(remoteRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pull the remote events to local database
|
||||||
|
Future<(List<Event>, int)?> pullRemoteEvents(Channel channel,
|
||||||
|
{String scope = 'global', depth = 10, offset = 0}) async {
|
||||||
|
final database = Get.find<DatabaseProvider>().database;
|
||||||
|
final lastOne = await (database.select(database.localMessageEventTable)
|
||||||
|
..where((x) => x.channelId.equals(channel.id))
|
||||||
|
..orderBy([(t) => OrderingTerm.desc(t.id)])
|
||||||
|
..limit(1))
|
||||||
|
.getSingleOrNull();
|
||||||
|
|
||||||
|
final data = await fetchRemoteEvents(
|
||||||
|
channel,
|
||||||
|
scope,
|
||||||
|
depth: depth,
|
||||||
|
offset: offset,
|
||||||
|
onBrake: (items) {
|
||||||
|
return items.any((x) => x.id == lastOne?.id);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (data != null) {
|
||||||
|
await database.batch((batch) {
|
||||||
|
batch.insertAllOnConflictUpdate(
|
||||||
|
database.localMessageEventTable,
|
||||||
|
data.$1.map((x) => LocalMessageEventTableCompanion(
|
||||||
|
id: Value(x.id),
|
||||||
|
channelId: Value(x.channelId),
|
||||||
|
data: Value(x),
|
||||||
|
createdAt: Value(x.createdAt),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<LocalMessageEventTableData>> listEvents(Channel channel) async {
|
||||||
|
final database = Get.find<DatabaseProvider>().database;
|
||||||
|
return await (database.select(database.localMessageEventTable)
|
||||||
|
..where((x) => x.channelId.equals(channel.id))
|
||||||
|
..orderBy([(t) => OrderingTerm.desc(t.id)]))
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<LocalMessageEventTableData?> getLastInChannel(Channel channel) async {
|
||||||
|
final database = Get.find<DatabaseProvider>().database;
|
||||||
|
return await (database.select(database.localMessageEventTable)
|
||||||
|
..where((x) => x.channelId.equals(channel.id))
|
||||||
|
..orderBy([(t) => OrderingTerm.desc(t.id)]))
|
||||||
|
.getSingleOrNull();
|
||||||
|
}
|
||||||
|
}
|
13
lib/providers/database/tables/json.dart
Normal file
13
lib/providers/database/tables/json.dart
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
|
||||||
|
class JsonConverter extends TypeConverter<Object?, String> {
|
||||||
|
const JsonConverter();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Object? fromSql(String fromDb) => jsonDecode(fromDb);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toSql(Object? value) => jsonEncode(value);
|
||||||
|
}
|
22
lib/providers/database/tables/messages.dart
Normal file
22
lib/providers/database/tables/messages.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:solian/models/event.dart';
|
||||||
|
|
||||||
|
class LocalMessageEventTable extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
IntColumn get channelId => integer()();
|
||||||
|
TextColumn get data => text().map(const MessageEventConverter())();
|
||||||
|
DateTimeColumn get createdAt =>
|
||||||
|
dateTime().withDefault(Constant(DateTime.now()))();
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageEventConverter extends TypeConverter<Event?, String> {
|
||||||
|
const MessageEventConverter();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Event? fromSql(String fromDb) => Event.fromJson(jsonDecode(fromDb));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toSql(Event? value) => jsonEncode(value?.toJson());
|
||||||
|
}
|
@ -1,173 +0,0 @@
|
|||||||
import 'package:floor/floor.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:solian/exceptions/request.dart';
|
|
||||||
import 'package:solian/models/channel.dart';
|
|
||||||
import 'package:solian/models/event.dart';
|
|
||||||
import 'package:solian/models/pagination.dart';
|
|
||||||
import 'package:solian/providers/auth.dart';
|
|
||||||
import 'package:solian/providers/message/events.dart';
|
|
||||||
|
|
||||||
Future<MessageHistoryDb> createHistoryDb() async {
|
|
||||||
final migration1to2 = Migration(1, 2, (database) async {
|
|
||||||
await database.execute('DROP TABLE IF EXISTS LocalMessage');
|
|
||||||
});
|
|
||||||
|
|
||||||
return await $FloorMessageHistoryDb
|
|
||||||
.databaseBuilder('messaging_data.dart')
|
|
||||||
.addMigrations([migration1to2]).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<(List<Event>, int)?> getWhatsNewEvents(int pivot, {take = 10}) async {
|
|
||||||
final AuthProvider auth = Get.find();
|
|
||||||
if (auth.isAuthorized.isFalse) return null;
|
|
||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
|
||||||
|
|
||||||
final resp = await client.get(
|
|
||||||
'/whats-new?pivot=$pivot&take=$take',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (resp.statusCode != 200) {
|
|
||||||
throw RequestException(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
final PaginationResult response = PaginationResult.fromJson(resp.body);
|
|
||||||
final result =
|
|
||||||
response.data?.map((e) => Event.fromJson(e)).toList() ?? List.empty();
|
|
||||||
|
|
||||||
return (result, response.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Event?> getRemoteEvent(int id, Channel channel, String scope) async {
|
|
||||||
final AuthProvider auth = Get.find();
|
|
||||||
if (auth.isAuthorized.isFalse) return null;
|
|
||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
|
||||||
|
|
||||||
final resp = await client.get(
|
|
||||||
'/channels/$scope/${channel.alias}/events/$id',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (resp.statusCode == 404) {
|
|
||||||
return null;
|
|
||||||
} else if (resp.statusCode != 200) {
|
|
||||||
throw RequestException(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Event.fromJson(resp.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<(List<Event>, int)?> getRemoteEvents(
|
|
||||||
Channel channel,
|
|
||||||
String scope, {
|
|
||||||
required int remainDepth,
|
|
||||||
bool Function(List<Event> items)? onBrake,
|
|
||||||
take = 10,
|
|
||||||
offset = 0,
|
|
||||||
}) async {
|
|
||||||
if (remainDepth <= 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final AuthProvider auth = Get.find();
|
|
||||||
if (auth.isAuthorized.isFalse) return null;
|
|
||||||
|
|
||||||
final client = auth.configureClient('messaging');
|
|
||||||
|
|
||||||
final resp = await client.get(
|
|
||||||
'/channels/$scope/${channel.alias}/events?take=$take&offset=$offset',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (resp.statusCode != 200) {
|
|
||||||
throw RequestException(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
final PaginationResult response = PaginationResult.fromJson(resp.body);
|
|
||||||
final result =
|
|
||||||
response.data?.map((e) => Event.fromJson(e)).toList() ?? List.empty();
|
|
||||||
|
|
||||||
if (onBrake != null && onBrake(result)) {
|
|
||||||
return (result, response.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
final expandResult = (await getRemoteEvents(
|
|
||||||
channel,
|
|
||||||
scope,
|
|
||||||
remainDepth: remainDepth - 1,
|
|
||||||
take: take,
|
|
||||||
offset: offset + result.length,
|
|
||||||
))
|
|
||||||
?.$1 ??
|
|
||||||
List.empty();
|
|
||||||
|
|
||||||
return ([...result, ...expandResult], response.count);
|
|
||||||
}
|
|
||||||
|
|
||||||
extension MessageHistoryAdaptor on MessageHistoryDb {
|
|
||||||
Future<LocalEvent> receiveEvent(Event remote) async {
|
|
||||||
final entry = LocalEvent(
|
|
||||||
remote.id,
|
|
||||||
remote,
|
|
||||||
remote.channelId,
|
|
||||||
remote.createdAt,
|
|
||||||
);
|
|
||||||
await localEvents.insert(entry);
|
|
||||||
switch (remote.type) {
|
|
||||||
case 'messages.edit':
|
|
||||||
final body = EventMessageBody.fromJson(remote.body);
|
|
||||||
if (body.relatedEvent != null) {
|
|
||||||
final target = await localEvents.findById(body.relatedEvent!);
|
|
||||||
if (target != null) {
|
|
||||||
target.data.body = remote.body;
|
|
||||||
target.data.updatedAt = remote.updatedAt;
|
|
||||||
await localEvents.update(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 'messages.delete':
|
|
||||||
final body = EventMessageBody.fromJson(remote.body);
|
|
||||||
if (body.relatedEvent != null) {
|
|
||||||
await localEvents.delete(body.relatedEvent!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<LocalEvent?> getEvent(int id, Channel channel,
|
|
||||||
{String scope = 'global'}) async {
|
|
||||||
final localRecord = await localEvents.findById(id);
|
|
||||||
if (localRecord != null) return localRecord;
|
|
||||||
|
|
||||||
final remoteRecord = await getRemoteEvent(id, channel, scope);
|
|
||||||
if (remoteRecord == null) return null;
|
|
||||||
|
|
||||||
return await receiveEvent(remoteRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<(List<Event>, int)?> syncRemoteEvents(Channel channel,
|
|
||||||
{String scope = 'global', depth = 10, offset = 0}) async {
|
|
||||||
final lastOne = await localEvents.findLastByChannel(channel.id);
|
|
||||||
|
|
||||||
final data = await getRemoteEvents(
|
|
||||||
channel,
|
|
||||||
scope,
|
|
||||||
remainDepth: depth,
|
|
||||||
offset: offset,
|
|
||||||
onBrake: (items) {
|
|
||||||
return items.any((x) => x.id == lastOne?.id);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (data != null) {
|
|
||||||
await localEvents.insertBulk(
|
|
||||||
data.$1
|
|
||||||
.map((x) => LocalEvent(x.id, x, x.channelId, x.createdAt))
|
|
||||||
.toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<LocalEvent>> listEvents(Channel channel) async {
|
|
||||||
return await localEvents.findAllByChannel(channel.id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:floor/floor.dart';
|
|
||||||
import 'package:solian/models/event.dart';
|
|
||||||
import 'package:sqflite/sqflite.dart' as sqflite;
|
|
||||||
|
|
||||||
part 'events.g.dart';
|
|
||||||
|
|
||||||
@entity
|
|
||||||
class LocalEvent {
|
|
||||||
@primaryKey
|
|
||||||
final int id;
|
|
||||||
|
|
||||||
final Event data;
|
|
||||||
final int channelId;
|
|
||||||
|
|
||||||
final DateTime createdAt;
|
|
||||||
|
|
||||||
LocalEvent(this.id, this.data, this.channelId, this.createdAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
class DateTimeConverter extends TypeConverter<DateTime, int> {
|
|
||||||
@override
|
|
||||||
DateTime decode(int databaseValue) {
|
|
||||||
return DateTime.fromMillisecondsSinceEpoch(databaseValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int encode(DateTime value) {
|
|
||||||
return value.millisecondsSinceEpoch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RemoteEventConverter extends TypeConverter<Event, String> {
|
|
||||||
@override
|
|
||||||
Event decode(String databaseValue) {
|
|
||||||
return Event.fromJson(jsonDecode(databaseValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String encode(Event value) {
|
|
||||||
return jsonEncode(value.toJson());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@dao
|
|
||||||
abstract class LocalEventDao {
|
|
||||||
@Query('SELECT COUNT(id) FROM LocalEvent WHERE channelId = :channelId')
|
|
||||||
Future<int?> countByChannel(int channelId);
|
|
||||||
|
|
||||||
@Query('SELECT * FROM LocalEvent WHERE id = :id')
|
|
||||||
Future<LocalEvent?> findById(int id);
|
|
||||||
|
|
||||||
@Query('SELECT * FROM LocalEvent WHERE channelId = :channelId ORDER BY createdAt DESC')
|
|
||||||
Future<List<LocalEvent>> findAllByChannel(int channelId);
|
|
||||||
|
|
||||||
@Query('SELECT * FROM LocalEvent WHERE channelId = :channelId ORDER BY createdAt DESC LIMIT 1')
|
|
||||||
Future<LocalEvent?> findLastByChannel(int channelId);
|
|
||||||
|
|
||||||
@Insert(onConflict: OnConflictStrategy.replace)
|
|
||||||
Future<void> insert(LocalEvent m);
|
|
||||||
|
|
||||||
@Insert(onConflict: OnConflictStrategy.replace)
|
|
||||||
Future<void> insertBulk(List<LocalEvent> m);
|
|
||||||
|
|
||||||
@Update(onConflict: OnConflictStrategy.replace)
|
|
||||||
Future<void> update(LocalEvent m);
|
|
||||||
|
|
||||||
@Query('DELETE FROM LocalEvent WHERE id = :id')
|
|
||||||
Future<void> delete(int id);
|
|
||||||
|
|
||||||
@Query('DELETE FROM LocalEvent WHERE channelId = :channelId')
|
|
||||||
Future<List<LocalEvent>> deleteByChannel(int channelId);
|
|
||||||
|
|
||||||
@Query('DELETE FROM LocalEvent')
|
|
||||||
Future<void> wipeLocalEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
@TypeConverters([DateTimeConverter, RemoteEventConverter])
|
|
||||||
@Database(version: 2, entities: [LocalEvent])
|
|
||||||
abstract class MessageHistoryDb extends FloorDatabase {
|
|
||||||
LocalEventDao get localEvents;
|
|
||||||
}
|
|
@ -1,228 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'events.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FloorGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
abstract class $MessageHistoryDbBuilderContract {
|
|
||||||
/// Adds migrations to the builder.
|
|
||||||
$MessageHistoryDbBuilderContract addMigrations(List<Migration> migrations);
|
|
||||||
|
|
||||||
/// Adds a database [Callback] to the builder.
|
|
||||||
$MessageHistoryDbBuilderContract addCallback(Callback callback);
|
|
||||||
|
|
||||||
/// Creates the database and initializes it.
|
|
||||||
Future<MessageHistoryDb> build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore: avoid_classes_with_only_static_members
|
|
||||||
class $FloorMessageHistoryDb {
|
|
||||||
/// Creates a database builder for a persistent database.
|
|
||||||
/// Once a database is built, you should keep a reference to it and re-use it.
|
|
||||||
static $MessageHistoryDbBuilderContract databaseBuilder(String name) =>
|
|
||||||
_$MessageHistoryDbBuilder(name);
|
|
||||||
|
|
||||||
/// Creates a database builder for an in memory database.
|
|
||||||
/// Information stored in an in memory database disappears when the process is killed.
|
|
||||||
/// Once a database is built, you should keep a reference to it and re-use it.
|
|
||||||
static $MessageHistoryDbBuilderContract inMemoryDatabaseBuilder() =>
|
|
||||||
_$MessageHistoryDbBuilder(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _$MessageHistoryDbBuilder implements $MessageHistoryDbBuilderContract {
|
|
||||||
_$MessageHistoryDbBuilder(this.name);
|
|
||||||
|
|
||||||
final String? name;
|
|
||||||
|
|
||||||
final List<Migration> _migrations = [];
|
|
||||||
|
|
||||||
Callback? _callback;
|
|
||||||
|
|
||||||
@override
|
|
||||||
$MessageHistoryDbBuilderContract addMigrations(List<Migration> migrations) {
|
|
||||||
_migrations.addAll(migrations);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
$MessageHistoryDbBuilderContract addCallback(Callback callback) {
|
|
||||||
_callback = callback;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<MessageHistoryDb> build() async {
|
|
||||||
final path = name != null
|
|
||||||
? await sqfliteDatabaseFactory.getDatabasePath(name!)
|
|
||||||
: ':memory:';
|
|
||||||
final database = _$MessageHistoryDb();
|
|
||||||
database.database = await database.open(
|
|
||||||
path,
|
|
||||||
_migrations,
|
|
||||||
_callback,
|
|
||||||
);
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _$MessageHistoryDb extends MessageHistoryDb {
|
|
||||||
_$MessageHistoryDb([StreamController<String>? listener]) {
|
|
||||||
changeListener = listener ?? StreamController<String>.broadcast();
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalEventDao? _localEventsInstance;
|
|
||||||
|
|
||||||
Future<sqflite.Database> open(
|
|
||||||
String path,
|
|
||||||
List<Migration> migrations, [
|
|
||||||
Callback? callback,
|
|
||||||
]) async {
|
|
||||||
final databaseOptions = sqflite.OpenDatabaseOptions(
|
|
||||||
version: 2,
|
|
||||||
onConfigure: (database) async {
|
|
||||||
await database.execute('PRAGMA foreign_keys = ON');
|
|
||||||
await callback?.onConfigure?.call(database);
|
|
||||||
},
|
|
||||||
onOpen: (database) async {
|
|
||||||
await callback?.onOpen?.call(database);
|
|
||||||
},
|
|
||||||
onUpgrade: (database, startVersion, endVersion) async {
|
|
||||||
await MigrationAdapter.runMigrations(
|
|
||||||
database, startVersion, endVersion, migrations);
|
|
||||||
|
|
||||||
await callback?.onUpgrade?.call(database, startVersion, endVersion);
|
|
||||||
},
|
|
||||||
onCreate: (database, version) async {
|
|
||||||
await database.execute(
|
|
||||||
'CREATE TABLE IF NOT EXISTS `LocalEvent` (`id` INTEGER NOT NULL, `data` TEXT NOT NULL, `channelId` INTEGER NOT NULL, `createdAt` INTEGER NOT NULL, PRIMARY KEY (`id`))');
|
|
||||||
|
|
||||||
await callback?.onCreate?.call(database, version);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
LocalEventDao get localEvents {
|
|
||||||
return _localEventsInstance ??= _$LocalEventDao(database, changeListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _$LocalEventDao extends LocalEventDao {
|
|
||||||
_$LocalEventDao(
|
|
||||||
this.database,
|
|
||||||
this.changeListener,
|
|
||||||
) : _queryAdapter = QueryAdapter(database),
|
|
||||||
_localEventInsertionAdapter = InsertionAdapter(
|
|
||||||
database,
|
|
||||||
'LocalEvent',
|
|
||||||
(LocalEvent item) => <String, Object?>{
|
|
||||||
'id': item.id,
|
|
||||||
'data': _remoteEventConverter.encode(item.data),
|
|
||||||
'channelId': item.channelId,
|
|
||||||
'createdAt': _dateTimeConverter.encode(item.createdAt)
|
|
||||||
}),
|
|
||||||
_localEventUpdateAdapter = UpdateAdapter(
|
|
||||||
database,
|
|
||||||
'LocalEvent',
|
|
||||||
['id'],
|
|
||||||
(LocalEvent item) => <String, Object?>{
|
|
||||||
'id': item.id,
|
|
||||||
'data': _remoteEventConverter.encode(item.data),
|
|
||||||
'channelId': item.channelId,
|
|
||||||
'createdAt': _dateTimeConverter.encode(item.createdAt)
|
|
||||||
});
|
|
||||||
|
|
||||||
final sqflite.DatabaseExecutor database;
|
|
||||||
|
|
||||||
final StreamController<String> changeListener;
|
|
||||||
|
|
||||||
final QueryAdapter _queryAdapter;
|
|
||||||
|
|
||||||
final InsertionAdapter<LocalEvent> _localEventInsertionAdapter;
|
|
||||||
|
|
||||||
final UpdateAdapter<LocalEvent> _localEventUpdateAdapter;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<int?> countByChannel(int channelId) async {
|
|
||||||
return _queryAdapter.query(
|
|
||||||
'SELECT COUNT(id) FROM LocalEvent WHERE channelId = ?1',
|
|
||||||
mapper: (Map<String, Object?> row) => row.values.first as int,
|
|
||||||
arguments: [channelId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<LocalEvent?> findById(int id) async {
|
|
||||||
return _queryAdapter.query('SELECT * FROM LocalEvent WHERE id = ?1',
|
|
||||||
mapper: (Map<String, Object?> row) => LocalEvent(
|
|
||||||
row['id'] as int,
|
|
||||||
_remoteEventConverter.decode(row['data'] as String),
|
|
||||||
row['channelId'] as int,
|
|
||||||
_dateTimeConverter.decode(row['createdAt'] as int)),
|
|
||||||
arguments: [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<LocalEvent>> findAllByChannel(int channelId) async {
|
|
||||||
return _queryAdapter.queryList(
|
|
||||||
'SELECT * FROM LocalEvent WHERE channelId = ?1 ORDER BY createdAt DESC',
|
|
||||||
mapper: (Map<String, Object?> row) => LocalEvent(
|
|
||||||
row['id'] as int,
|
|
||||||
_remoteEventConverter.decode(row['data'] as String),
|
|
||||||
row['channelId'] as int,
|
|
||||||
_dateTimeConverter.decode(row['createdAt'] as int)),
|
|
||||||
arguments: [channelId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<LocalEvent?> findLastByChannel(int channelId) async {
|
|
||||||
return _queryAdapter.query(
|
|
||||||
'SELECT * FROM LocalEvent WHERE channelId = ?1 ORDER BY createdAt DESC LIMIT 1',
|
|
||||||
mapper: (Map<String, Object?> row) => LocalEvent(row['id'] as int, _remoteEventConverter.decode(row['data'] as String), row['channelId'] as int, _dateTimeConverter.decode(row['createdAt'] as int)),
|
|
||||||
arguments: [channelId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> delete(int id) async {
|
|
||||||
await _queryAdapter
|
|
||||||
.queryNoReturn('DELETE FROM LocalEvent WHERE id = ?1', arguments: [id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<LocalEvent>> deleteByChannel(int channelId) async {
|
|
||||||
return _queryAdapter.queryList(
|
|
||||||
'DELETE FROM LocalEvent WHERE channelId = ?1',
|
|
||||||
mapper: (Map<String, Object?> row) => LocalEvent(
|
|
||||||
row['id'] as int,
|
|
||||||
_remoteEventConverter.decode(row['data'] as String),
|
|
||||||
row['channelId'] as int,
|
|
||||||
_dateTimeConverter.decode(row['createdAt'] as int)),
|
|
||||||
arguments: [channelId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> wipeLocalEvents() async {
|
|
||||||
await _queryAdapter.queryNoReturn('DELETE FROM LocalEvent');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> insert(LocalEvent m) async {
|
|
||||||
await _localEventInsertionAdapter.insert(m, OnConflictStrategy.replace);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> insertBulk(List<LocalEvent> m) async {
|
|
||||||
await _localEventInsertionAdapter.insertList(m, OnConflictStrategy.replace);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> update(LocalEvent m) async {
|
|
||||||
await _localEventUpdateAdapter.update(m, OnConflictStrategy.replace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore_for_file: unused_element
|
|
||||||
final _dateTimeConverter = DateTimeConverter();
|
|
||||||
final _remoteEventConverter = RemoteEventConverter();
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:solian/controllers/chat_events_controller.dart';
|
import 'package:solian/controllers/chat_events_controller.dart';
|
||||||
import 'package:solian/exts.dart';
|
import 'package:solian/exts.dart';
|
||||||
@ -156,7 +155,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen>
|
|||||||
|
|
||||||
void _keepUpdateWithServer() {
|
void _keepUpdateWithServer() {
|
||||||
_getOngoingCall();
|
_getOngoingCall();
|
||||||
_chatController.getEvents(_channel!, widget.realm);
|
_chatController.getInitialEvents(_channel!, widget.realm);
|
||||||
setState(() => _isOutOfSyncSince = null);
|
setState(() => _isOutOfSyncSince = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ class _ChannelChatScreenState extends State<ChannelChatScreen>
|
|||||||
|
|
||||||
_getOngoingCall();
|
_getOngoingCall();
|
||||||
_getChannel().then((_) {
|
_getChannel().then((_) {
|
||||||
_chatController.getEvents(_channel!, widget.realm);
|
_chatController.getInitialEvents(_channel!, widget.realm);
|
||||||
_listenMessages();
|
_listenMessages();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -295,13 +294,6 @@ class _ChannelChatScreenState extends State<ChannelChatScreen>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Obx(() {
|
|
||||||
if (_chatController.isLoading.isTrue) {
|
|
||||||
return const LinearProgressIndicator().animate().slideY();
|
|
||||||
} else {
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
ClipRect(
|
ClipRect(
|
||||||
child: BackdropFilter(
|
child: BackdropFilter(
|
||||||
filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50),
|
filter: ImageFilter.blur(sigmaX: 50, sigmaY: 50),
|
||||||
|
@ -18,8 +18,8 @@ import 'package:solian/models/post.dart';
|
|||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/providers/content/posts.dart';
|
import 'package:solian/providers/content/posts.dart';
|
||||||
import 'package:solian/providers/daily_sign.dart';
|
import 'package:solian/providers/daily_sign.dart';
|
||||||
|
import 'package:solian/providers/database/services/messages.dart';
|
||||||
import 'package:solian/providers/last_read.dart';
|
import 'package:solian/providers/last_read.dart';
|
||||||
import 'package:solian/providers/message/adaptor.dart';
|
|
||||||
import 'package:solian/providers/websocket.dart';
|
import 'package:solian/providers/websocket.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
import 'package:solian/screens/account/notification.dart';
|
import 'package:solian/screens/account/notification.dart';
|
||||||
@ -72,7 +72,8 @@ class _DashboardScreenState extends State<DashboardScreen> {
|
|||||||
Future<void> _pullMessages() async {
|
Future<void> _pullMessages() async {
|
||||||
if (_lastRead.messagesLastReadAt == null) return;
|
if (_lastRead.messagesLastReadAt == null) return;
|
||||||
log('[Dashboard] Pulling messages with pivot: ${_lastRead.messagesLastReadAt}');
|
log('[Dashboard] Pulling messages with pivot: ${_lastRead.messagesLastReadAt}');
|
||||||
final out = await getWhatsNewEvents(_lastRead.messagesLastReadAt!);
|
final src = Get.find<MessagesFetchingProvider>();
|
||||||
|
final out = await src.getWhatsNewEvents(_lastRead.messagesLastReadAt!);
|
||||||
if (out == null) return;
|
if (out == null) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
_currentMessages = out.$1;
|
_currentMessages = out.$1;
|
||||||
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:solian/controllers/chat_events_controller.dart';
|
|
||||||
import 'package:solian/exts.dart';
|
import 'package:solian/exts.dart';
|
||||||
import 'package:solian/providers/theme_switcher.dart';
|
import 'package:solian/providers/theme_switcher.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
@ -97,10 +96,7 @@ class _SettingScreenState extends State<SettingScreen> {
|
|||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 22),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 22),
|
||||||
title: Text('messageHistoryWipe'.tr),
|
title: Text('messageHistoryWipe'.tr),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
final chatHistory = ChatEventController();
|
// TODO Wipe message history
|
||||||
chatHistory.initialize().then((_) async {
|
|
||||||
await chatHistory.database.localEvents.wipeLocalEvents();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -105,7 +105,7 @@ class _ChannelListWidgetState extends State<ChannelListWidget> {
|
|||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: Future.delayed(
|
future: Future.delayed(
|
||||||
const Duration(milliseconds: 500),
|
const Duration(milliseconds: 500),
|
||||||
() => _eventController.database.localEvents.findLastByChannel(item.id),
|
() => _eventController.src.getLastInChannel(item),
|
||||||
),
|
),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (!snapshot.hasData && snapshot.data == null) {
|
if (!snapshot.hasData && snapshot.data == null) {
|
||||||
@ -114,8 +114,9 @@ class _ChannelListWidgetState extends State<ChannelListWidget> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final data = snapshot.data!.data!;
|
||||||
return Text(
|
return Text(
|
||||||
'${snapshot.data!.data.sender.account.nick}: ${snapshot.data!.data.body['text'] ?? 'Unsupported message to preview'}',
|
'${data.sender.account.nick}: ${data.body['text'] ?? 'Unsupported message to preview'}',
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
);
|
);
|
||||||
|
@ -97,7 +97,7 @@ class ChatEvent extends StatelessWidget {
|
|||||||
return Container(
|
return Container(
|
||||||
constraints: const BoxConstraints(maxWidth: 480),
|
constraints: const BoxConstraints(maxWidth: 480),
|
||||||
child: ChatEvent(
|
child: ChatEvent(
|
||||||
item: snapshot.data!.data,
|
item: snapshot.data!.data!,
|
||||||
isMerged: false,
|
isMerged: false,
|
||||||
isQuote: true,
|
isQuote: true,
|
||||||
),
|
),
|
||||||
|
@ -6,6 +6,7 @@ import 'package:solian/models/event.dart';
|
|||||||
import 'package:solian/providers/last_read.dart';
|
import 'package:solian/providers/last_read.dart';
|
||||||
import 'package:solian/widgets/chat/chat_event.dart';
|
import 'package:solian/widgets/chat/chat_event.dart';
|
||||||
import 'package:solian/widgets/chat/chat_event_action.dart';
|
import 'package:solian/widgets/chat/chat_event_action.dart';
|
||||||
|
import 'package:very_good_infinite_list/very_good_infinite_list.dart';
|
||||||
|
|
||||||
class ChatEventList extends StatelessWidget {
|
class ChatEventList extends StatelessWidget {
|
||||||
final String scope;
|
final String scope;
|
||||||
@ -36,8 +37,9 @@ class ChatEventList extends StatelessWidget {
|
|||||||
reverse: true,
|
reverse: true,
|
||||||
slivers: [
|
slivers: [
|
||||||
Obx(() {
|
Obx(() {
|
||||||
return SliverList.builder(
|
return SliverInfiniteList(
|
||||||
key: Key('chat-history#${channel.id}'),
|
key: Key('chat-history#${channel.id}'),
|
||||||
|
isLoading: chatController.isLoading.value,
|
||||||
itemCount: chatController.currentEvents.length,
|
itemCount: chatController.currentEvents.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
Get.find<LastReadProvider>().messagesLastReadAt =
|
Get.find<LastReadProvider>().messagesLastReadAt =
|
||||||
@ -62,7 +64,7 @@ class ChatEventList extends StatelessWidget {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: ChatEvent(
|
child: ChatEvent(
|
||||||
key: Key('m${item.uuid}'),
|
key: Key('m${item!.uuid}'),
|
||||||
item: item,
|
item: item,
|
||||||
isMerged: isMerged,
|
isMerged: isMerged,
|
||||||
chatController: chatController,
|
chatController: chatController,
|
||||||
@ -89,28 +91,12 @@ class ChatEventList extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
onFetchData: () {
|
||||||
}),
|
chatController.loadEvents(
|
||||||
Obx(() {
|
chatController.channel!,
|
||||||
final amount =
|
chatController.scope!,
|
||||||
chatController.totalEvents - chatController.currentEvents.length;
|
);
|
||||||
|
},
|
||||||
if (amount.value <= 0 || chatController.isLoading.isTrue) {
|
|
||||||
return const SliverToBoxAdapter(child: SizedBox.shrink());
|
|
||||||
}
|
|
||||||
|
|
||||||
return SliverToBoxAdapter(
|
|
||||||
child: ListTile(
|
|
||||||
tileColor: Theme.of(context).colorScheme.surfaceContainerLow,
|
|
||||||
leading: const Icon(Icons.sync_disabled),
|
|
||||||
title: Text('messageUnSync'.tr),
|
|
||||||
subtitle: Text('messageUnSyncCaption'.trParams({
|
|
||||||
'count': amount.string,
|
|
||||||
})),
|
|
||||||
onTap: () {
|
|
||||||
chatController.loadEvents(channel, scope);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
||||||
#include <media_kit_video/media_kit_video_plugin.h>
|
#include <media_kit_video/media_kit_video_plugin.h>
|
||||||
#include <pasteboard/pasteboard_plugin.h>
|
#include <pasteboard/pasteboard_plugin.h>
|
||||||
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
@ -41,6 +42,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||||||
g_autoptr(FlPluginRegistrar) pasteboard_registrar =
|
g_autoptr(FlPluginRegistrar) pasteboard_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
|
||||||
pasteboard_plugin_register_with_registrar(pasteboard_registrar);
|
pasteboard_plugin_register_with_registrar(pasteboard_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin");
|
||||||
|
sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
|
@ -11,6 +11,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
media_kit_libs_linux
|
media_kit_libs_linux
|
||||||
media_kit_video
|
media_kit_video
|
||||||
pasteboard
|
pasteboard
|
||||||
|
sqlite3_flutter_libs
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import screen_brightness_macos
|
|||||||
import share_plus
|
import share_plus
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite
|
import sqflite
|
||||||
|
import sqlite3_flutter_libs
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
import wakelock_plus
|
import wakelock_plus
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
|
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||||
}
|
}
|
||||||
|
214
pubspec.lock
214
pubspec.lock
@ -30,6 +30,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.7.0"
|
version: "6.7.0"
|
||||||
|
analyzer_plugin:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: analyzer_plugin
|
||||||
|
sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.11.3"
|
||||||
animations:
|
animations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -162,10 +170,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cached_network_image
|
name: cached_network_image
|
||||||
sha256: "4a5d8d2c728b0f3d0245f69f921d7be90cae4c2fd5288f773088672c0893f819"
|
sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.0"
|
version: "3.4.1"
|
||||||
cached_network_image_platform_interface:
|
cached_network_image_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -178,10 +186,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cached_network_image_web
|
name: cached_network_image_web
|
||||||
sha256: "6322dde7a5ad92202e64df659241104a43db20ed594c41ca18de1014598d7996"
|
sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.1"
|
||||||
carousel_slider:
|
carousel_slider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -298,10 +306,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dart_style
|
name: dart_style
|
||||||
sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9"
|
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.6"
|
version: "2.3.7"
|
||||||
dart_webrtc:
|
dart_webrtc:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -326,14 +334,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.4"
|
version: "0.4.4"
|
||||||
dev_build:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dev_build
|
|
||||||
sha256: f526d1fbe68875f6119ffc333f114dfe6aa93ad04439276d53968f7977cc410e
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.0+11"
|
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -374,6 +374,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
drift:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: drift
|
||||||
|
sha256: "5b561ec76fff260e1e0593a29ca0d058a140a4b4dfb11dcc0c3813820cd20200"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.20.2"
|
||||||
|
drift_dev:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: drift_dev
|
||||||
|
sha256: "3ee987578ca2281b5ff91eadd757cd6dd36001458d6e33784f990d67ff38f756"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.20.3"
|
||||||
|
drift_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: drift_flutter
|
||||||
|
sha256: c670c947fe17ad149678a43fdbbfdb69321f0c83d315043e34e8ad2729e11f49
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
dropdown_button2:
|
dropdown_button2:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -466,26 +490,26 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_analytics
|
name: firebase_analytics
|
||||||
sha256: "7e032ade38dec2a92f543ba02c5f72f54ffaa095c60d2132b867eab56de3bc73"
|
sha256: "7b5ae39d853ead76f9d030dc23389bfec4ea826d7cccb4eea4873dcb0cdd172b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.3.0"
|
version: "11.3.1"
|
||||||
firebase_analytics_platform_interface:
|
firebase_analytics_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_analytics_platform_interface
|
name: firebase_analytics_platform_interface
|
||||||
sha256: b62a2444767d95067a7e36b1d6e335e0b877968574bbbfb656168c46f2e95a13
|
sha256: "0205e05bb37abd29d5dec5cd89aeb04f3f58bf849aad21dd938be0507d52a40c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.2"
|
version: "4.2.3"
|
||||||
firebase_analytics_web:
|
firebase_analytics_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_analytics_web
|
name: firebase_analytics_web
|
||||||
sha256: bad44f71f96cfca6c16c9dd4f70b85f123ddca7d5dd698977449fadf298b1782
|
sha256: "434807f8b30526e21cc062410c28ee5c6680a13626c4443b5ffede29f84b0c74"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.9+2"
|
version: "0.5.10"
|
||||||
firebase_core:
|
firebase_core:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -514,26 +538,26 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_crashlytics
|
name: firebase_crashlytics
|
||||||
sha256: "4c9872020c0d97a161362ee6af7000cfdb8666234ddc290a15252ad379bb235a"
|
sha256: c4fdbb14ba6f36794f89dc27fb5c759c9cc67ecbaeb079edc4dba515bbf9f555
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.1.1"
|
||||||
firebase_crashlytics_platform_interface:
|
firebase_crashlytics_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_crashlytics_platform_interface
|
name: firebase_crashlytics_platform_interface
|
||||||
sha256: ede8a199ff03378857d3c8cbb7fa58d37c27bb5a6b75faf8415ff6925dcaae2a
|
sha256: "891d6f7ba4b93672d0e1265f27b6a9dccd56ba2cc30ce6496586b32d1d8770ac"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.6.41"
|
version: "3.6.42"
|
||||||
firebase_messaging:
|
firebase_messaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging
|
name: firebase_messaging
|
||||||
sha256: "29941ba5a3204d80656c0e52103369aa9a53edfd9ceae05a2bb3376f24fda453"
|
sha256: cc02c4afd6510cd84586020670140c4a23fbe52af16cd260ccf8ede101bb8d1b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.1.0"
|
version: "15.1.1"
|
||||||
firebase_messaging_platform_interface:
|
firebase_messaging_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -554,26 +578,26 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_performance
|
name: firebase_performance
|
||||||
sha256: "66666f697ecdcca2616af99f8ccfa74d795e5819c598227f2784fc00b1c6e421"
|
sha256: "879ce4d83242cb7d1ec67a8b45daa351f230211778e34eeea979894839c4832a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.0+5"
|
version: "0.10.0+6"
|
||||||
firebase_performance_platform_interface:
|
firebase_performance_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_performance_platform_interface
|
name: firebase_performance_platform_interface
|
||||||
sha256: ceaa026d067347cc6ea11113ba926ae450f56e305c186d1edce78f05983b481a
|
sha256: ac68eba644f593903a931ba7f26f0677b725d5a60f8f7bc0fed01d88a11d1463
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.4+41"
|
version: "0.1.4+42"
|
||||||
firebase_performance_web:
|
firebase_performance_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_performance_web
|
name: firebase_performance_web
|
||||||
sha256: "6d121cd7e27b63995998dc4039caf0cbf304c2eee6fc6ed9ac7f80860cc0e51c"
|
sha256: ff53b9c5d8601fc983d0173b88fdfd8abcc74948f0a3753f3c1ec276b680f23c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.6+13"
|
version: "0.1.7"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -590,38 +614,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.69.0"
|
version: "0.69.0"
|
||||||
floor:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: floor
|
|
||||||
sha256: c1b06023912b5b8e49deb6a9d867863c535ae1a232d991c3582bba3ee8687867
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.0"
|
|
||||||
floor_annotation:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: floor_annotation
|
|
||||||
sha256: a40949580a7ab0eee572686e2d3b1638fd6bd6a753e661d792ab4236b365b23b
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.0"
|
|
||||||
floor_common:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: floor_common
|
|
||||||
sha256: "41c9914862f83a821815e1b1ffd47a1e1ae2130c35ff882ba2d000a67713ba64"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.0"
|
|
||||||
floor_generator:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: floor_generator
|
|
||||||
sha256: "1499b3ab878a807e6fbe6f140dc014124845cd1df3090a113aae5fa7577a1e77"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.5.0"
|
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -861,14 +853,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.7.0"
|
version: "10.7.0"
|
||||||
freezed:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: freezed
|
|
||||||
sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.5.7"
|
|
||||||
freezed_annotation:
|
freezed_annotation:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1157,14 +1141,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
lists:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lists
|
|
||||||
sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
livekit_client:
|
livekit_client:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1473,10 +1449,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_platform_interface
|
name: permission_handler_platform_interface
|
||||||
sha256: fe0ffe274d665be8e34f9c59705441a7d248edebbe5d9e3ec2665f88b79358ea
|
sha256: e9c8eadee926c4532d0305dff94b85bf961f16759c3af791486613152af4b4f9
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.2"
|
version: "4.2.3"
|
||||||
permission_handler_windows:
|
permission_handler_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1557,14 +1533,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
process_run:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: process_run
|
|
||||||
sha256: "112a77da35be50617ed9e2230df68d0817972f225e7f97ce8336f76b4e601606"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
protobuf:
|
protobuf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1645,6 +1613,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
recase:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: recase
|
||||||
|
sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
rxdart:
|
rxdart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1851,7 +1827,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.0.0"
|
||||||
sqflite:
|
sqflite:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqflite
|
name: sqflite
|
||||||
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
|
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
|
||||||
@ -1866,22 +1842,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.4+2"
|
version: "2.5.4+2"
|
||||||
sqflite_common_ffi:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: sqflite_common_ffi
|
|
||||||
sha256: "4d6137c29e930d6e4a8ff373989dd9de7bac12e3bc87bce950f6e844e8ad3bb5"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.3.3"
|
|
||||||
sqflite_common_ffi_web:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: sqflite_common_ffi_web
|
|
||||||
sha256: cfc9d1c61a3e06e5b2e96994a44b11125b4f451fee95b9fad8bd473b4613d592
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.3+1"
|
|
||||||
sqlite3:
|
sqlite3:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1890,14 +1850,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.6"
|
version: "2.4.6"
|
||||||
|
sqlite3_flutter_libs:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqlite3_flutter_libs
|
||||||
|
sha256: "62bbb4073edbcdf53f40c80775f33eea01d301b7b81417e5b3fb7395416258c1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.24"
|
||||||
sqlparser:
|
sqlparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqlparser
|
name: sqlparser
|
||||||
sha256: "7b20045d1ccfb7bc1df7e8f9fee5ae58673fce6ff62cefbb0e0fd7214e90e5a0"
|
sha256: "852cf80f9e974ac8e1b613758a8aa640215f7701352b66a7f468e95711eb570b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.34.1"
|
version: "0.38.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1930,14 +1898,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
strings:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: strings
|
|
||||||
sha256: "052836499f03897d3860a603b330c1ea3c8a14177b21f34b15a1295f36024aae"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "3.1.2"
|
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1986,14 +1946,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.2"
|
||||||
unicode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: unicode
|
|
||||||
sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.1"
|
|
||||||
universal_io:
|
universal_io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -2122,6 +2074,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
|
very_good_infinite_list:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: very_good_infinite_list
|
||||||
|
sha256: "03445e302f9e0878b6b429c096825463e0990dd38fa69a3c5c74c646afd0e485"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.0"
|
||||||
vm_service:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -2206,10 +2166,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32_registry
|
name: win32_registry
|
||||||
sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6"
|
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.4"
|
version: "1.1.5"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
10
pubspec.yaml
10
pubspec.yaml
@ -40,8 +40,6 @@ dependencies:
|
|||||||
package_info_plus: ^8.0.0
|
package_info_plus: ^8.0.0
|
||||||
device_info_plus: ^10.1.0
|
device_info_plus: ^10.1.0
|
||||||
flutter_acrylic: ^1.1.4
|
flutter_acrylic: ^1.1.4
|
||||||
floor: ^1.5.0
|
|
||||||
sqflite: ^2.3.3+1
|
|
||||||
protocol_handler: ^0.2.0
|
protocol_handler: ^0.2.0
|
||||||
markdown: ^7.2.2
|
markdown: ^7.2.2
|
||||||
pasteboard: ^0.3.0
|
pasteboard: ^0.3.0
|
||||||
@ -77,6 +75,9 @@ dependencies:
|
|||||||
media_kit: ^1.1.11
|
media_kit: ^1.1.11
|
||||||
media_kit_video: ^1.2.5
|
media_kit_video: ^1.2.5
|
||||||
media_kit_libs_video: ^1.0.5
|
media_kit_libs_video: ^1.0.5
|
||||||
|
drift: ^2.20.2
|
||||||
|
drift_flutter: ^0.2.0
|
||||||
|
very_good_infinite_list: ^0.8.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -85,13 +86,10 @@ dev_dependencies:
|
|||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^4.0.0
|
||||||
flutter_launcher_icons: ^0.13.1
|
flutter_launcher_icons: ^0.13.1
|
||||||
|
|
||||||
floor_generator: ^1.4.0
|
|
||||||
build_runner: ^2.4.12
|
build_runner: ^2.4.12
|
||||||
sqflite_common_ffi: ^2.3.3
|
|
||||||
sqflite_common_ffi_web: ^0.4.3+1
|
|
||||||
flutter_native_splash: ^2.4.1
|
flutter_native_splash: ^2.4.1
|
||||||
freezed: ^2.5.7
|
|
||||||
json_serializable: ^6.8.0
|
json_serializable: ^6.8.0
|
||||||
|
drift_dev: ^2.20.3
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <protocol_handler_windows/protocol_handler_windows_plugin_c_api.h>
|
#include <protocol_handler_windows/protocol_handler_windows_plugin_c_api.h>
|
||||||
#include <screen_brightness_windows/screen_brightness_windows_plugin.h>
|
#include <screen_brightness_windows/screen_brightness_windows_plugin.h>
|
||||||
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
#include <share_plus/share_plus_windows_plugin_c_api.h>
|
||||||
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
@ -57,6 +58,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||||||
registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin"));
|
registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin"));
|
||||||
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
SharePlusWindowsPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
|
||||||
|
Sqlite3FlutterLibsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
protocol_handler_windows
|
protocol_handler_windows
|
||||||
screen_brightness_windows
|
screen_brightness_windows
|
||||||
share_plus
|
share_plus
|
||||||
|
sqlite3_flutter_libs
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user