✨ News Reader Basis
This commit is contained in:
parent
a355e3bf90
commit
963e538ae5
@ -19,6 +19,10 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:enableOnBackInvokedCallback="true"
|
android:enableOnBackInvokedCallback="true"
|
||||||
android:requestLegacyExternalStorage="true">
|
android:requestLegacyExternalStorage="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="flutterEmbedding"
|
||||||
|
android:value="2" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
11
api/Reader/List News Sources.bru
Normal file
11
api/Reader/List News Sources.bru
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
meta {
|
||||||
|
name: List News Sources
|
||||||
|
type: http
|
||||||
|
seq: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: {{endpoint}}/cgi/re/well-known/sources
|
||||||
|
body: none
|
||||||
|
auth: none
|
||||||
|
}
|
17
api/Reader/List News.bru
Normal file
17
api/Reader/List News.bru
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
meta {
|
||||||
|
name: List News
|
||||||
|
type: http
|
||||||
|
seq: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: {{endpoint}}/cgi/re/news?take=10&offset=0&source=taiwan-pts
|
||||||
|
body: none
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
params:query {
|
||||||
|
take: 10
|
||||||
|
offset: 0
|
||||||
|
source: taiwan-pts
|
||||||
|
}
|
17
api/Reader/Trigger Scan News.bru
Normal file
17
api/Reader/Trigger Scan News.bru
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
meta {
|
||||||
|
name: Trigger Scan News
|
||||||
|
type: http
|
||||||
|
seq: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{endpoint}}/cgi/re/admin/scan
|
||||||
|
body: json
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"eager": true
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@
|
|||||||
"screenAccountProfileEdit": "Edit Profile",
|
"screenAccountProfileEdit": "Edit Profile",
|
||||||
"screenAbuseReport": "Abuse Reports",
|
"screenAbuseReport": "Abuse Reports",
|
||||||
"screenSettings": "Settings",
|
"screenSettings": "Settings",
|
||||||
|
"screenNews": "News",
|
||||||
"screenAlbum": "Album",
|
"screenAlbum": "Album",
|
||||||
"screenChat": "Chat",
|
"screenChat": "Chat",
|
||||||
"screenChatManage": "Edit Channel",
|
"screenChatManage": "Edit Channel",
|
||||||
@ -558,5 +559,9 @@
|
|||||||
"postCategoryKnowledge": "Knowledge",
|
"postCategoryKnowledge": "Knowledge",
|
||||||
"postCategoryLiterature": "Literature",
|
"postCategoryLiterature": "Literature",
|
||||||
"postCategoryFunny": "Funny",
|
"postCategoryFunny": "Funny",
|
||||||
"postCategoryUncategorized": "Uncategorized"
|
"postCategoryUncategorized": "Uncategorized",
|
||||||
|
"newsAllSources": "All News",
|
||||||
|
"newsReadingProviderSwap": "Swap",
|
||||||
|
"newsReadingFromReader": "You're reading from HyperNet.Reader",
|
||||||
|
"newsReadingFromOriginal": "You're reading the original article"
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"screenAccountProfileEdit": "编辑资料",
|
"screenAccountProfileEdit": "编辑资料",
|
||||||
"screenAbuseReport": "滥用检举",
|
"screenAbuseReport": "滥用检举",
|
||||||
"screenSettings": "设置",
|
"screenSettings": "设置",
|
||||||
|
"screenNews": "新闻",
|
||||||
"screenAlbum": "相册",
|
"screenAlbum": "相册",
|
||||||
"screenChat": "聊天",
|
"screenChat": "聊天",
|
||||||
"screenChatManage": "编辑聊天频道",
|
"screenChatManage": "编辑聊天频道",
|
||||||
@ -556,5 +557,9 @@
|
|||||||
"postCategoryKnowledge": "知识",
|
"postCategoryKnowledge": "知识",
|
||||||
"postCategoryLiterature": "文学",
|
"postCategoryLiterature": "文学",
|
||||||
"postCategoryFunny": "搞笑",
|
"postCategoryFunny": "搞笑",
|
||||||
"postCategoryUncategorized": "未分类"
|
"postCategoryUncategorized": "未分类",
|
||||||
|
"newsAllSources": "所有新闻",
|
||||||
|
"newsReadingProviderSwap": "切换",
|
||||||
|
"newsReadingFromReader": "你正在从 HyperNet.Reader 阅读文章",
|
||||||
|
"newsReadingFromOriginal": "你正在阅读原始文章"
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,13 @@ PODS:
|
|||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
- flutter_app_update (0.0.1):
|
- flutter_app_update (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- flutter_inappwebview_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- flutter_inappwebview_ios/Core (= 0.0.1)
|
||||||
|
- OrderedSet (~> 6.0.3)
|
||||||
|
- flutter_inappwebview_ios/Core (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- OrderedSet (~> 6.0.3)
|
||||||
- flutter_native_splash (2.4.3):
|
- flutter_native_splash (2.4.3):
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_udid (0.0.1):
|
- flutter_udid (0.0.1):
|
||||||
@ -188,6 +195,7 @@ PODS:
|
|||||||
- nanopb/encode (= 3.30910.0)
|
- nanopb/encode (= 3.30910.0)
|
||||||
- nanopb/decode (3.30910.0)
|
- nanopb/decode (3.30910.0)
|
||||||
- nanopb/encode (3.30910.0)
|
- nanopb/encode (3.30910.0)
|
||||||
|
- OrderedSet (6.0.3)
|
||||||
- package_info_plus (0.4.5):
|
- package_info_plus (0.4.5):
|
||||||
- Flutter
|
- Flutter
|
||||||
- pasteboard (0.0.1):
|
- pasteboard (0.0.1):
|
||||||
@ -239,6 +247,7 @@ DEPENDENCIES:
|
|||||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_app_update (from `.symlinks/plugins/flutter_app_update/ios`)
|
- flutter_app_update (from `.symlinks/plugins/flutter_app_update/ios`)
|
||||||
|
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
|
||||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||||
- flutter_udid (from `.symlinks/plugins/flutter_udid/ios`)
|
- flutter_udid (from `.symlinks/plugins/flutter_udid/ios`)
|
||||||
- flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`)
|
- flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`)
|
||||||
@ -282,6 +291,7 @@ SPEC REPOS:
|
|||||||
- GoogleUtilities
|
- GoogleUtilities
|
||||||
- Kingfisher
|
- Kingfisher
|
||||||
- nanopb
|
- nanopb
|
||||||
|
- OrderedSet
|
||||||
- PromisesObjC
|
- PromisesObjC
|
||||||
- SAMKeychain
|
- SAMKeychain
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
@ -309,6 +319,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter
|
:path: Flutter
|
||||||
flutter_app_update:
|
flutter_app_update:
|
||||||
:path: ".symlinks/plugins/flutter_app_update/ios"
|
:path: ".symlinks/plugins/flutter_app_update/ios"
|
||||||
|
flutter_inappwebview_ios:
|
||||||
|
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||||
flutter_udid:
|
flutter_udid:
|
||||||
@ -380,6 +392,7 @@ SPEC CHECKSUMS:
|
|||||||
FirebaseMessaging: e1aca1fcc23e8b9eddb0e33f375ff90944623021
|
FirebaseMessaging: e1aca1fcc23e8b9eddb0e33f375ff90944623021
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
flutter_app_update: 65f61da626cb111d1b24674abc4b01728d7723bc
|
flutter_app_update: 65f61da626cb111d1b24674abc4b01728d7723bc
|
||||||
|
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
|
||||||
flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a
|
flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a
|
||||||
flutter_udid: b2417673f287ee62817a1de3d1643f47b9f508ab
|
flutter_udid: b2417673f287ee62817a1de3d1643f47b9f508ab
|
||||||
flutter_webrtc: 90260f83024b1b96d239a575ea4e3708e79344d1
|
flutter_webrtc: 90260f83024b1b96d239a575ea4e3708e79344d1
|
||||||
@ -396,6 +409,7 @@ SPEC CHECKSUMS:
|
|||||||
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
||||||
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
||||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||||
|
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||||
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
||||||
pasteboard: 982969ebaa7c78af3e6cc7761e8f5e77565d9ce0
|
pasteboard: 982969ebaa7c78af3e6cc7761e8f5e77565d9ce0
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
|
@ -58,6 +58,11 @@ class NavigationProvider extends ChangeNotifier {
|
|||||||
screen: 'realm',
|
screen: 'realm',
|
||||||
label: 'screenRealm',
|
label: 'screenRealm',
|
||||||
),
|
),
|
||||||
|
AppNavDestination(
|
||||||
|
icon: Icon(Symbols.newspaper, weight: 400, opticalSize: 20),
|
||||||
|
screen: 'news',
|
||||||
|
label: 'screenNews',
|
||||||
|
),
|
||||||
AppNavDestination(
|
AppNavDestination(
|
||||||
icon: Icon(Symbols.photo_library, weight: 400, opticalSize: 20),
|
icon: Icon(Symbols.photo_library, weight: 400, opticalSize: 20),
|
||||||
screen: 'album',
|
screen: 'album',
|
||||||
@ -83,8 +88,7 @@ class NavigationProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
List<AppNavDestination> destinations = [];
|
List<AppNavDestination> destinations = [];
|
||||||
|
|
||||||
int get pinnedDestinationCount =>
|
int get pinnedDestinationCount => destinations.where((ele) => ele.isPinned).length;
|
||||||
destinations.where((ele) => ele.isPinned).length;
|
|
||||||
|
|
||||||
NavigationProvider() {
|
NavigationProvider() {
|
||||||
buildDestinations(kDefaultPinnedDestination);
|
buildDestinations(kDefaultPinnedDestination);
|
||||||
@ -113,17 +117,13 @@ class NavigationProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isIndexInRange(int min, int max) {
|
bool isIndexInRange(int min, int max) {
|
||||||
return _currentIndex != null &&
|
return _currentIndex != null && _currentIndex! >= min && _currentIndex! < max;
|
||||||
_currentIndex! >= min &&
|
|
||||||
_currentIndex! < max;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void autoDetectIndex(GoRouter? state) {
|
void autoDetectIndex(GoRouter? state) {
|
||||||
if (state == null) return;
|
if (state == null) return;
|
||||||
final idx = destinations.indexWhere(
|
final idx = destinations.indexWhere(
|
||||||
(ele) =>
|
(ele) => ele.screen == state.routerDelegate.currentConfiguration.last.route.name,
|
||||||
ele.screen ==
|
|
||||||
state.routerDelegate.currentConfiguration.last.route.name,
|
|
||||||
);
|
);
|
||||||
_currentIndex = idx == -1 ? null : idx;
|
_currentIndex = idx == -1 ? null : idx;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -19,6 +19,8 @@ import 'package:surface/screens/chat/room.dart';
|
|||||||
import 'package:surface/screens/explore.dart';
|
import 'package:surface/screens/explore.dart';
|
||||||
import 'package:surface/screens/friend.dart';
|
import 'package:surface/screens/friend.dart';
|
||||||
import 'package:surface/screens/home.dart';
|
import 'package:surface/screens/home.dart';
|
||||||
|
import 'package:surface/screens/news/news_detail.dart';
|
||||||
|
import 'package:surface/screens/news/news_list.dart';
|
||||||
import 'package:surface/screens/notification.dart';
|
import 'package:surface/screens/notification.dart';
|
||||||
import 'package:surface/screens/post/post_detail.dart';
|
import 'package:surface/screens/post/post_detail.dart';
|
||||||
import 'package:surface/screens/post/post_editor.dart';
|
import 'package:surface/screens/post/post_editor.dart';
|
||||||
@ -31,7 +33,6 @@ import 'package:surface/screens/settings.dart';
|
|||||||
import 'package:surface/screens/sharing.dart';
|
import 'package:surface/screens/sharing.dart';
|
||||||
import 'package:surface/types/post.dart';
|
import 'package:surface/types/post.dart';
|
||||||
import 'package:surface/widgets/about.dart';
|
import 'package:surface/widgets/about.dart';
|
||||||
import 'package:surface/widgets/navigation/app_background.dart';
|
|
||||||
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
|
|
||||||
Widget _fadeThroughTransition(
|
Widget _fadeThroughTransition(
|
||||||
@ -48,18 +49,12 @@ final _appRoutes = [
|
|||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
name: 'home',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => const HomeScreen(),
|
||||||
transitionsBuilder: _fadeThroughTransition,
|
|
||||||
child: const HomeScreen(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/posts',
|
path: '/posts',
|
||||||
name: 'explore',
|
name: 'explore',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => const ExploreScreen(),
|
||||||
transitionsBuilder: _fadeThroughTransition,
|
|
||||||
child: const ExploreScreen(),
|
|
||||||
),
|
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/write/:mode',
|
path: '/write/:mode',
|
||||||
@ -104,64 +99,42 @@ final _appRoutes = [
|
|||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/account',
|
path: '/account',
|
||||||
name: 'account',
|
name: 'account',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => const AccountScreen(),
|
||||||
transitionsBuilder: _fadeThroughTransition,
|
|
||||||
child: const AccountScreen(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/chat',
|
path: '/chat',
|
||||||
name: 'chat',
|
name: 'chat',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => const ChatScreen(),
|
||||||
transitionsBuilder: _fadeThroughTransition,
|
|
||||||
child: const ChatScreen(),
|
|
||||||
),
|
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/:scope/:alias',
|
path: '/:scope/:alias',
|
||||||
name: 'chatRoom',
|
name: 'chatRoom',
|
||||||
builder: (context, state) => AppBackground(
|
builder: (context, state) => ChatRoomScreen(
|
||||||
child: ChatRoomScreen(
|
scope: state.pathParameters['scope']!,
|
||||||
scope: state.pathParameters['scope']!,
|
alias: state.pathParameters['alias']!,
|
||||||
alias: state.pathParameters['alias']!,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/:scope/:alias/call',
|
path: '/:scope/:alias/call',
|
||||||
name: 'chatCallRoom',
|
name: 'chatCallRoom',
|
||||||
builder: (context, state) => AppBackground(
|
builder: (context, state) => CallRoomScreen(
|
||||||
child: CallRoomScreen(
|
scope: state.pathParameters['scope']!,
|
||||||
scope: state.pathParameters['scope']!,
|
alias: state.pathParameters['alias']!,
|
||||||
alias: state.pathParameters['alias']!,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/:scope/:alias/detail',
|
path: '/:scope/:alias/detail',
|
||||||
name: 'channelDetail',
|
name: 'channelDetail',
|
||||||
builder: (context, state) => AppBackground(
|
builder: (context, state) => ChannelDetailScreen(
|
||||||
child: ChannelDetailScreen(
|
scope: state.pathParameters['scope']!,
|
||||||
scope: state.pathParameters['scope']!,
|
alias: state.pathParameters['alias']!,
|
||||||
alias: state.pathParameters['alias']!,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/manage',
|
path: '/manage',
|
||||||
name: 'chatManage',
|
name: 'chatManage',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => ChatManageScreen(
|
||||||
child: ChatManageScreen(
|
editingChannelAlias: state.uri.queryParameters['editing'],
|
||||||
editingChannelAlias: state.uri.queryParameters['editing'],
|
|
||||||
),
|
|
||||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
||||||
return FadeThroughTransition(
|
|
||||||
animation: animation,
|
|
||||||
secondaryAnimation: secondaryAnimation,
|
|
||||||
fillColor: Colors.transparent,
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -182,36 +155,40 @@ final _appRoutes = [
|
|||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/manage',
|
path: '/manage',
|
||||||
name: 'realmManage',
|
name: 'realmManage',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => RealmManageScreen(
|
||||||
transitionsBuilder: _fadeThroughTransition,
|
editingRealmAlias: state.uri.queryParameters['editing'],
|
||||||
child: RealmManageScreen(
|
|
||||||
editingRealmAlias: state.uri.queryParameters['editing'],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/news',
|
||||||
|
name: 'news',
|
||||||
|
builder: (context, state) => const NewsScreen(),
|
||||||
|
routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: '/:hash',
|
||||||
|
name: 'newsDetail',
|
||||||
|
builder: (context, state) => NewsDetailScreen(
|
||||||
|
hash: state.pathParameters['hash']!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/album',
|
path: '/album',
|
||||||
name: 'album',
|
name: 'album',
|
||||||
pageBuilder: (context, state) => CustomTransitionPage(
|
builder: (context, state) => const AlbumScreen(),
|
||||||
transitionsBuilder: _fadeThroughTransition,
|
|
||||||
child: const AlbumScreen(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/friend',
|
path: '/friend',
|
||||||
name: 'friend',
|
name: 'friend',
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
builder: (context, state) => const FriendScreen(),
|
||||||
child: const FriendScreen(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/notification',
|
path: '/notification',
|
||||||
name: 'notification',
|
name: 'notification',
|
||||||
pageBuilder: (context, state) => NoTransitionPage(
|
builder: (context, state) => const NotificationScreen(),
|
||||||
child: const NotificationScreen(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/auth/login',
|
path: '/auth/login',
|
||||||
|
113
lib/screens/news/news_detail.dart
Normal file
113
lib/screens/news/news_detail.dart
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:surface/providers/sn_network.dart';
|
||||||
|
import 'package:surface/types/news.dart';
|
||||||
|
import 'package:surface/widgets/dialog.dart';
|
||||||
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
|
class NewsDetailScreen extends StatefulWidget {
|
||||||
|
final String hash;
|
||||||
|
|
||||||
|
const NewsDetailScreen({super.key, required this.hash});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NewsDetailScreen> createState() => _NewsDetailScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewsDetailScreenState extends State<NewsDetailScreen> {
|
||||||
|
SnNewsArticle? _article;
|
||||||
|
|
||||||
|
Future<void> _fetchArticle() async {
|
||||||
|
try {
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
final resp = await sn.client.get('/cgi/re/news/${widget.hash}');
|
||||||
|
_article = SnNewsArticle.fromJson(resp.data);
|
||||||
|
} catch (err) {
|
||||||
|
if (!mounted) return;
|
||||||
|
context.showErrorDialog(err).then((_) {
|
||||||
|
if (!mounted) return;
|
||||||
|
Navigator.pop(context);
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_fetchArticle();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isReadingFromReader = true;
|
||||||
|
|
||||||
|
String get _htmlContent => """
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #000000;
|
||||||
|
color: #fff;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${_article?.content ?? ''}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
""";
|
||||||
|
|
||||||
|
InAppWebViewController? _webViewController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AppScaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: const PageBackButton(),
|
||||||
|
title: Text(_article?.title ?? 'loading'.tr()),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
MaterialBanner(
|
||||||
|
dividerColor: Colors.transparent,
|
||||||
|
leading: const Icon(Icons.info),
|
||||||
|
content: Text(_isReadingFromReader ? 'newsReadingFromReader'.tr() : 'newsReadingFromOriginal'.tr()),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
child: Text('newsReadingProviderSwap').tr(),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() => _isReadingFromReader = !_isReadingFromReader);
|
||||||
|
if (!_isReadingFromReader) {
|
||||||
|
_webViewController?.goTo(historyItem: WebHistoryItem(url: WebUri(_article!.url)));
|
||||||
|
} else {
|
||||||
|
_webViewController?.goBack();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: InAppWebView(
|
||||||
|
key: Key('news-detail-webview-${widget.hash}-$_isReadingFromReader'),
|
||||||
|
onWebViewCreated: (controller) {
|
||||||
|
_webViewController = controller;
|
||||||
|
},
|
||||||
|
initialUrlRequest: URLRequest(url: WebUri(_article!.url)),
|
||||||
|
onLoadStop: (controller, url) {
|
||||||
|
print("Loaded: $url");
|
||||||
|
},
|
||||||
|
onLoadError: (controller, url, code, message) {
|
||||||
|
print("Error loading $url: $message ($code)");
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
189
lib/screens/news/news_list.dart
Normal file
189
lib/screens/news/news_list.dart
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'package:surface/providers/sn_network.dart';
|
||||||
|
import 'package:surface/types/news.dart';
|
||||||
|
import 'package:surface/widgets/app_bar_leading.dart';
|
||||||
|
import 'package:surface/widgets/dialog.dart';
|
||||||
|
import 'package:surface/widgets/navigation/app_scaffold.dart';
|
||||||
|
import 'package:surface/widgets/universal_image.dart';
|
||||||
|
import 'package:very_good_infinite_list/very_good_infinite_list.dart';
|
||||||
|
|
||||||
|
class NewsScreen extends StatefulWidget {
|
||||||
|
const NewsScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NewsScreen> createState() => _NewsScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewsScreenState extends State<NewsScreen> {
|
||||||
|
List<SnNewsSource>? _sources;
|
||||||
|
|
||||||
|
@override
|
||||||
|
initState() {
|
||||||
|
super.initState();
|
||||||
|
_fetchSources();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _fetchSources() async {
|
||||||
|
try {
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
final resp = await sn.client.get('/cgi/re/well-known/sources');
|
||||||
|
_sources = List<SnNewsSource>.from(
|
||||||
|
resp.data?.map((e) => SnNewsSource.fromJson(e)) ?? [],
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
if (!mounted) return;
|
||||||
|
context.showErrorDialog(err);
|
||||||
|
} finally {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_sources == null) {
|
||||||
|
return AppScaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: AutoAppBarLeading(),
|
||||||
|
title: Text('screenNews').tr(),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefaultTabController(
|
||||||
|
length: _sources!.length + 1,
|
||||||
|
child: AppScaffold(
|
||||||
|
body: NestedScrollView(
|
||||||
|
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||||
|
return <Widget>[
|
||||||
|
SliverOverlapAbsorber(
|
||||||
|
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||||
|
sliver: SliverAppBar(
|
||||||
|
leading: AutoAppBarLeading(),
|
||||||
|
title: Text('screenNews').tr(),
|
||||||
|
bottom: TabBar(
|
||||||
|
isScrollable: true,
|
||||||
|
tabs: [
|
||||||
|
Tab(child: Text('newsAllSources'.tr())),
|
||||||
|
for (final source in _sources!) Tab(child: Text(source.label)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
body: TabBarView(
|
||||||
|
children: [
|
||||||
|
_NewsArticleListWidget(),
|
||||||
|
for (final source in _sources!) _NewsArticleListWidget(source: source.id),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewsArticleListWidget extends StatefulWidget {
|
||||||
|
final String? source;
|
||||||
|
|
||||||
|
const _NewsArticleListWidget({this.source});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_NewsArticleListWidget> createState() => _NewsArticleListWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewsArticleListWidgetState extends State<_NewsArticleListWidget> {
|
||||||
|
bool _isBusy = false;
|
||||||
|
|
||||||
|
int? _totalCount;
|
||||||
|
final List<SnNewsArticle> _articles = List.empty(growable: true);
|
||||||
|
|
||||||
|
Future<void> _fetchArticles() async {
|
||||||
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
final resp = await sn.client.get('/cgi/re/news', queryParameters: {
|
||||||
|
'take': 10,
|
||||||
|
'offset': _articles.length,
|
||||||
|
if (widget.source != null) 'source': widget.source,
|
||||||
|
});
|
||||||
|
_totalCount = resp.data['count'];
|
||||||
|
_articles.addAll(List<SnNewsArticle>.from(
|
||||||
|
resp.data['data']?.map((e) => SnNewsArticle.fromJson(e)) ?? [],
|
||||||
|
));
|
||||||
|
} catch (err) {
|
||||||
|
if (!mounted) return;
|
||||||
|
context.showErrorDialog(err);
|
||||||
|
} finally {
|
||||||
|
setState(() => _isBusy = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_fetchArticles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MediaQuery.removePadding(
|
||||||
|
context: context,
|
||||||
|
removeTop: true,
|
||||||
|
child: RefreshIndicator(
|
||||||
|
onRefresh: _fetchArticles,
|
||||||
|
child: InfiniteList(
|
||||||
|
isLoading: _isBusy,
|
||||||
|
itemCount: _articles.length,
|
||||||
|
hasReachedMax: _totalCount != null && _articles.length >= _totalCount!,
|
||||||
|
onFetchData: () {
|
||||||
|
_fetchArticles();
|
||||||
|
},
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final article = _articles[index];
|
||||||
|
|
||||||
|
final baseUri = Uri.parse(article.url);
|
||||||
|
final baseUrl = '${baseUri.scheme}://${baseUri.host}';
|
||||||
|
|
||||||
|
return Card(
|
||||||
|
child: InkWell(
|
||||||
|
radius: 8,
|
||||||
|
onTap: () {
|
||||||
|
GoRouter.of(context).pushNamed(
|
||||||
|
'newsDetail',
|
||||||
|
pathParameters: {'hash': article.hash},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
if (article.thumbnail.isNotEmpty && !article.thumbnail.endsWith('.svg'))
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 16 / 9,
|
||||||
|
child: AutoResizeUniversalImage('$baseUrl/${article.thumbnail}'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(article.title).textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||||
|
Text(article.description).textStyle(Theme.of(context).textTheme.bodyMedium!),
|
||||||
|
const Gap(8),
|
||||||
|
Text(article.source).textStyle(Theme.of(context).textTheme.bodySmall!),
|
||||||
|
],
|
||||||
|
).padding(all: 8),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
38
lib/types/news.dart
Normal file
38
lib/types/news.dart
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'news.freezed.dart';
|
||||||
|
part 'news.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class SnNewsSource with _$SnNewsSource {
|
||||||
|
const factory SnNewsSource({
|
||||||
|
required String id,
|
||||||
|
required String label,
|
||||||
|
required String type,
|
||||||
|
required String source,
|
||||||
|
required int depth,
|
||||||
|
required bool enabled,
|
||||||
|
}) = _SnNewsSource;
|
||||||
|
|
||||||
|
factory SnNewsSource.fromJson(Map<String, dynamic> json) => _$SnNewsSourceFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class SnNewsArticle with _$SnNewsArticle {
|
||||||
|
const factory SnNewsArticle({
|
||||||
|
required int id,
|
||||||
|
required DateTime createdAt,
|
||||||
|
required DateTime updatedAt,
|
||||||
|
required dynamic deletedAt,
|
||||||
|
required String thumbnail,
|
||||||
|
required String title,
|
||||||
|
required String description,
|
||||||
|
required String content,
|
||||||
|
required String url,
|
||||||
|
required String hash,
|
||||||
|
required String source,
|
||||||
|
required dynamic publishedAt,
|
||||||
|
}) = _SnNewsArticle;
|
||||||
|
|
||||||
|
factory SnNewsArticle.fromJson(Map<String, dynamic> json) => _$SnNewsArticleFromJson(json);
|
||||||
|
}
|
660
lib/types/news.freezed.dart
Normal file
660
lib/types/news.freezed.dart
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
// 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 'news.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
SnNewsSource _$SnNewsSourceFromJson(Map<String, dynamic> json) {
|
||||||
|
return _SnNewsSource.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnNewsSource {
|
||||||
|
String get id => throw _privateConstructorUsedError;
|
||||||
|
String get label => throw _privateConstructorUsedError;
|
||||||
|
String get type => throw _privateConstructorUsedError;
|
||||||
|
String get source => throw _privateConstructorUsedError;
|
||||||
|
int get depth => throw _privateConstructorUsedError;
|
||||||
|
bool get enabled => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this SnNewsSource to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsSource
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$SnNewsSourceCopyWith<SnNewsSource> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $SnNewsSourceCopyWith<$Res> {
|
||||||
|
factory $SnNewsSourceCopyWith(
|
||||||
|
SnNewsSource value, $Res Function(SnNewsSource) then) =
|
||||||
|
_$SnNewsSourceCopyWithImpl<$Res, SnNewsSource>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{String id,
|
||||||
|
String label,
|
||||||
|
String type,
|
||||||
|
String source,
|
||||||
|
int depth,
|
||||||
|
bool enabled});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnNewsSourceCopyWithImpl<$Res, $Val extends SnNewsSource>
|
||||||
|
implements $SnNewsSourceCopyWith<$Res> {
|
||||||
|
_$SnNewsSourceCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsSource
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? label = null,
|
||||||
|
Object? type = null,
|
||||||
|
Object? source = null,
|
||||||
|
Object? depth = null,
|
||||||
|
Object? enabled = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
label: null == label
|
||||||
|
? _value.label
|
||||||
|
: label // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
type: null == type
|
||||||
|
? _value.type
|
||||||
|
: type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
source: null == source
|
||||||
|
? _value.source
|
||||||
|
: source // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
depth: null == depth
|
||||||
|
? _value.depth
|
||||||
|
: depth // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
enabled: null == enabled
|
||||||
|
? _value.enabled
|
||||||
|
: enabled // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$SnNewsSourceImplCopyWith<$Res>
|
||||||
|
implements $SnNewsSourceCopyWith<$Res> {
|
||||||
|
factory _$$SnNewsSourceImplCopyWith(
|
||||||
|
_$SnNewsSourceImpl value, $Res Function(_$SnNewsSourceImpl) then) =
|
||||||
|
__$$SnNewsSourceImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{String id,
|
||||||
|
String label,
|
||||||
|
String type,
|
||||||
|
String source,
|
||||||
|
int depth,
|
||||||
|
bool enabled});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$SnNewsSourceImplCopyWithImpl<$Res>
|
||||||
|
extends _$SnNewsSourceCopyWithImpl<$Res, _$SnNewsSourceImpl>
|
||||||
|
implements _$$SnNewsSourceImplCopyWith<$Res> {
|
||||||
|
__$$SnNewsSourceImplCopyWithImpl(
|
||||||
|
_$SnNewsSourceImpl _value, $Res Function(_$SnNewsSourceImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsSource
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? label = null,
|
||||||
|
Object? type = null,
|
||||||
|
Object? source = null,
|
||||||
|
Object? depth = null,
|
||||||
|
Object? enabled = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$SnNewsSourceImpl(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
label: null == label
|
||||||
|
? _value.label
|
||||||
|
: label // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
type: null == type
|
||||||
|
? _value.type
|
||||||
|
: type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
source: null == source
|
||||||
|
? _value.source
|
||||||
|
: source // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
depth: null == depth
|
||||||
|
? _value.depth
|
||||||
|
: depth // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
enabled: null == enabled
|
||||||
|
? _value.enabled
|
||||||
|
: enabled // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$SnNewsSourceImpl implements _SnNewsSource {
|
||||||
|
const _$SnNewsSourceImpl(
|
||||||
|
{required this.id,
|
||||||
|
required this.label,
|
||||||
|
required this.type,
|
||||||
|
required this.source,
|
||||||
|
required this.depth,
|
||||||
|
required this.enabled});
|
||||||
|
|
||||||
|
factory _$SnNewsSourceImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$SnNewsSourceImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String id;
|
||||||
|
@override
|
||||||
|
final String label;
|
||||||
|
@override
|
||||||
|
final String type;
|
||||||
|
@override
|
||||||
|
final String source;
|
||||||
|
@override
|
||||||
|
final int depth;
|
||||||
|
@override
|
||||||
|
final bool enabled;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnNewsSource(id: $id, label: $label, type: $type, source: $source, depth: $depth, enabled: $enabled)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$SnNewsSourceImpl &&
|
||||||
|
(identical(other.id, id) || other.id == id) &&
|
||||||
|
(identical(other.label, label) || other.label == label) &&
|
||||||
|
(identical(other.type, type) || other.type == type) &&
|
||||||
|
(identical(other.source, source) || other.source == source) &&
|
||||||
|
(identical(other.depth, depth) || other.depth == depth) &&
|
||||||
|
(identical(other.enabled, enabled) || other.enabled == enabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
Object.hash(runtimeType, id, label, type, source, depth, enabled);
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsSource
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$SnNewsSourceImplCopyWith<_$SnNewsSourceImpl> get copyWith =>
|
||||||
|
__$$SnNewsSourceImplCopyWithImpl<_$SnNewsSourceImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$SnNewsSourceImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _SnNewsSource implements SnNewsSource {
|
||||||
|
const factory _SnNewsSource(
|
||||||
|
{required final String id,
|
||||||
|
required final String label,
|
||||||
|
required final String type,
|
||||||
|
required final String source,
|
||||||
|
required final int depth,
|
||||||
|
required final bool enabled}) = _$SnNewsSourceImpl;
|
||||||
|
|
||||||
|
factory _SnNewsSource.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$SnNewsSourceImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get id;
|
||||||
|
@override
|
||||||
|
String get label;
|
||||||
|
@override
|
||||||
|
String get type;
|
||||||
|
@override
|
||||||
|
String get source;
|
||||||
|
@override
|
||||||
|
int get depth;
|
||||||
|
@override
|
||||||
|
bool get enabled;
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsSource
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$SnNewsSourceImplCopyWith<_$SnNewsSourceImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
SnNewsArticle _$SnNewsArticleFromJson(Map<String, dynamic> json) {
|
||||||
|
return _SnNewsArticle.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnNewsArticle {
|
||||||
|
int get id => throw _privateConstructorUsedError;
|
||||||
|
DateTime get createdAt => throw _privateConstructorUsedError;
|
||||||
|
DateTime get updatedAt => throw _privateConstructorUsedError;
|
||||||
|
dynamic get deletedAt => throw _privateConstructorUsedError;
|
||||||
|
String get thumbnail => throw _privateConstructorUsedError;
|
||||||
|
String get title => throw _privateConstructorUsedError;
|
||||||
|
String get description => throw _privateConstructorUsedError;
|
||||||
|
String get content => throw _privateConstructorUsedError;
|
||||||
|
String get url => throw _privateConstructorUsedError;
|
||||||
|
String get hash => throw _privateConstructorUsedError;
|
||||||
|
String get source => throw _privateConstructorUsedError;
|
||||||
|
dynamic get publishedAt => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this SnNewsArticle to a JSON map.
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsArticle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$SnNewsArticleCopyWith<SnNewsArticle> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $SnNewsArticleCopyWith<$Res> {
|
||||||
|
factory $SnNewsArticleCopyWith(
|
||||||
|
SnNewsArticle value, $Res Function(SnNewsArticle) then) =
|
||||||
|
_$SnNewsArticleCopyWithImpl<$Res, SnNewsArticle>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
DateTime createdAt,
|
||||||
|
DateTime updatedAt,
|
||||||
|
dynamic deletedAt,
|
||||||
|
String thumbnail,
|
||||||
|
String title,
|
||||||
|
String description,
|
||||||
|
String content,
|
||||||
|
String url,
|
||||||
|
String hash,
|
||||||
|
String source,
|
||||||
|
dynamic publishedAt});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnNewsArticleCopyWithImpl<$Res, $Val extends SnNewsArticle>
|
||||||
|
implements $SnNewsArticleCopyWith<$Res> {
|
||||||
|
_$SnNewsArticleCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsArticle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? createdAt = null,
|
||||||
|
Object? updatedAt = null,
|
||||||
|
Object? deletedAt = freezed,
|
||||||
|
Object? thumbnail = null,
|
||||||
|
Object? title = null,
|
||||||
|
Object? description = null,
|
||||||
|
Object? content = null,
|
||||||
|
Object? url = null,
|
||||||
|
Object? hash = null,
|
||||||
|
Object? source = null,
|
||||||
|
Object? publishedAt = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
createdAt: null == createdAt
|
||||||
|
? _value.createdAt
|
||||||
|
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
updatedAt: null == updatedAt
|
||||||
|
? _value.updatedAt
|
||||||
|
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
deletedAt: freezed == deletedAt
|
||||||
|
? _value.deletedAt
|
||||||
|
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as dynamic,
|
||||||
|
thumbnail: null == thumbnail
|
||||||
|
? _value.thumbnail
|
||||||
|
: thumbnail // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
title: null == title
|
||||||
|
? _value.title
|
||||||
|
: title // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
description: null == description
|
||||||
|
? _value.description
|
||||||
|
: description // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
content: null == content
|
||||||
|
? _value.content
|
||||||
|
: content // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
url: null == url
|
||||||
|
? _value.url
|
||||||
|
: url // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
hash: null == hash
|
||||||
|
? _value.hash
|
||||||
|
: hash // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
source: null == source
|
||||||
|
? _value.source
|
||||||
|
: source // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
publishedAt: freezed == publishedAt
|
||||||
|
? _value.publishedAt
|
||||||
|
: publishedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as dynamic,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$SnNewsArticleImplCopyWith<$Res>
|
||||||
|
implements $SnNewsArticleCopyWith<$Res> {
|
||||||
|
factory _$$SnNewsArticleImplCopyWith(
|
||||||
|
_$SnNewsArticleImpl value, $Res Function(_$SnNewsArticleImpl) then) =
|
||||||
|
__$$SnNewsArticleImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{int id,
|
||||||
|
DateTime createdAt,
|
||||||
|
DateTime updatedAt,
|
||||||
|
dynamic deletedAt,
|
||||||
|
String thumbnail,
|
||||||
|
String title,
|
||||||
|
String description,
|
||||||
|
String content,
|
||||||
|
String url,
|
||||||
|
String hash,
|
||||||
|
String source,
|
||||||
|
dynamic publishedAt});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$SnNewsArticleImplCopyWithImpl<$Res>
|
||||||
|
extends _$SnNewsArticleCopyWithImpl<$Res, _$SnNewsArticleImpl>
|
||||||
|
implements _$$SnNewsArticleImplCopyWith<$Res> {
|
||||||
|
__$$SnNewsArticleImplCopyWithImpl(
|
||||||
|
_$SnNewsArticleImpl _value, $Res Function(_$SnNewsArticleImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsArticle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = null,
|
||||||
|
Object? createdAt = null,
|
||||||
|
Object? updatedAt = null,
|
||||||
|
Object? deletedAt = freezed,
|
||||||
|
Object? thumbnail = null,
|
||||||
|
Object? title = null,
|
||||||
|
Object? description = null,
|
||||||
|
Object? content = null,
|
||||||
|
Object? url = null,
|
||||||
|
Object? hash = null,
|
||||||
|
Object? source = null,
|
||||||
|
Object? publishedAt = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_$SnNewsArticleImpl(
|
||||||
|
id: null == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
createdAt: null == createdAt
|
||||||
|
? _value.createdAt
|
||||||
|
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
updatedAt: null == updatedAt
|
||||||
|
? _value.updatedAt
|
||||||
|
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,
|
||||||
|
deletedAt: freezed == deletedAt
|
||||||
|
? _value.deletedAt
|
||||||
|
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as dynamic,
|
||||||
|
thumbnail: null == thumbnail
|
||||||
|
? _value.thumbnail
|
||||||
|
: thumbnail // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
title: null == title
|
||||||
|
? _value.title
|
||||||
|
: title // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
description: null == description
|
||||||
|
? _value.description
|
||||||
|
: description // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
content: null == content
|
||||||
|
? _value.content
|
||||||
|
: content // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
url: null == url
|
||||||
|
? _value.url
|
||||||
|
: url // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
hash: null == hash
|
||||||
|
? _value.hash
|
||||||
|
: hash // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
source: null == source
|
||||||
|
? _value.source
|
||||||
|
: source // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
publishedAt: freezed == publishedAt
|
||||||
|
? _value.publishedAt
|
||||||
|
: publishedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as dynamic,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$SnNewsArticleImpl implements _SnNewsArticle {
|
||||||
|
const _$SnNewsArticleImpl(
|
||||||
|
{required this.id,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.deletedAt,
|
||||||
|
required this.thumbnail,
|
||||||
|
required this.title,
|
||||||
|
required this.description,
|
||||||
|
required this.content,
|
||||||
|
required this.url,
|
||||||
|
required this.hash,
|
||||||
|
required this.source,
|
||||||
|
required this.publishedAt});
|
||||||
|
|
||||||
|
factory _$SnNewsArticleImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$SnNewsArticleImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final int id;
|
||||||
|
@override
|
||||||
|
final DateTime createdAt;
|
||||||
|
@override
|
||||||
|
final DateTime updatedAt;
|
||||||
|
@override
|
||||||
|
final dynamic deletedAt;
|
||||||
|
@override
|
||||||
|
final String thumbnail;
|
||||||
|
@override
|
||||||
|
final String title;
|
||||||
|
@override
|
||||||
|
final String description;
|
||||||
|
@override
|
||||||
|
final String content;
|
||||||
|
@override
|
||||||
|
final String url;
|
||||||
|
@override
|
||||||
|
final String hash;
|
||||||
|
@override
|
||||||
|
final String source;
|
||||||
|
@override
|
||||||
|
final dynamic publishedAt;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnNewsArticle(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, thumbnail: $thumbnail, title: $title, description: $description, content: $content, url: $url, hash: $hash, source: $source, publishedAt: $publishedAt)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$SnNewsArticleImpl &&
|
||||||
|
(identical(other.id, id) || other.id == id) &&
|
||||||
|
(identical(other.createdAt, createdAt) ||
|
||||||
|
other.createdAt == createdAt) &&
|
||||||
|
(identical(other.updatedAt, updatedAt) ||
|
||||||
|
other.updatedAt == updatedAt) &&
|
||||||
|
const DeepCollectionEquality().equals(other.deletedAt, deletedAt) &&
|
||||||
|
(identical(other.thumbnail, thumbnail) ||
|
||||||
|
other.thumbnail == thumbnail) &&
|
||||||
|
(identical(other.title, title) || other.title == title) &&
|
||||||
|
(identical(other.description, description) ||
|
||||||
|
other.description == description) &&
|
||||||
|
(identical(other.content, content) || other.content == content) &&
|
||||||
|
(identical(other.url, url) || other.url == url) &&
|
||||||
|
(identical(other.hash, hash) || other.hash == hash) &&
|
||||||
|
(identical(other.source, source) || other.source == source) &&
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other.publishedAt, publishedAt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
id,
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
const DeepCollectionEquality().hash(deletedAt),
|
||||||
|
thumbnail,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
content,
|
||||||
|
url,
|
||||||
|
hash,
|
||||||
|
source,
|
||||||
|
const DeepCollectionEquality().hash(publishedAt));
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsArticle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$SnNewsArticleImplCopyWith<_$SnNewsArticleImpl> get copyWith =>
|
||||||
|
__$$SnNewsArticleImplCopyWithImpl<_$SnNewsArticleImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$SnNewsArticleImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _SnNewsArticle implements SnNewsArticle {
|
||||||
|
const factory _SnNewsArticle(
|
||||||
|
{required final int id,
|
||||||
|
required final DateTime createdAt,
|
||||||
|
required final DateTime updatedAt,
|
||||||
|
required final dynamic deletedAt,
|
||||||
|
required final String thumbnail,
|
||||||
|
required final String title,
|
||||||
|
required final String description,
|
||||||
|
required final String content,
|
||||||
|
required final String url,
|
||||||
|
required final String hash,
|
||||||
|
required final String source,
|
||||||
|
required final dynamic publishedAt}) = _$SnNewsArticleImpl;
|
||||||
|
|
||||||
|
factory _SnNewsArticle.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$SnNewsArticleImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get id;
|
||||||
|
@override
|
||||||
|
DateTime get createdAt;
|
||||||
|
@override
|
||||||
|
DateTime get updatedAt;
|
||||||
|
@override
|
||||||
|
dynamic get deletedAt;
|
||||||
|
@override
|
||||||
|
String get thumbnail;
|
||||||
|
@override
|
||||||
|
String get title;
|
||||||
|
@override
|
||||||
|
String get description;
|
||||||
|
@override
|
||||||
|
String get content;
|
||||||
|
@override
|
||||||
|
String get url;
|
||||||
|
@override
|
||||||
|
String get hash;
|
||||||
|
@override
|
||||||
|
String get source;
|
||||||
|
@override
|
||||||
|
dynamic get publishedAt;
|
||||||
|
|
||||||
|
/// Create a copy of SnNewsArticle
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$SnNewsArticleImplCopyWith<_$SnNewsArticleImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
59
lib/types/news.g.dart
Normal file
59
lib/types/news.g.dart
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'news.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$SnNewsSourceImpl _$$SnNewsSourceImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnNewsSourceImpl(
|
||||||
|
id: json['id'] as String,
|
||||||
|
label: json['label'] as String,
|
||||||
|
type: json['type'] as String,
|
||||||
|
source: json['source'] as String,
|
||||||
|
depth: (json['depth'] as num).toInt(),
|
||||||
|
enabled: json['enabled'] as bool,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$SnNewsSourceImplToJson(_$SnNewsSourceImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'label': instance.label,
|
||||||
|
'type': instance.type,
|
||||||
|
'source': instance.source,
|
||||||
|
'depth': instance.depth,
|
||||||
|
'enabled': instance.enabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$SnNewsArticleImpl _$$SnNewsArticleImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnNewsArticleImpl(
|
||||||
|
id: (json['id'] as num).toInt(),
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt: json['deleted_at'],
|
||||||
|
thumbnail: json['thumbnail'] as String,
|
||||||
|
title: json['title'] as String,
|
||||||
|
description: json['description'] as String,
|
||||||
|
content: json['content'] as String,
|
||||||
|
url: json['url'] as String,
|
||||||
|
hash: json['hash'] as String,
|
||||||
|
source: json['source'] as String,
|
||||||
|
publishedAt: json['published_at'],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$SnNewsArticleImplToJson(_$SnNewsArticleImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
|
'deleted_at': instance.deletedAt,
|
||||||
|
'thumbnail': instance.thumbnail,
|
||||||
|
'title': instance.title,
|
||||||
|
'description': instance.description,
|
||||||
|
'content': instance.content,
|
||||||
|
'url': instance.url,
|
||||||
|
'hash': instance.hash,
|
||||||
|
'source': instance.source,
|
||||||
|
'published_at': instance.publishedAt,
|
||||||
|
};
|
@ -13,6 +13,7 @@ import file_selector_macos
|
|||||||
import firebase_analytics
|
import firebase_analytics
|
||||||
import firebase_core
|
import firebase_core
|
||||||
import firebase_messaging
|
import firebase_messaging
|
||||||
|
import flutter_inappwebview_macos
|
||||||
import flutter_udid
|
import flutter_udid
|
||||||
import flutter_webrtc
|
import flutter_webrtc
|
||||||
import gal
|
import gal
|
||||||
@ -40,6 +41,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin"))
|
FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin"))
|
||||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||||
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
|
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
|
||||||
|
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
|
||||||
FlutterUdidPlugin.register(with: registry.registrar(forPlugin: "FlutterUdidPlugin"))
|
FlutterUdidPlugin.register(with: registry.registrar(forPlugin: "FlutterUdidPlugin"))
|
||||||
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
||||||
GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
|
GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
|
||||||
|
64
pubspec.lock
64
pubspec.lock
@ -675,6 +675,70 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
|
flutter_inappwebview:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview
|
||||||
|
sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.5"
|
||||||
|
flutter_inappwebview_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_android
|
||||||
|
sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.3"
|
||||||
|
flutter_inappwebview_internal_annotations:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_internal_annotations
|
||||||
|
sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.0"
|
||||||
|
flutter_inappwebview_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_ios
|
||||||
|
sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_inappwebview_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_macos
|
||||||
|
sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_inappwebview_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_platform_interface
|
||||||
|
sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0+1"
|
||||||
|
flutter_inappwebview_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_web
|
||||||
|
sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.2"
|
||||||
|
flutter_inappwebview_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_inappwebview_windows
|
||||||
|
sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.6.0"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -115,6 +115,7 @@ dependencies:
|
|||||||
slide_countdown: ^2.0.2
|
slide_countdown: ^2.0.2
|
||||||
video_compress: ^3.1.3
|
video_compress: ^3.1.3
|
||||||
cached_network_image: ^3.4.1
|
cached_network_image: ^3.4.1
|
||||||
|
flutter_inappwebview: ^6.1.5
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
-->
|
-->
|
||||||
<base href="$FLUTTER_BASE_HREF">
|
<base href="$FLUTTER_BASE_HREF">
|
||||||
|
|
||||||
|
<script type="application/javascript" src="/assets/packages/flutter_inappwebview_web/assets/web/web_support.js" defer></script>
|
||||||
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||||
<meta name="description" content="A new Flutter project.">
|
<meta name="description" content="A new Flutter project.">
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <file_saver/file_saver_plugin.h>
|
#include <file_saver/file_saver_plugin.h>
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||||
|
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
|
||||||
#include <flutter_udid/flutter_udid_plugin_c_api.h>
|
#include <flutter_udid/flutter_udid_plugin_c_api.h>
|
||||||
#include <flutter_webrtc/flutter_web_r_t_c_plugin.h>
|
#include <flutter_webrtc/flutter_web_r_t_c_plugin.h>
|
||||||
#include <gal/gal_plugin_c_api.h>
|
#include <gal/gal_plugin_c_api.h>
|
||||||
@ -34,6 +35,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||||
FirebaseCorePluginCApiRegisterWithRegistrar(
|
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||||
|
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
|
||||||
FlutterUdidPluginCApiRegisterWithRegistrar(
|
FlutterUdidPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FlutterUdidPluginCApi"));
|
registry->GetRegistrarForPlugin("FlutterUdidPluginCApi"));
|
||||||
FlutterWebRTCPluginRegisterWithRegistrar(
|
FlutterWebRTCPluginRegisterWithRegistrar(
|
||||||
|
@ -8,6 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
file_saver
|
file_saver
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
firebase_core
|
firebase_core
|
||||||
|
flutter_inappwebview_windows
|
||||||
flutter_udid
|
flutter_udid
|
||||||
flutter_webrtc
|
flutter_webrtc
|
||||||
gal
|
gal
|
||||||
|
Loading…
x
Reference in New Issue
Block a user