diff --git a/analysis_options.yaml b/analysis_options.yaml index 0d29021..767d362 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -24,5 +24,8 @@ linter: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule +analyzer: + errors: + invalid_annotation_target: ignore # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options diff --git a/assets/fonts/Nunito-Bold.ttf b/assets/fonts/Nunito-Bold.ttf new file mode 100755 index 0000000..886134d Binary files /dev/null and b/assets/fonts/Nunito-Bold.ttf differ diff --git a/assets/fonts/Nunito-Italic.ttf b/assets/fonts/Nunito-Italic.ttf new file mode 100755 index 0000000..f4ab114 Binary files /dev/null and b/assets/fonts/Nunito-Italic.ttf differ diff --git a/assets/fonts/Nunito-Regular.ttf b/assets/fonts/Nunito-Regular.ttf new file mode 100755 index 0000000..9411bfb Binary files /dev/null and b/assets/fonts/Nunito-Regular.ttf differ diff --git a/build.yaml b/build.yaml new file mode 100644 index 0000000..60c987c --- /dev/null +++ b/build.yaml @@ -0,0 +1,7 @@ +targets: + $default: + builders: + json_serializable: + options: + explicit_to_json: true + field_rename: snake diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..ecc1c54 --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,30 @@ +PODS: + - Flutter (1.0.0) + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + +DEPENDENCIES: + - Flutter (from `Flutter`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + +SPEC CHECKSUMS: + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + +PODFILE CHECKSUM: 4305caec6b40dde0ae97be1573c53de1882a07e5 + +COCOAPODS: 1.16.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index f3ef85c..568d6a8 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -11,9 +11,11 @@ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 755557017FD1B99AFC4F9127 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + B87C0E607033790E71B54D73 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6D834CA86410B09796B312B /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -40,10 +42,15 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 14118AC858B441AB16B7309E /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 14DFD79BE7C26E51B117583C /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 1C14F71D23E4371602065522 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3A1C47BD29CC6AC2587D4DBE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -55,13 +62,25 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A499FDB2082EB000933AA8C5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + E6B10A9A85BECA2E576C91FF /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + F6D834CA86410B09796B312B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 1DFF8FEBBD0CF5A990600776 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 755557017FD1B99AFC4F9127 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B87C0E607033790E71B54D73 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -76,6 +95,29 @@ path = RunnerTests; sourceTree = ""; }; + 498A09270B73B217F0279168 /* Frameworks */ = { + isa = PBXGroup; + children = ( + F6D834CA86410B09796B312B /* Pods_Runner.framework */, + 29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 91E124CE95BCB4DCD890160D /* Pods */ = { + isa = PBXGroup; + children = ( + 1C14F71D23E4371602065522 /* Pods-Runner.debug.xcconfig */, + A499FDB2082EB000933AA8C5 /* Pods-Runner.release.xcconfig */, + 3A1C47BD29CC6AC2587D4DBE /* Pods-Runner.profile.xcconfig */, + 14DFD79BE7C26E51B117583C /* Pods-RunnerTests.debug.xcconfig */, + 14118AC858B441AB16B7309E /* Pods-RunnerTests.release.xcconfig */, + E6B10A9A85BECA2E576C91FF /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -94,6 +136,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + 91E124CE95BCB4DCD890160D /* Pods */, + 498A09270B73B217F0279168 /* Frameworks */, ); sourceTree = ""; }; @@ -128,8 +172,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 4815E0A19398E51078F4160D /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, + 1DFF8FEBBD0CF5A990600776 /* Frameworks */, ); buildRules = ( ); @@ -145,12 +191,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + E947029FCA058878F9B63890 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 8C0351B03869BBF493808288 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -238,6 +286,45 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 4815E0A19398E51078F4160D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 8C0351B03869BBF493808288 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -253,6 +340,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + E947029FCA058878F9B63890 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -379,6 +488,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 14DFD79BE7C26E51B117583C /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -396,6 +506,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 14118AC858B441AB16B7309E /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -411,6 +522,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E6B10A9A85BECA2E576C91FF /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/lib/main.dart b/lib/main.dart index a873c81..87978ff 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,22 +1,35 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:island/pods/config.dart'; import 'package:island/pods/theme.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:island/route.dart'; import 'package:island/widgets/app_scaffold.dart'; +import 'package:shared_preferences/shared_preferences.dart'; -void main() { +void main() async { WidgetsFlutterBinding.ensureInitialized(); + final prefs = await SharedPreferences.getInstance(); - doWhenWindowReady(() { - const initialSize = Size(600, 450); - appWindow.minSize = initialSize; - appWindow.size = initialSize; - appWindow.alignment = Alignment.center; - appWindow.show(); - }); + if (!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows)) { + doWhenWindowReady(() { + const initialSize = Size(600, 450); + appWindow.minSize = initialSize; + appWindow.size = initialSize; + appWindow.alignment = Alignment.center; + appWindow.show(); + }); + } - runApp(ProviderScope(child: IslandApp())); + runApp( + ProviderScope( + overrides: [sharedPreferencesProvider.overrideWithValue(prefs)], + child: IslandApp(), + ), + ); } class IslandApp extends ConsumerWidget { diff --git a/lib/models/file.dart b/lib/models/file.dart new file mode 100644 index 0000000..420bb34 --- /dev/null +++ b/lib/models/file.dart @@ -0,0 +1,27 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'file.freezed.dart'; +part 'file.g.dart'; + +@freezed +abstract class SnCloudFile with _$SnCloudFile { + const factory SnCloudFile({ + required String id, + required String name, + required String? description, + required Map? fileMeta, + required Map? userMeta, + required String? mimeType, + required String? hash, + required int size, + required DateTime uploadedAt, + required String? uploadedTo, + required int usedCount, + required DateTime createdAt, + required DateTime updatedAt, + required DateTime? deletedAt, + }) = _SnCloudFile; + + factory SnCloudFile.fromJson(Map json) => + _$SnCloudFileFromJson(json); +} diff --git a/lib/models/file.freezed.dart b/lib/models/file.freezed.dart new file mode 100644 index 0000000..7c6e319 --- /dev/null +++ b/lib/models/file.freezed.dart @@ -0,0 +1,203 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'file.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$SnCloudFile { + + String get id; String get name; String? get description; Map? get fileMeta; Map? get userMeta; String? get mimeType; String? get hash; int get size; DateTime get uploadedAt; String? get uploadedTo; int get usedCount; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; +/// Create a copy of SnCloudFile +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$SnCloudFileCopyWith get copyWith => _$SnCloudFileCopyWithImpl(this as SnCloudFile, _$identity); + + /// Serializes this SnCloudFile to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.usedCount, usedCount) || other.usedCount == usedCount)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(fileMeta),const DeepCollectionEquality().hash(userMeta),mimeType,hash,size,uploadedAt,uploadedTo,usedCount,createdAt,updatedAt,deletedAt); + +@override +String toString() { + return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, usedCount: $usedCount, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class $SnCloudFileCopyWith<$Res> { + factory $SnCloudFileCopyWith(SnCloudFile value, $Res Function(SnCloudFile) _then) = _$SnCloudFileCopyWithImpl; +@useResult +$Res call({ + String id, String name, String? description, Map? fileMeta, Map? userMeta, String? mimeType, String? hash, int size, DateTime uploadedAt, String? uploadedTo, int usedCount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt +}); + + + + +} +/// @nodoc +class _$SnCloudFileCopyWithImpl<$Res> + implements $SnCloudFileCopyWith<$Res> { + _$SnCloudFileCopyWithImpl(this._self, this._then); + + final SnCloudFile _self; + final $Res Function(SnCloudFile) _then; + +/// Create a copy of SnCloudFile +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = null,Object? uploadedTo = freezed,Object? usedCount = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable +as String?,fileMeta: freezed == fileMeta ? _self.fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable +as Map?,userMeta: freezed == userMeta ? _self.userMeta : userMeta // ignore: cast_nullable_to_non_nullable +as Map?,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable +as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable +as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable +as int,uploadedAt: null == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable +as DateTime,uploadedTo: freezed == uploadedTo ? _self.uploadedTo : uploadedTo // ignore: cast_nullable_to_non_nullable +as String?,usedCount: null == usedCount ? _self.usedCount : usedCount // ignore: cast_nullable_to_non_nullable +as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?, + )); +} + +} + + +/// @nodoc +@JsonSerializable() + +class _SnCloudFile implements SnCloudFile { + const _SnCloudFile({required this.id, required this.name, required this.description, required final Map? fileMeta, required final Map? userMeta, required this.mimeType, required this.hash, required this.size, required this.uploadedAt, required this.uploadedTo, required this.usedCount, required this.createdAt, required this.updatedAt, required this.deletedAt}): _fileMeta = fileMeta,_userMeta = userMeta; + factory _SnCloudFile.fromJson(Map json) => _$SnCloudFileFromJson(json); + +@override final String id; +@override final String name; +@override final String? description; + final Map? _fileMeta; +@override Map? get fileMeta { + final value = _fileMeta; + if (value == null) return null; + if (_fileMeta is EqualUnmodifiableMapView) return _fileMeta; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); +} + + final Map? _userMeta; +@override Map? get userMeta { + final value = _userMeta; + if (value == null) return null; + if (_userMeta is EqualUnmodifiableMapView) return _userMeta; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(value); +} + +@override final String? mimeType; +@override final String? hash; +@override final int size; +@override final DateTime uploadedAt; +@override final String? uploadedTo; +@override final int usedCount; +@override final DateTime createdAt; +@override final DateTime updatedAt; +@override final DateTime? deletedAt; + +/// Create a copy of SnCloudFile +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SnCloudFileCopyWith<_SnCloudFile> get copyWith => __$SnCloudFileCopyWithImpl<_SnCloudFile>(this, _$identity); + +@override +Map toJson() { + return _$SnCloudFileToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.usedCount, usedCount) || other.usedCount == usedCount)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(_fileMeta),const DeepCollectionEquality().hash(_userMeta),mimeType,hash,size,uploadedAt,uploadedTo,usedCount,createdAt,updatedAt,deletedAt); + +@override +String toString() { + return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, usedCount: $usedCount, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$SnCloudFileCopyWith<$Res> implements $SnCloudFileCopyWith<$Res> { + factory _$SnCloudFileCopyWith(_SnCloudFile value, $Res Function(_SnCloudFile) _then) = __$SnCloudFileCopyWithImpl; +@override @useResult +$Res call({ + String id, String name, String? description, Map? fileMeta, Map? userMeta, String? mimeType, String? hash, int size, DateTime uploadedAt, String? uploadedTo, int usedCount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt +}); + + + + +} +/// @nodoc +class __$SnCloudFileCopyWithImpl<$Res> + implements _$SnCloudFileCopyWith<$Res> { + __$SnCloudFileCopyWithImpl(this._self, this._then); + + final _SnCloudFile _self; + final $Res Function(_SnCloudFile) _then; + +/// Create a copy of SnCloudFile +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = null,Object? uploadedTo = freezed,Object? usedCount = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_SnCloudFile( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable +as String?,fileMeta: freezed == fileMeta ? _self._fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable +as Map?,userMeta: freezed == userMeta ? _self._userMeta : userMeta // ignore: cast_nullable_to_non_nullable +as Map?,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable +as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable +as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable +as int,uploadedAt: null == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable +as DateTime,uploadedTo: freezed == uploadedTo ? _self.uploadedTo : uploadedTo // ignore: cast_nullable_to_non_nullable +as String?,usedCount: null == usedCount ? _self.usedCount : usedCount // ignore: cast_nullable_to_non_nullable +as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?, + )); +} + + +} + +// dart format on diff --git a/lib/models/file.g.dart b/lib/models/file.g.dart new file mode 100644 index 0000000..41a0216 --- /dev/null +++ b/lib/models/file.g.dart @@ -0,0 +1,45 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'file.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_SnCloudFile _$SnCloudFileFromJson(Map json) => _SnCloudFile( + id: json['id'] as String, + name: json['name'] as String, + description: json['description'] as String?, + fileMeta: json['file_meta'] as Map?, + userMeta: json['user_meta'] as Map?, + mimeType: json['mime_type'] as String?, + hash: json['hash'] as String?, + size: (json['size'] as num).toInt(), + uploadedAt: DateTime.parse(json['uploaded_at'] as String), + uploadedTo: json['uploaded_to'] as String?, + usedCount: (json['used_count'] as num).toInt(), + createdAt: DateTime.parse(json['created_at'] as String), + updatedAt: DateTime.parse(json['updated_at'] as String), + deletedAt: + json['deleted_at'] == null + ? null + : DateTime.parse(json['deleted_at'] as String), +); + +Map _$SnCloudFileToJson(_SnCloudFile instance) => + { + 'id': instance.id, + 'name': instance.name, + 'description': instance.description, + 'file_meta': instance.fileMeta, + 'user_meta': instance.userMeta, + 'mime_type': instance.mimeType, + 'hash': instance.hash, + 'size': instance.size, + 'uploaded_at': instance.uploadedAt.toIso8601String(), + 'uploaded_to': instance.uploadedTo, + 'used_count': instance.usedCount, + 'created_at': instance.createdAt.toIso8601String(), + 'updated_at': instance.updatedAt.toIso8601String(), + 'deleted_at': instance.deletedAt?.toIso8601String(), + }; diff --git a/lib/models/post.dart b/lib/models/post.dart new file mode 100644 index 0000000..3ffb269 --- /dev/null +++ b/lib/models/post.dart @@ -0,0 +1,63 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:island/models/file.dart'; + +part 'post.freezed.dart'; +part 'post.g.dart'; + +@freezed +abstract class SnPost with _$SnPost { + const factory SnPost({ + required int id, + required String title, + required String description, + required dynamic language, + required dynamic editedAt, + required DateTime publishedAt, + required int visibility, + required String content, + required int type, + required dynamic meta, + required int viewsUnique, + required int viewsTotal, + required int upvotes, + required int downvotes, + required dynamic threadedPostId, + required dynamic threadedPost, + required dynamic repliedPostId, + required dynamic repliedPost, + required dynamic forwardedPostId, + required dynamic forwardedPost, + required List attachments, + required SnPublisher publisher, + required List reactions, + required List tags, + required List categories, + required List collections, + required bool empty, + required DateTime createdAt, + required DateTime updatedAt, + required dynamic deletedAt, + }) = _SnPost; + + factory SnPost.fromJson(Map json) => _$SnPostFromJson(json); +} + +@freezed +abstract class SnPublisher with _$SnPublisher { + const factory SnPublisher({ + required int id, + required int publisherType, + required String name, + required String nick, + required String bio, + required SnCloudFile picture, + required SnCloudFile background, + required int accountId, + required DateTime createdAt, + required DateTime updatedAt, + required DateTime? deletedAt, + }) = _SnPublisher; + + factory SnPublisher.fromJson(Map json) => + _$SnPublisherFromJson(json); +} diff --git a/lib/models/post.freezed.dart b/lib/models/post.freezed.dart new file mode 100644 index 0000000..c52c0bf --- /dev/null +++ b/lib/models/post.freezed.dart @@ -0,0 +1,482 @@ +// dart format width=80 +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'post.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$SnPost { + + int get id; String get title; String get description; dynamic get language; dynamic get editedAt; DateTime get publishedAt; int get visibility; String get content; int get type; dynamic get meta; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; dynamic get threadedPostId; dynamic get threadedPost; dynamic get repliedPostId; dynamic get repliedPost; dynamic get forwardedPostId; dynamic get forwardedPost; List get attachments; SnPublisher get publisher; List get reactions; List get tags; List get categories; List get collections; bool get empty; DateTime get createdAt; DateTime get updatedAt; dynamic get deletedAt; +/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$SnPostCopyWith get copyWith => _$SnPostCopyWithImpl(this as SnPost, _$identity); + + /// Serializes this SnPost to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.language, language)&&const DeepCollectionEquality().equals(other.editedAt, editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&const DeepCollectionEquality().equals(other.threadedPostId, threadedPostId)&&const DeepCollectionEquality().equals(other.threadedPost, threadedPost)&&const DeepCollectionEquality().equals(other.repliedPostId, repliedPostId)&&const DeepCollectionEquality().equals(other.repliedPost, repliedPost)&&const DeepCollectionEquality().equals(other.forwardedPostId, forwardedPostId)&&const DeepCollectionEquality().equals(other.forwardedPost, forwardedPost)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.empty, empty) || other.empty == empty)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&const DeepCollectionEquality().equals(other.deletedAt, deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hashAll([runtimeType,id,title,description,const DeepCollectionEquality().hash(language),const DeepCollectionEquality().hash(editedAt),publishedAt,visibility,content,type,const DeepCollectionEquality().hash(meta),viewsUnique,viewsTotal,upvotes,downvotes,const DeepCollectionEquality().hash(threadedPostId),const DeepCollectionEquality().hash(threadedPost),const DeepCollectionEquality().hash(repliedPostId),const DeepCollectionEquality().hash(repliedPost),const DeepCollectionEquality().hash(forwardedPostId),const DeepCollectionEquality().hash(forwardedPost),const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),empty,createdAt,updatedAt,const DeepCollectionEquality().hash(deletedAt)]); + +@override +String toString() { + return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, empty: $empty, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class $SnPostCopyWith<$Res> { + factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl; +@useResult +$Res call({ + int id, String title, String description, dynamic language, dynamic editedAt, DateTime publishedAt, int visibility, String content, int type, dynamic meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, dynamic threadedPostId, dynamic threadedPost, dynamic repliedPostId, dynamic repliedPost, dynamic forwardedPostId, dynamic forwardedPost, List attachments, SnPublisher publisher, List reactions, List tags, List categories, List collections, bool empty, DateTime createdAt, DateTime updatedAt, dynamic deletedAt +}); + + +$SnPublisherCopyWith<$Res> get publisher; + +} +/// @nodoc +class _$SnPostCopyWithImpl<$Res> + implements $SnPostCopyWith<$Res> { + _$SnPostCopyWithImpl(this._self, this._then); + + final SnPost _self; + final $Res Function(SnPost) _then; + +/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = null,Object? description = null,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = null,Object? visibility = null,Object? content = null,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? empty = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable +as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable +as String,language: freezed == language ? _self.language : language // ignore: cast_nullable_to_non_nullable +as dynamic,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore: cast_nullable_to_non_nullable +as dynamic,publishedAt: null == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable +as DateTime,visibility: null == visibility ? _self.visibility : visibility // ignore: cast_nullable_to_non_nullable +as int,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable +as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable +as int,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable +as dynamic,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable +as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable +as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable +as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable +as int,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable +as dynamic,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable +as dynamic,repliedPostId: freezed == repliedPostId ? _self.repliedPostId : repliedPostId // ignore: cast_nullable_to_non_nullable +as dynamic,repliedPost: freezed == repliedPost ? _self.repliedPost : repliedPost // ignore: cast_nullable_to_non_nullable +as dynamic,forwardedPostId: freezed == forwardedPostId ? _self.forwardedPostId : forwardedPostId // ignore: cast_nullable_to_non_nullable +as dynamic,forwardedPost: freezed == forwardedPost ? _self.forwardedPost : forwardedPost // ignore: cast_nullable_to_non_nullable +as dynamic,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable +as List,publisher: null == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable +as SnPublisher,reactions: null == reactions ? _self.reactions : reactions // ignore: cast_nullable_to_non_nullable +as List,tags: null == tags ? _self.tags : tags // ignore: cast_nullable_to_non_nullable +as List,categories: null == categories ? _self.categories : categories // ignore: cast_nullable_to_non_nullable +as List,collections: null == collections ? _self.collections : collections // ignore: cast_nullable_to_non_nullable +as List,empty: null == empty ? _self.empty : empty // ignore: cast_nullable_to_non_nullable +as bool,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as dynamic, + )); +} +/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnPublisherCopyWith<$Res> get publisher { + + return $SnPublisherCopyWith<$Res>(_self.publisher, (value) { + return _then(_self.copyWith(publisher: value)); + }); +} +} + + +/// @nodoc +@JsonSerializable() + +class _SnPost implements SnPost { + const _SnPost({required this.id, required this.title, required this.description, required this.language, required this.editedAt, required this.publishedAt, required this.visibility, required this.content, required this.type, required this.meta, required this.viewsUnique, required this.viewsTotal, required this.upvotes, required this.downvotes, required this.threadedPostId, required this.threadedPost, required this.repliedPostId, required this.repliedPost, required this.forwardedPostId, required this.forwardedPost, required final List attachments, required this.publisher, required final List reactions, required final List tags, required final List categories, required final List collections, required this.empty, required this.createdAt, required this.updatedAt, required this.deletedAt}): _attachments = attachments,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections; + factory _SnPost.fromJson(Map json) => _$SnPostFromJson(json); + +@override final int id; +@override final String title; +@override final String description; +@override final dynamic language; +@override final dynamic editedAt; +@override final DateTime publishedAt; +@override final int visibility; +@override final String content; +@override final int type; +@override final dynamic meta; +@override final int viewsUnique; +@override final int viewsTotal; +@override final int upvotes; +@override final int downvotes; +@override final dynamic threadedPostId; +@override final dynamic threadedPost; +@override final dynamic repliedPostId; +@override final dynamic repliedPost; +@override final dynamic forwardedPostId; +@override final dynamic forwardedPost; + final List _attachments; +@override List get attachments { + if (_attachments is EqualUnmodifiableListView) return _attachments; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_attachments); +} + +@override final SnPublisher publisher; + final List _reactions; +@override List get reactions { + if (_reactions is EqualUnmodifiableListView) return _reactions; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_reactions); +} + + final List _tags; +@override List get tags { + if (_tags is EqualUnmodifiableListView) return _tags; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_tags); +} + + final List _categories; +@override List get categories { + if (_categories is EqualUnmodifiableListView) return _categories; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_categories); +} + + final List _collections; +@override List get collections { + if (_collections is EqualUnmodifiableListView) return _collections; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_collections); +} + +@override final bool empty; +@override final DateTime createdAt; +@override final DateTime updatedAt; +@override final dynamic deletedAt; + +/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SnPostCopyWith<_SnPost> get copyWith => __$SnPostCopyWithImpl<_SnPost>(this, _$identity); + +@override +Map toJson() { + return _$SnPostToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.language, language)&&const DeepCollectionEquality().equals(other.editedAt, editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&const DeepCollectionEquality().equals(other.threadedPostId, threadedPostId)&&const DeepCollectionEquality().equals(other.threadedPost, threadedPost)&&const DeepCollectionEquality().equals(other.repliedPostId, repliedPostId)&&const DeepCollectionEquality().equals(other.repliedPost, repliedPost)&&const DeepCollectionEquality().equals(other.forwardedPostId, forwardedPostId)&&const DeepCollectionEquality().equals(other.forwardedPost, forwardedPost)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.empty, empty) || other.empty == empty)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&const DeepCollectionEquality().equals(other.deletedAt, deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hashAll([runtimeType,id,title,description,const DeepCollectionEquality().hash(language),const DeepCollectionEquality().hash(editedAt),publishedAt,visibility,content,type,const DeepCollectionEquality().hash(meta),viewsUnique,viewsTotal,upvotes,downvotes,const DeepCollectionEquality().hash(threadedPostId),const DeepCollectionEquality().hash(threadedPost),const DeepCollectionEquality().hash(repliedPostId),const DeepCollectionEquality().hash(repliedPost),const DeepCollectionEquality().hash(forwardedPostId),const DeepCollectionEquality().hash(forwardedPost),const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),empty,createdAt,updatedAt,const DeepCollectionEquality().hash(deletedAt)]); + +@override +String toString() { + return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, empty: $empty, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> { + factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl; +@override @useResult +$Res call({ + int id, String title, String description, dynamic language, dynamic editedAt, DateTime publishedAt, int visibility, String content, int type, dynamic meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, dynamic threadedPostId, dynamic threadedPost, dynamic repliedPostId, dynamic repliedPost, dynamic forwardedPostId, dynamic forwardedPost, List attachments, SnPublisher publisher, List reactions, List tags, List categories, List collections, bool empty, DateTime createdAt, DateTime updatedAt, dynamic deletedAt +}); + + +@override $SnPublisherCopyWith<$Res> get publisher; + +} +/// @nodoc +class __$SnPostCopyWithImpl<$Res> + implements _$SnPostCopyWith<$Res> { + __$SnPostCopyWithImpl(this._self, this._then); + + final _SnPost _self; + final $Res Function(_SnPost) _then; + +/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = null,Object? description = null,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = null,Object? visibility = null,Object? content = null,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? empty = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_SnPost( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable +as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable +as String,language: freezed == language ? _self.language : language // ignore: cast_nullable_to_non_nullable +as dynamic,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore: cast_nullable_to_non_nullable +as dynamic,publishedAt: null == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable +as DateTime,visibility: null == visibility ? _self.visibility : visibility // ignore: cast_nullable_to_non_nullable +as int,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable +as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable +as int,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable +as dynamic,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable +as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable +as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable +as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable +as int,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable +as dynamic,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable +as dynamic,repliedPostId: freezed == repliedPostId ? _self.repliedPostId : repliedPostId // ignore: cast_nullable_to_non_nullable +as dynamic,repliedPost: freezed == repliedPost ? _self.repliedPost : repliedPost // ignore: cast_nullable_to_non_nullable +as dynamic,forwardedPostId: freezed == forwardedPostId ? _self.forwardedPostId : forwardedPostId // ignore: cast_nullable_to_non_nullable +as dynamic,forwardedPost: freezed == forwardedPost ? _self.forwardedPost : forwardedPost // ignore: cast_nullable_to_non_nullable +as dynamic,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable +as List,publisher: null == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable +as SnPublisher,reactions: null == reactions ? _self._reactions : reactions // ignore: cast_nullable_to_non_nullable +as List,tags: null == tags ? _self._tags : tags // ignore: cast_nullable_to_non_nullable +as List,categories: null == categories ? _self._categories : categories // ignore: cast_nullable_to_non_nullable +as List,collections: null == collections ? _self._collections : collections // ignore: cast_nullable_to_non_nullable +as List,empty: null == empty ? _self.empty : empty // ignore: cast_nullable_to_non_nullable +as bool,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as dynamic, + )); +} + +/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnPublisherCopyWith<$Res> get publisher { + + return $SnPublisherCopyWith<$Res>(_self.publisher, (value) { + return _then(_self.copyWith(publisher: value)); + }); +} +} + + +/// @nodoc +mixin _$SnPublisher { + + int get id; int get publisherType; String get name; String get nick; String get bio; SnCloudFile get picture; SnCloudFile get background; int get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; +/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$SnPublisherCopyWith get copyWith => _$SnPublisherCopyWithImpl(this as SnPublisher, _$identity); + + /// Serializes this SnPublisher to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPublisher&&(identical(other.id, id) || other.id == id)&&(identical(other.publisherType, publisherType) || other.publisherType == publisherType)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,publisherType,name,nick,bio,picture,background,accountId,createdAt,updatedAt,deletedAt); + +@override +String toString() { + return 'SnPublisher(id: $id, publisherType: $publisherType, name: $name, nick: $nick, bio: $bio, picture: $picture, background: $background, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class $SnPublisherCopyWith<$Res> { + factory $SnPublisherCopyWith(SnPublisher value, $Res Function(SnPublisher) _then) = _$SnPublisherCopyWithImpl; +@useResult +$Res call({ + int id, int publisherType, String name, String nick, String bio, SnCloudFile picture, SnCloudFile background, int accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt +}); + + +$SnCloudFileCopyWith<$Res> get picture;$SnCloudFileCopyWith<$Res> get background; + +} +/// @nodoc +class _$SnPublisherCopyWithImpl<$Res> + implements $SnPublisherCopyWith<$Res> { + _$SnPublisherCopyWithImpl(this._self, this._then); + + final SnPublisher _self; + final $Res Function(SnPublisher) _then; + +/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? publisherType = null,Object? name = null,Object? nick = null,Object? bio = null,Object? picture = null,Object? background = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int,publisherType: null == publisherType ? _self.publisherType : publisherType // ignore: cast_nullable_to_non_nullable +as int,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable +as String,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable +as String,picture: null == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable +as SnCloudFile,background: null == background ? _self.background : background // ignore: cast_nullable_to_non_nullable +as SnCloudFile,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable +as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?, + )); +} +/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnCloudFileCopyWith<$Res> get picture { + + return $SnCloudFileCopyWith<$Res>(_self.picture, (value) { + return _then(_self.copyWith(picture: value)); + }); +}/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnCloudFileCopyWith<$Res> get background { + + return $SnCloudFileCopyWith<$Res>(_self.background, (value) { + return _then(_self.copyWith(background: value)); + }); +} +} + + +/// @nodoc +@JsonSerializable() + +class _SnPublisher implements SnPublisher { + const _SnPublisher({required this.id, required this.publisherType, required this.name, required this.nick, required this.bio, required this.picture, required this.background, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt}); + factory _SnPublisher.fromJson(Map json) => _$SnPublisherFromJson(json); + +@override final int id; +@override final int publisherType; +@override final String name; +@override final String nick; +@override final String bio; +@override final SnCloudFile picture; +@override final SnCloudFile background; +@override final int accountId; +@override final DateTime createdAt; +@override final DateTime updatedAt; +@override final DateTime? deletedAt; + +/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SnPublisherCopyWith<_SnPublisher> get copyWith => __$SnPublisherCopyWithImpl<_SnPublisher>(this, _$identity); + +@override +Map toJson() { + return _$SnPublisherToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPublisher&&(identical(other.id, id) || other.id == id)&&(identical(other.publisherType, publisherType) || other.publisherType == publisherType)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,publisherType,name,nick,bio,picture,background,accountId,createdAt,updatedAt,deletedAt); + +@override +String toString() { + return 'SnPublisher(id: $id, publisherType: $publisherType, name: $name, nick: $nick, bio: $bio, picture: $picture, background: $background, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)'; +} + + +} + +/// @nodoc +abstract mixin class _$SnPublisherCopyWith<$Res> implements $SnPublisherCopyWith<$Res> { + factory _$SnPublisherCopyWith(_SnPublisher value, $Res Function(_SnPublisher) _then) = __$SnPublisherCopyWithImpl; +@override @useResult +$Res call({ + int id, int publisherType, String name, String nick, String bio, SnCloudFile picture, SnCloudFile background, int accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt +}); + + +@override $SnCloudFileCopyWith<$Res> get picture;@override $SnCloudFileCopyWith<$Res> get background; + +} +/// @nodoc +class __$SnPublisherCopyWithImpl<$Res> + implements _$SnPublisherCopyWith<$Res> { + __$SnPublisherCopyWithImpl(this._self, this._then); + + final _SnPublisher _self; + final $Res Function(_SnPublisher) _then; + +/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? publisherType = null,Object? name = null,Object? nick = null,Object? bio = null,Object? picture = null,Object? background = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) { + return _then(_SnPublisher( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int,publisherType: null == publisherType ? _self.publisherType : publisherType // ignore: cast_nullable_to_non_nullable +as int,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable +as String,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable +as String,picture: null == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable +as SnCloudFile,background: null == background ? _self.background : background // ignore: cast_nullable_to_non_nullable +as SnCloudFile,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable +as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?, + )); +} + +/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnCloudFileCopyWith<$Res> get picture { + + return $SnCloudFileCopyWith<$Res>(_self.picture, (value) { + return _then(_self.copyWith(picture: value)); + }); +}/// Create a copy of SnPublisher +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnCloudFileCopyWith<$Res> get background { + + return $SnCloudFileCopyWith<$Res>(_self.background, (value) { + return _then(_self.copyWith(background: value)); + }); +} +} + +// dart format on diff --git a/lib/models/post.g.dart b/lib/models/post.g.dart new file mode 100644 index 0000000..8a3be7e --- /dev/null +++ b/lib/models/post.g.dart @@ -0,0 +1,108 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_SnPost _$SnPostFromJson(Map json) => _SnPost( + id: (json['id'] as num).toInt(), + title: json['title'] as String, + description: json['description'] as String, + language: json['language'], + editedAt: json['edited_at'], + publishedAt: DateTime.parse(json['published_at'] as String), + visibility: (json['visibility'] as num).toInt(), + content: json['content'] as String, + type: (json['type'] as num).toInt(), + meta: json['meta'], + viewsUnique: (json['views_unique'] as num).toInt(), + viewsTotal: (json['views_total'] as num).toInt(), + upvotes: (json['upvotes'] as num).toInt(), + downvotes: (json['downvotes'] as num).toInt(), + threadedPostId: json['threaded_post_id'], + threadedPost: json['threaded_post'], + repliedPostId: json['replied_post_id'], + repliedPost: json['replied_post'], + forwardedPostId: json['forwarded_post_id'], + forwardedPost: json['forwarded_post'], + attachments: + (json['attachments'] as List) + .map((e) => SnCloudFile.fromJson(e as Map)) + .toList(), + publisher: SnPublisher.fromJson(json['publisher'] as Map), + reactions: json['reactions'] as List, + tags: json['tags'] as List, + categories: json['categories'] as List, + collections: json['collections'] as List, + empty: json['empty'] as bool, + createdAt: DateTime.parse(json['created_at'] as String), + updatedAt: DateTime.parse(json['updated_at'] as String), + deletedAt: json['deleted_at'], +); + +Map _$SnPostToJson(_SnPost instance) => { + 'id': instance.id, + 'title': instance.title, + 'description': instance.description, + 'language': instance.language, + 'edited_at': instance.editedAt, + 'published_at': instance.publishedAt.toIso8601String(), + 'visibility': instance.visibility, + 'content': instance.content, + 'type': instance.type, + 'meta': instance.meta, + 'views_unique': instance.viewsUnique, + 'views_total': instance.viewsTotal, + 'upvotes': instance.upvotes, + 'downvotes': instance.downvotes, + 'threaded_post_id': instance.threadedPostId, + 'threaded_post': instance.threadedPost, + 'replied_post_id': instance.repliedPostId, + 'replied_post': instance.repliedPost, + 'forwarded_post_id': instance.forwardedPostId, + 'forwarded_post': instance.forwardedPost, + 'attachments': instance.attachments.map((e) => e.toJson()).toList(), + 'publisher': instance.publisher.toJson(), + 'reactions': instance.reactions, + 'tags': instance.tags, + 'categories': instance.categories, + 'collections': instance.collections, + 'empty': instance.empty, + 'created_at': instance.createdAt.toIso8601String(), + 'updated_at': instance.updatedAt.toIso8601String(), + 'deleted_at': instance.deletedAt, +}; + +_SnPublisher _$SnPublisherFromJson(Map json) => _SnPublisher( + id: (json['id'] as num).toInt(), + publisherType: (json['publisher_type'] as num).toInt(), + name: json['name'] as String, + nick: json['nick'] as String, + bio: json['bio'] as String, + picture: SnCloudFile.fromJson(json['picture'] as Map), + background: SnCloudFile.fromJson(json['background'] as Map), + accountId: (json['account_id'] as num).toInt(), + createdAt: DateTime.parse(json['created_at'] as String), + updatedAt: DateTime.parse(json['updated_at'] as String), + deletedAt: + json['deleted_at'] == null + ? null + : DateTime.parse(json['deleted_at'] as String), +); + +Map _$SnPublisherToJson(_SnPublisher instance) => + { + 'id': instance.id, + 'publisher_type': instance.publisherType, + 'name': instance.name, + 'nick': instance.nick, + 'bio': instance.bio, + 'picture': instance.picture.toJson(), + 'background': instance.background.toJson(), + 'account_id': instance.accountId, + 'created_at': instance.createdAt.toIso8601String(), + 'updated_at': instance.updatedAt.toIso8601String(), + 'deleted_at': instance.deletedAt?.toIso8601String(), + }; diff --git a/lib/pods/config.dart b/lib/pods/config.dart index e18c9cb..082a500 100644 --- a/lib/pods/config.dart +++ b/lib/pods/config.dart @@ -6,7 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart'; const kAtkStoreKey = 'nex_user_atk'; const kRtkStoreKey = 'nex_user_rtk'; -const kNetworkServerDefault = 'https://api.sn.solsynth.dev'; +const kNetworkServerDefault = 'http://localhost:5071'; const kNetworkServerStoreKey = 'app_server_url'; const kAppbarTransparentStoreKey = 'app_bar_transparent'; diff --git a/lib/pods/network.dart b/lib/pods/network.dart new file mode 100644 index 0000000..35bca33 --- /dev/null +++ b/lib/pods/network.dart @@ -0,0 +1,20 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:dio/dio.dart'; +import 'config.dart'; + +final dioProvider = Provider((ref) { + final serverUrl = ref.watch(serverUrlProvider); + final dio = Dio( + BaseOptions( + baseUrl: serverUrl, + connectTimeout: const Duration(seconds: 10), + receiveTimeout: const Duration(seconds: 10), + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + ), + ); + + return dio; +}); diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index f8a47c9..68b6e38 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -1,12 +1,80 @@ import 'package:auto_route/annotations.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:island/widgets/app_scaffold.dart'; +import 'package:island/models/post.dart'; +import 'package:very_good_infinite_list/very_good_infinite_list.dart'; +import 'package:dio/dio.dart'; +import 'package:island/pods/network.dart'; @RoutePage() -class ExploreScreen extends StatelessWidget { +class ExploreScreen extends ConsumerWidget { const ExploreScreen({super.key}); @override - Widget build(BuildContext context) { - return const Placeholder(); + Widget build(BuildContext context, WidgetRef ref) { + final postAsync = ref.watch(postListProvider); + + return AppScaffold( + appBar: AppBar(title: const Text('Explore')), + body: postAsync.when( + data: + (controller) => InfiniteList( + itemCount: controller.posts.length, + isLoading: controller.isLoading, + hasReachedMax: controller.hasReachedMax, + onFetchData: controller.fetchMore, + itemBuilder: (context, index) { + final post = controller.posts[index]; + return ListTile(title: Text(post.content)); + }, + ), + loading: () => const Center(child: CircularProgressIndicator()), + error: (e, _) => Center(child: Text('Error: $e')), + ), + ); + } +} + +final postListProvider = FutureProvider<_PostListController>((ref) async { + final dio = ref.watch(dioProvider); + final controller = _PostListController(dio); + await controller.fetchMore(); + return controller; +}); + +class _PostListController { + _PostListController(this._dio); + + final Dio _dio; + final List posts = []; + bool isLoading = false; + bool hasReachedMax = false; + int offset = 0; + final int take = 20; + int total = 0; + + Future fetchMore() async { + if (isLoading || hasReachedMax) return; + isLoading = true; + + final response = await _dio.get( + '/posts', + queryParameters: {'offset': offset, 'take': take}, + ); + + final List fetched = + (response.data as List) + .map((e) => SnPost.fromJson(e as Map)) + .toList(); + + final headerTotal = int.tryParse(response.headers['x-total']?.first ?? ''); + if (headerTotal != null) total = headerTotal; + + posts.addAll(fetched); + offset += fetched.length; + if (posts.length >= total) hasReachedMax = true; + + isLoading = false; } } diff --git a/lib/widgets/app_scaffold.dart b/lib/widgets/app_scaffold.dart index ecec4ee..8b652f3 100644 --- a/lib/widgets/app_scaffold.dart +++ b/lib/widgets/app_scaffold.dart @@ -1,8 +1,12 @@ import 'dart:io'; +import 'package:auto_route/auto_route.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:responsive_framework/responsive_framework.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:styled_widget/styled_widget.dart'; class WindowScaffold extends StatelessWidget { @@ -74,3 +78,155 @@ class WindowScaffold extends StatelessWidget { return child; } } + +final rootScaffoldKey = GlobalKey(); + +class AppScaffold extends StatelessWidget { + final Widget? body; + final PreferredSizeWidget? bottomNavigationBar; + final PreferredSizeWidget? bottomSheet; + final Drawer? drawer; + final Widget? endDrawer; + final FloatingActionButtonAnimator? floatingActionButtonAnimator; + final FloatingActionButtonLocation? floatingActionButtonLocation; + final Widget? floatingActionButton; + final AppBar? appBar; + final DrawerCallback? onDrawerChanged; + final DrawerCallback? onEndDrawerChanged; + final bool noBackground; + + const AppScaffold({ + super.key, + this.appBar, + this.body, + this.floatingActionButton, + this.floatingActionButtonLocation, + this.floatingActionButtonAnimator, + this.bottomNavigationBar, + this.bottomSheet, + this.drawer, + this.endDrawer, + this.onDrawerChanged, + this.onEndDrawerChanged, + this.noBackground = false, + }); + + @override + Widget build(BuildContext context) { + final appBarHeight = appBar?.preferredSize.height ?? 0; + final safeTop = MediaQuery.of(context).padding.top; + + final content = Column( + children: [ + IgnorePointer( + child: SizedBox(height: appBar != null ? appBarHeight + safeTop : 0), + ), + if (body != null) Expanded(child: body!), + ], + ); + + return Scaffold( + extendBody: true, + extendBodyBehindAppBar: true, + backgroundColor: + noBackground + ? Colors.transparent + : Theme.of(context).scaffoldBackgroundColor, + body: SizedBox.expand( + child: + noBackground + ? content + : AppBackground(isRoot: true, child: content), + ), + appBar: appBar, + bottomNavigationBar: bottomNavigationBar, + bottomSheet: bottomSheet, + drawer: drawer, + endDrawer: endDrawer, + floatingActionButton: floatingActionButton, + floatingActionButtonAnimator: floatingActionButtonAnimator, + floatingActionButtonLocation: floatingActionButtonLocation, + onDrawerChanged: onDrawerChanged, + onEndDrawerChanged: onEndDrawerChanged, + ); + } +} + +class PageBackButton extends StatelessWidget { + const PageBackButton({super.key}); + + @override + Widget build(BuildContext context) { + return BackButton( + onPressed: () { + context.router.maybePop(); + }, + ); + } +} + +const kAppBackgroundImagePath = 'island_app_background'; + +final backgroundImageFileProvider = FutureProvider((ref) async { + if (kIsWeb) return null; + final dir = await getApplicationSupportDirectory(); + final path = '${dir.path}/$kAppBackgroundImagePath'; + final file = File(path); + return file.existsSync() ? file : null; +}); + +class AppBackground extends ConsumerWidget { + final Widget child; + final bool isRoot; + + const AppBackground({super.key, required this.child, this.isRoot = false}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final imageFileAsync = ref.watch(backgroundImageFileProvider); + + if (isRoot || ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE)) { + return imageFileAsync.when( + data: (file) { + if (file != null) { + final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + + final size = MediaQuery.of(context).size; + return Container( + color: Theme.of(context).colorScheme.surface, + child: Container( + decoration: BoxDecoration( + backgroundBlendMode: BlendMode.darken, + color: Theme.of(context).colorScheme.surface, + image: DecorationImage( + opacity: 0.2, + image: ResizeImage( + FileImage(file), + width: (size.width * devicePixelRatio).round(), + height: (size.height * devicePixelRatio).round(), + policy: ResizeImagePolicy.fit, + ), + fit: BoxFit.cover, + ), + ), + child: child, + ), + ); + } + return Material( + color: Theme.of(context).colorScheme.surface, + child: child, + ); + }, + loading: () => const SizedBox(), + error: + (_, __) => Material( + color: Theme.of(context).colorScheme.surface, + child: child, + ), + ); + } + + return Material(color: Colors.transparent, child: child); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 1264e75..b61c560 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,9 +6,11 @@ import FlutterMacOS import Foundation import bitsdojo_window_macos +import path_provider_foundation import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 87e10a2..063791c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -233,6 +233,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + dio: + dependency: "direct main" + description: + name: dio + sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + url: "https://pub.dev" + source: hosted + version: "5.8.0+1" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" fake_async: dependency: transitive description: @@ -304,6 +320,22 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed: + dependency: "direct dev" + description: + name: freezed + sha256: "6022db4c7bfa626841b2a10f34dd1e1b68e8f8f9650db6112dcdeeca45ca793c" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + freezed_annotation: + dependency: "direct main" + description: + name: freezed_annotation + sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b + url: "https://pub.dev" + source: hosted + version: "3.0.0" frontend_server_client: dependency: transitive description: @@ -377,13 +409,21 @@ packages: source: hosted version: "0.7.2" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted version: "4.9.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c + url: "https://pub.dev" + source: hosted + version: "6.9.5" leak_tracker: dependency: transitive description: @@ -480,6 +520,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 + url: "https://pub.dev" + source: hosted + version: "2.2.17" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" + url: "https://pub.dev" + source: hosted + version: "2.4.1" path_provider_linux: dependency: transitive description: @@ -653,6 +717,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" + url: "https://pub.dev" + source: hosted + version: "1.3.5" source_span: dependency: transitive description: @@ -749,6 +821,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + very_good_infinite_list: + dependency: "direct main" + description: + name: very_good_infinite_list + sha256: "2f72172c28849b29c65dda0e598d486a59d669cfff1d60db7896719ec8211501" + url: "https://pub.dev" + source: hosted + version: "0.9.0" vm_service: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ae06229..52d2166 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: island -description: "A new Flutter project." +description: "The Solar Network V3 App" # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 +version: 3.0.0+93 environment: sdk: ^3.7.2 @@ -42,6 +42,11 @@ dependencies: shared_preferences: ^2.5.3 responsive_framework: ^1.5.1 flutter_riverpod: ^2.6.1 + path_provider: ^2.1.5 + dio: ^5.8.0+1 + very_good_infinite_list: ^0.9.0 + freezed_annotation: ^3.0.0 + json_annotation: ^4.9.0 dev_dependencies: flutter_test: @@ -55,6 +60,8 @@ dev_dependencies: flutter_lints: ^5.0.0 auto_route_generator: ^10.0.1 build_runner: ^2.4.15 + freezed: ^3.0.6 + json_serializable: ^6.9.5 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec @@ -83,17 +90,15 @@ flutter: # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 + fonts: + - family: Nunito + fonts: + - asset: assets/fonts/Nunito-Regular.ttf + - asset: assets/fonts/Nunito-Bold.ttf + weight: 700 + - asset: assets/fonts/Nunito-Italic.ttf + style: italic + # # For details regarding fonts from package dependencies, # see https://flutter.dev/to/font-from-package