Compare commits
	
		
			10 Commits
		
	
	
		
			2.2.1+44
			...
			57279eb3e4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 57279eb3e4 | |||
| c403a2914a | |||
| bcb176344c | |||
| ecf362cffc | |||
| f4ab7671d8 | |||
| a2a3018917 | |||
| 0bdb664000 | |||
| 9c3b61ce57 | |||
| d06df3d278 | |||
| 547ba19e61 | 
| @@ -7,11 +7,7 @@ meta { | ||||
| post { | ||||
|   url: {{endpoint}}/cgi/uc/boosts/1/activate | ||||
|   body: none | ||||
|   auth: bearer | ||||
| } | ||||
|  | ||||
| auth:bearer { | ||||
|   token: {{atk}} | ||||
|   auth: inherit | ||||
| } | ||||
|  | ||||
| body:json { | ||||
|   | ||||
							
								
								
									
										19
									
								
								api/Paperclip/Stickers/Create Sticker Pack.bru
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								api/Paperclip/Stickers/Create Sticker Pack.bru
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| meta { | ||||
|   name: Create Sticker Pack | ||||
|   type: http | ||||
|   seq: 1 | ||||
| } | ||||
|  | ||||
| post { | ||||
|   url: {{endpoint}}/cgi/uc/stickers/packs | ||||
|   body: json | ||||
|   auth: inherit | ||||
| } | ||||
|  | ||||
| body:json { | ||||
|   { | ||||
|     "prefix": "cat", | ||||
|     "name": "Solar Network full of Cats!", | ||||
|     "description": "The sticker packs is full of stickers which related with cats!" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										20
									
								
								api/Paperclip/Stickers/Create Sticker.bru
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								api/Paperclip/Stickers/Create Sticker.bru
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| meta { | ||||
|   name: Create Sticker | ||||
|   type: http | ||||
|   seq: 2 | ||||
| } | ||||
|  | ||||
| post { | ||||
|   url: {{endpoint}}/cgi/uc/stickers | ||||
|   body: json | ||||
|   auth: inherit | ||||
| } | ||||
|  | ||||
| body:json { | ||||
|   { | ||||
|     "alias": "AteChip", | ||||
|     "name": "Cat ate chips", | ||||
|     "attachment_id": "d0b692cc64054463", | ||||
|     "pack_id": 2 | ||||
|   } | ||||
| } | ||||
| @@ -7,11 +7,7 @@ meta { | ||||
| post { | ||||
|   url: {{endpoint}}/cgi/id/dev/notify/all | ||||
|   body: json | ||||
|   auth: bearer | ||||
| } | ||||
|  | ||||
| auth:bearer { | ||||
|   token: {{atk}} | ||||
|   auth: inherit | ||||
| } | ||||
|  | ||||
| body:json { | ||||
|   | ||||
							
								
								
									
										7
									
								
								api/collection.bru
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								api/collection.bru
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| auth { | ||||
|   mode: bearer | ||||
| } | ||||
|  | ||||
| auth:bearer { | ||||
|   token: {{atk}} | ||||
| } | ||||
| @@ -414,6 +414,9 @@ | ||||
|   "celebrateBirthday": "Happy birthday, {}!", | ||||
|   "celebrateMerryXmas": "Merry christmas, {}!", | ||||
|   "celebrateNewYear": "Happy new year, {}!", | ||||
|   "celebrateLunarNewYear": "Happy lunar new year, {}!", | ||||
|   "celebrateMidAutumn": "Happy mid-autumn festival, {}!", | ||||
|   "celebrateDragonBoat": "Happy dragon boat festival, {}!", | ||||
|   "celebrateValentineDay": "Today is valentine's day, {}!", | ||||
|   "celebrateLaborDay": "Today is labor day, {}.", | ||||
|   "celebrateMotherDay": "Today is mother's day, {}.", | ||||
| @@ -423,6 +426,9 @@ | ||||
|   "celebrateThanksgiving": "Today is thanksgiving day, {}!", | ||||
|   "pendingBirthday": "Birthday in {}", | ||||
|   "pendingMerryXmas": "Christmas in {}", | ||||
|   "pendingLunarNewYear": "Lunar new year in {}", | ||||
|   "pendingMidAutumn": "Mid-autumn festival in {}", | ||||
|   "pendingDragonBoat": "Dragon boat festival in {}", | ||||
|   "pendingNewYear": "New year in {}", | ||||
|   "pendingValentineDay": "Valentine's day in {}", | ||||
|   "pendingLaborDay": "Labor day in {}", | ||||
|   | ||||
| @@ -410,6 +410,9 @@ | ||||
|   "dailyCheckNegativeHint6": "出门", | ||||
|   "dailyCheckNegativeHint6Description": "忘带伞遇上大雨", | ||||
|   "celebrateBirthday": "生日快乐,{}!", | ||||
|   "celebrateLunarNewYear": "春节快乐,{}!", | ||||
|   "celebrateMidAutumn": "中秋节快乐,{}!", | ||||
|   "celebrateDragonBoat": "端午节快乐,{}!", | ||||
|   "celebrateMerryXmas": "圣诞快乐,{}!", | ||||
|   "celebrateNewYear": "新年快乐,{}!", | ||||
|   "celebrateValentineDay": "今天是情人节,{}!", | ||||
| @@ -419,6 +422,9 @@ | ||||
|   "celebrateFatherDay": "今天是父亲节,{}。", | ||||
|   "celebrateHalloween": "快乐在圣诞节,{}!", | ||||
|   "celebrateThanksgiving": "今天是感恩节,{}!", | ||||
|   "pendingLunarNewYear": "{} 过春节", | ||||
|   "pendingMidAutumn": "{} 过中秋节", | ||||
|   "pendingDragonBoat": "{} 过端午节", | ||||
|   "pendingBirthday": "{} 过生日", | ||||
|   "pendingMerryXmas": "{} 过圣诞节", | ||||
|   "pendingNewYear": "{} 跨年", | ||||
|   | ||||
| @@ -279,6 +279,10 @@ | ||||
|     "one": "{} 個附件", | ||||
|     "other": "{} 個附件" | ||||
|   }, | ||||
|   "messageTyping": { | ||||
|     "one": "{} 正在輸入", | ||||
|     "other": "{} 正在輸入" | ||||
|   }, | ||||
|   "fieldAttachmentRandomId": "訪問 ID", | ||||
|   "fieldAttachmentAlt": "概述文字", | ||||
|   "addAttachmentFromAlbum": "從相冊中添加附件", | ||||
| @@ -406,6 +410,9 @@ | ||||
|   "dailyCheckNegativeHint6": "出門", | ||||
|   "dailyCheckNegativeHint6Description": "忘帶傘遇上大雨", | ||||
|   "celebrateBirthday": "生日快樂,{}!", | ||||
|   "celebrateLunarNewYear": "春節快樂,{}!", | ||||
|   "celebrateMidAutumn": "中秋節快樂,{}!", | ||||
|   "celebrateDragonBoat": "端午節快樂,{}!", | ||||
|   "celebrateMerryXmas": "聖誕快樂,{}!", | ||||
|   "celebrateNewYear": "新年快樂,{}!", | ||||
|   "celebrateValentineDay": "今天是情人節,{}!", | ||||
| @@ -415,6 +422,9 @@ | ||||
|   "celebrateFatherDay": "今天是父親節,{}。", | ||||
|   "celebrateHalloween": "快樂在聖誕節,{}!", | ||||
|   "celebrateThanksgiving": "今天是感恩節,{}!", | ||||
|   "pendingLunarNewYear": "{} 過春節", | ||||
|   "pendingMidAutumn": "{} 過中秋節", | ||||
|   "pendingDragonBoat": "{} 過端午節", | ||||
|   "pendingBirthday": "{} 過生日", | ||||
|   "pendingMerryXmas": "{} 過聖誕節", | ||||
|   "pendingNewYear": "{} 跨年", | ||||
|   | ||||
| @@ -279,6 +279,10 @@ | ||||
|     "one": "{} 個附件", | ||||
|     "other": "{} 個附件" | ||||
|   }, | ||||
|   "messageTyping": { | ||||
|     "one": "{} 正在輸入", | ||||
|     "other": "{} 正在輸入" | ||||
|   }, | ||||
|   "fieldAttachmentRandomId": "訪問 ID", | ||||
|   "fieldAttachmentAlt": "概述文字", | ||||
|   "addAttachmentFromAlbum": "從相冊中添加附件", | ||||
| @@ -406,6 +410,9 @@ | ||||
|   "dailyCheckNegativeHint6": "出門", | ||||
|   "dailyCheckNegativeHint6Description": "忘帶傘遇上大雨", | ||||
|   "celebrateBirthday": "生日快樂,{}!", | ||||
|   "celebrateLunarNewYear": "春節快樂,{}!", | ||||
|   "celebrateMidAutumn": "中秋節快樂,{}!", | ||||
|   "celebrateDragonBoat": "端午節快樂,{}!", | ||||
|   "celebrateMerryXmas": "聖誕快樂,{}!", | ||||
|   "celebrateNewYear": "新年快樂,{}!", | ||||
|   "celebrateValentineDay": "今天是情人節,{}!", | ||||
| @@ -415,6 +422,9 @@ | ||||
|   "celebrateFatherDay": "今天是父親節,{}。", | ||||
|   "celebrateHalloween": "快樂在聖誕節,{}!", | ||||
|   "celebrateThanksgiving": "今天是感恩節,{}!", | ||||
|   "pendingLunarNewYear": "{} 過春節", | ||||
|   "pendingMidAutumn": "{} 過中秋節", | ||||
|   "pendingDragonBoat": "{} 過端午節", | ||||
|   "pendingBirthday": "{} 過生日", | ||||
|   "pendingMerryXmas": "{} 過聖誕節", | ||||
|   "pendingNewYear": "{} 跨年", | ||||
|   | ||||
| @@ -380,7 +380,7 @@ SPEC CHECKSUMS: | ||||
|   FirebaseMessaging: f8a160d99c2c2e5babbbcc90c4a3e15db036aee2 | ||||
|   Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 | ||||
|   flutter_app_update: 65f61da626cb111d1b24674abc4b01728d7723bc | ||||
|   flutter_native_splash: e8a1e01082d97a8099d973f919f57904c925008a | ||||
|   flutter_native_splash: f71420956eb811e6d310720fee915f1d42852e7a | ||||
|   flutter_udid: b2417673f287ee62817a1de3d1643f47b9f508ab | ||||
|   flutter_webrtc: 1a53bd24f97bcfeff512f13699e721897f261563 | ||||
|   gal: 6a522c75909f1244732d4596d11d6a2f86ff37a5 | ||||
|   | ||||
| @@ -83,7 +83,6 @@ class ChatMessageController extends ChangeNotifier { | ||||
|           if (member.id == profile?.id) break; | ||||
|           if (!typingMembers.any((x) => x.id == member.id)) { | ||||
|             typingMembers.add(member); | ||||
|             print('Typing member: ${typingMembers.map((ele) => member.id)}'); | ||||
|             notifyListeners(); | ||||
|           } | ||||
|           typingInactiveTimer[member.id]?.cancel(); | ||||
|   | ||||
| @@ -623,13 +623,15 @@ class PostWriteController extends ChangeNotifier { | ||||
|   void reset() { | ||||
|     publishedAt = null; | ||||
|     publishedUntil = null; | ||||
|     thumbnail = null; | ||||
|     visibility = 0; | ||||
|     titleController.clear(); | ||||
|     descriptionController.clear(); | ||||
|     contentController.clear(); | ||||
|     aliasController.clear(); | ||||
|     tags.clear(); | ||||
|     categories.clear(); | ||||
|     attachments.clear(); | ||||
|     tags = List.empty(growable: true); | ||||
|     categories = List.empty(growable: true); | ||||
|     attachments = List.empty(growable: true); | ||||
|     editingPost = null; | ||||
|     replyingPost = null; | ||||
|     repostingPost = null; | ||||
|   | ||||
| @@ -10,7 +10,6 @@ import 'package:easy_localization_loader/easy_localization_loader.dart'; | ||||
| import 'package:firebase_core/firebase_core.dart'; | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:gap/gap.dart'; | ||||
| import 'package:go_router/go_router.dart'; | ||||
| import 'package:hive_flutter/hive_flutter.dart'; | ||||
| import 'package:package_info_plus/package_info_plus.dart'; | ||||
| @@ -18,7 +17,6 @@ import 'package:provider/provider.dart'; | ||||
| import 'package:relative_time/relative_time.dart'; | ||||
| import 'package:responsive_framework/responsive_framework.dart'; | ||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||
| import 'package:styled_widget/styled_widget.dart'; | ||||
| import 'package:surface/firebase_options.dart'; | ||||
| import 'package:surface/providers/channel.dart'; | ||||
| import 'package:surface/providers/chat_call.dart'; | ||||
| @@ -30,6 +28,7 @@ import 'package:surface/providers/post.dart'; | ||||
| import 'package:surface/providers/relationship.dart'; | ||||
| import 'package:surface/providers/sn_attachment.dart'; | ||||
| import 'package:surface/providers/sn_network.dart'; | ||||
| import 'package:surface/providers/sn_sticker.dart'; | ||||
| import 'package:surface/providers/special_day.dart'; | ||||
| import 'package:surface/providers/theme.dart'; | ||||
| import 'package:surface/providers/user_directory.dart'; | ||||
| @@ -41,7 +40,6 @@ import 'package:surface/types/chat.dart'; | ||||
| import 'package:surface/types/realm.dart'; | ||||
| import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy; | ||||
| import 'package:surface/widgets/dialog.dart'; | ||||
| import 'package:surface/widgets/version_label.dart'; | ||||
| import 'package:version/version.dart'; | ||||
| import 'package:workmanager/workmanager.dart'; | ||||
| import 'package:in_app_review/in_app_review.dart'; | ||||
| @@ -144,6 +142,7 @@ class SolianApp extends StatelessWidget { | ||||
|             Provider(create: (ctx) => SnPostContentProvider(ctx)), | ||||
|             Provider(create: (ctx) => SnRelationshipProvider(ctx)), | ||||
|             Provider(create: (ctx) => SnLinkPreviewProvider(ctx)), | ||||
|             Provider(create: (ctx) => SnStickerProvider(ctx)), | ||||
|             ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)), | ||||
|             ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)), | ||||
|             ChangeNotifierProvider(create: (ctx) => NotificationProvider(ctx)), | ||||
| @@ -208,8 +207,6 @@ class _AppSplashScreen extends StatefulWidget { | ||||
| } | ||||
|  | ||||
| class _AppSplashScreenState extends State<_AppSplashScreen> { | ||||
|   bool _isReady = false; | ||||
|  | ||||
|   void _tryRequestRating() async { | ||||
|     final prefs = await SharedPreferences.getInstance(); | ||||
|     if (prefs.containsKey('first_boot_time')) { | ||||
| @@ -282,8 +279,6 @@ class _AppSplashScreenState extends State<_AppSplashScreen> { | ||||
|     } catch (err) { | ||||
|       if (!mounted) return; | ||||
|       await context.showErrorDialog(err); | ||||
|     } finally { | ||||
|       setState(() => _isReady = true); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -303,32 +298,6 @@ class _AppSplashScreenState extends State<_AppSplashScreen> { | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     if (!_isReady) { | ||||
|       return Scaffold( | ||||
|         backgroundColor: Theme.of(context).colorScheme.surface, | ||||
|         body: Container( | ||||
|           constraints: const BoxConstraints(maxWidth: 180), | ||||
|           child: Column( | ||||
|             mainAxisAlignment: MainAxisAlignment.center, | ||||
|             mainAxisSize: MainAxisSize.min, | ||||
|             children: [ | ||||
|               if (MediaQuery.of(context).platformBrightness == Brightness.dark) | ||||
|                 Image.asset("assets/icon/icon-dark.png", width: 64, height: 64) | ||||
|               else | ||||
|                 Image.asset("assets/icon/icon.png", width: 64, height: 64), | ||||
|               const Gap(6), | ||||
|               LinearProgressIndicator( | ||||
|                 backgroundColor: Theme.of(context).colorScheme.surfaceContainer, | ||||
|               ), | ||||
|               const Gap(20), | ||||
|               Text('appInitializing'.tr(), textAlign: TextAlign.center), | ||||
|               AppVersionLabel(), | ||||
|             ], | ||||
|           ), | ||||
|         ).center(), | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     return widget.child; | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										38
									
								
								lib/providers/sn_sticker.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								lib/providers/sn_sticker.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| import 'dart:developer'; | ||||
|  | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:surface/providers/sn_network.dart'; | ||||
| import 'package:surface/types/attachment.dart'; | ||||
|  | ||||
| class SnStickerProvider { | ||||
|   late final SnNetworkProvider _sn; | ||||
|   final Map<String, SnSticker?> _cache = {}; | ||||
|  | ||||
|   SnStickerProvider(BuildContext context) { | ||||
|     _sn = context.read<SnNetworkProvider>(); | ||||
|   } | ||||
|  | ||||
|   bool hasNotSticker(String alias) { | ||||
|     return _cache.containsKey(alias) && _cache[alias] == null; | ||||
|   } | ||||
|  | ||||
|   Future<SnSticker?> lookupSticker(String alias) async { | ||||
|     if (_cache.containsKey(alias)) { | ||||
|       return _cache[alias]; | ||||
|     } | ||||
|  | ||||
|     try { | ||||
|       final resp = await _sn.client.get('/cgi/uc/stickers/lookup/$alias'); | ||||
|       final sticker = SnSticker.fromJson(resp.data); | ||||
|       _cache[alias] = sticker; | ||||
|  | ||||
|       return sticker; | ||||
|     } catch (err) { | ||||
|       _cache[alias] = null; | ||||
|       log('[Sticker] Failed to lookup sticker $alias: $err'); | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
|   } | ||||
| } | ||||
| @@ -3,9 +3,12 @@ import 'package:provider/provider.dart'; | ||||
| import 'package:surface/providers/userinfo.dart'; | ||||
|  | ||||
| // Stored as key: month, day | ||||
| const Map<String, (int, int)> kSpecialDays = { | ||||
| final Map<String, (int, int)> kSpecialDays = { | ||||
|   // Birthday is dynamically generated according to the user's profile | ||||
|   'NewYear': (1, 1), | ||||
|   'LunarNewYear': (lunarToGregorian(null, 1, 1).month, lunarToGregorian(null, 1, 1).day), | ||||
|   'MidAutumn': (lunarToGregorian(null, 8, 15).month, lunarToGregorian(null, 8, 15).day), | ||||
|   'DragonBoat': (lunarToGregorian(null, 5, 5).month, lunarToGregorian(null, 5, 5).day), | ||||
|   'ValentineDay': (2, 14), | ||||
|   'LaborDay': (5, 1), | ||||
|   'MotherDay': (5, 11), | ||||
| @@ -19,6 +22,9 @@ const Map<String, (int, int)> kSpecialDays = { | ||||
| const Map<String, String> kSpecialDaysSymbol = { | ||||
|   'Birthday': '🎂', | ||||
|   'NewYear': '🎉', | ||||
|   'LunarNewYear': '🎉', | ||||
|   'MidAutumn': '🥮', | ||||
|   'DragonBoat': '🐲', | ||||
|   'MerryXmas': '🎄', | ||||
|   'ValentineDay': '💑', | ||||
|   'LaborDay': '🏋️', | ||||
| @@ -134,3 +140,45 @@ class SpecialDayProvider { | ||||
|     return (elapsedDuration / totalDuration).clamp(0.0, 1.0); | ||||
|   } | ||||
| } | ||||
|  | ||||
| final Map<int, LunarYear> lunarYearData = { | ||||
|   2025: LunarYear( | ||||
|     startDate: DateTime(2025, 1, 29), | ||||
|     months: [29, 30, 30, 29, 30, 29, 29, 30, 30, 29, 30, 29], | ||||
|     leapMonth: 0, | ||||
|   ), | ||||
| }; | ||||
|  | ||||
| class LunarYear { | ||||
|   final DateTime startDate; | ||||
|   final List<int> months; | ||||
|   final int leapMonth; | ||||
|  | ||||
|   LunarYear({required this.startDate, required this.months, required this.leapMonth}); | ||||
| } | ||||
|  | ||||
| DateTime lunarToGregorian(int? year, int month, int day, {bool isLeapMonth = false}) { | ||||
|   year = year ?? DateTime.now().year; | ||||
|   final lunarYear = lunarYearData[year]; | ||||
|   if (lunarYear == null) { | ||||
|     throw Exception('Lunar data for year $year not found'); | ||||
|   } | ||||
|  | ||||
|   int leapMonth = lunarYear.leapMonth; | ||||
|   if (isLeapMonth && (leapMonth == 0 || leapMonth != month)) { | ||||
|     throw Exception('Invalid leap month for year $year'); | ||||
|   } | ||||
|  | ||||
|   int daysFromStart = 0; | ||||
|   for (int i = 0; i < month - 1; i++) { | ||||
|     daysFromStart += lunarYear.months[i]; | ||||
|   } | ||||
|  | ||||
|   if (isLeapMonth) { | ||||
|     daysFromStart += lunarYear.months[month - 1]; | ||||
|   } | ||||
|  | ||||
|   daysFromStart += day - 1; | ||||
|  | ||||
|   return lunarYear.startDate.add(Duration(days: daysFromStart)); | ||||
| } | ||||
|   | ||||
| @@ -1,3 +0,0 @@ | ||||
| class StickerProvider { | ||||
|  | ||||
| } | ||||
| @@ -35,7 +35,7 @@ class WebSocketProvider extends ChangeNotifier { | ||||
|  | ||||
|   Future<void> connect({noRetry = false}) async { | ||||
|     if (!_ua.isAuthorized) return; | ||||
|     if (isConnected) { | ||||
|     if (isConnected || conn != null) { | ||||
|       disconnect(); | ||||
|     } | ||||
|  | ||||
| @@ -97,7 +97,7 @@ class WebSocketProvider extends ChangeNotifier { | ||||
|       onError: (err) { | ||||
|         isConnected = false; | ||||
|         notifyListeners(); | ||||
|         Future.delayed(const Duration(seconds: 11), () => connect()); | ||||
|         Future.delayed(const Duration(seconds: 1), () => connect()); | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
|   | ||||
| @@ -197,7 +197,7 @@ class _HomeDashSpecialDayWidgetState extends State<_HomeDashSpecialDayWidget> { | ||||
|       return Card( | ||||
|         child: ListTile( | ||||
|           leading: Text(kSpecialDaysSymbol[name] ?? '🎉').fontSize(24), | ||||
|           title: Text('pending$name').tr(args: [RelativeTime(context).format(date)]), | ||||
|           title: Text('pending$name').tr(args: [RelativeTime(context).format(date).replaceFirst('in', '').trim()]), | ||||
|           subtitle: Row( | ||||
|             crossAxisAlignment: CrossAxisAlignment.center, | ||||
|             children: [ | ||||
|   | ||||
| @@ -96,6 +96,8 @@ class _PostDetailScreenState extends State<PostDetailScreen> { | ||||
|                         ), | ||||
|                   ), | ||||
|                 ]), | ||||
|                 maxLines: 2, | ||||
|                 overflow: TextOverflow.ellipsis, | ||||
|               ) | ||||
|             : Text('postDetail').tr(), | ||||
|       ), | ||||
|   | ||||
| @@ -141,3 +141,39 @@ class SnAttachmentBoost with _$SnAttachmentBoost { | ||||
|  | ||||
|   factory SnAttachmentBoost.fromJson(Map<String, Object?> json) => _$SnAttachmentBoostFromJson(json); | ||||
| } | ||||
|  | ||||
| @freezed | ||||
| class SnSticker with _$SnSticker { | ||||
|   const factory SnSticker({ | ||||
|     required int id, | ||||
|     required DateTime createdAt, | ||||
|     required DateTime updatedAt, | ||||
|     required DateTime? deletedAt, | ||||
|     required String alias, | ||||
|     required String name, | ||||
|     required int attachmentId, | ||||
|     required SnAttachment attachment, | ||||
|     required int packId, | ||||
|     required SnStickerPack pack, | ||||
|     required int accountId, | ||||
|   }) = _SnSticker; | ||||
|  | ||||
|   factory SnSticker.fromJson(Map<String, Object?> json) => _$SnStickerFromJson(json); | ||||
| } | ||||
|  | ||||
| @freezed | ||||
| class SnStickerPack with _$SnStickerPack { | ||||
|   const factory SnStickerPack({ | ||||
|     required int id, | ||||
|     required DateTime createdAt, | ||||
|     required DateTime updatedAt, | ||||
|     required DateTime? deletedAt, | ||||
|     required String prefix, | ||||
|     required String name, | ||||
|     required String description, | ||||
|     required List<SnSticker>? stickers, | ||||
|     required int accountId, | ||||
|   }) = _SnStickerPack; | ||||
|  | ||||
|   factory SnStickerPack.fromJson(Map<String, Object?> json) => _$SnStickerPackFromJson(json); | ||||
| } | ||||
|   | ||||
| @@ -2272,3 +2272,738 @@ abstract class _SnAttachmentBoost implements SnAttachmentBoost { | ||||
|   _$$SnAttachmentBoostImplCopyWith<_$SnAttachmentBoostImpl> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
|  | ||||
| SnSticker _$SnStickerFromJson(Map<String, dynamic> json) { | ||||
|   return _SnSticker.fromJson(json); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| mixin _$SnSticker { | ||||
|   int get id => throw _privateConstructorUsedError; | ||||
|   DateTime get createdAt => throw _privateConstructorUsedError; | ||||
|   DateTime get updatedAt => throw _privateConstructorUsedError; | ||||
|   DateTime? get deletedAt => throw _privateConstructorUsedError; | ||||
|   String get alias => throw _privateConstructorUsedError; | ||||
|   String get name => throw _privateConstructorUsedError; | ||||
|   int get attachmentId => throw _privateConstructorUsedError; | ||||
|   SnAttachment get attachment => throw _privateConstructorUsedError; | ||||
|   int get packId => throw _privateConstructorUsedError; | ||||
|   SnStickerPack get pack => throw _privateConstructorUsedError; | ||||
|   int get accountId => throw _privateConstructorUsedError; | ||||
|  | ||||
|   /// Serializes this SnSticker to a JSON map. | ||||
|   Map<String, dynamic> toJson() => throw _privateConstructorUsedError; | ||||
|  | ||||
|   /// Create a copy of SnSticker | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   $SnStickerCopyWith<SnSticker> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class $SnStickerCopyWith<$Res> { | ||||
|   factory $SnStickerCopyWith(SnSticker value, $Res Function(SnSticker) then) = | ||||
|       _$SnStickerCopyWithImpl<$Res, SnSticker>; | ||||
|   @useResult | ||||
|   $Res call( | ||||
|       {int id, | ||||
|       DateTime createdAt, | ||||
|       DateTime updatedAt, | ||||
|       DateTime? deletedAt, | ||||
|       String alias, | ||||
|       String name, | ||||
|       int attachmentId, | ||||
|       SnAttachment attachment, | ||||
|       int packId, | ||||
|       SnStickerPack pack, | ||||
|       int accountId}); | ||||
|  | ||||
|   $SnAttachmentCopyWith<$Res> get attachment; | ||||
|   $SnStickerPackCopyWith<$Res> get pack; | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class _$SnStickerCopyWithImpl<$Res, $Val extends SnSticker> | ||||
|     implements $SnStickerCopyWith<$Res> { | ||||
|   _$SnStickerCopyWithImpl(this._value, this._then); | ||||
|  | ||||
|   // ignore: unused_field | ||||
|   final $Val _value; | ||||
|   // ignore: unused_field | ||||
|   final $Res Function($Val) _then; | ||||
|  | ||||
|   /// Create a copy of SnSticker | ||||
|   /// 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? alias = null, | ||||
|     Object? name = null, | ||||
|     Object? attachmentId = null, | ||||
|     Object? attachment = null, | ||||
|     Object? packId = null, | ||||
|     Object? pack = null, | ||||
|     Object? accountId = null, | ||||
|   }) { | ||||
|     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 DateTime?, | ||||
|       alias: null == alias | ||||
|           ? _value.alias | ||||
|           : alias // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       name: null == name | ||||
|           ? _value.name | ||||
|           : name // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       attachmentId: null == attachmentId | ||||
|           ? _value.attachmentId | ||||
|           : attachmentId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|       attachment: null == attachment | ||||
|           ? _value.attachment | ||||
|           : attachment // ignore: cast_nullable_to_non_nullable | ||||
|               as SnAttachment, | ||||
|       packId: null == packId | ||||
|           ? _value.packId | ||||
|           : packId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|       pack: null == pack | ||||
|           ? _value.pack | ||||
|           : pack // ignore: cast_nullable_to_non_nullable | ||||
|               as SnStickerPack, | ||||
|       accountId: null == accountId | ||||
|           ? _value.accountId | ||||
|           : accountId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|     ) as $Val); | ||||
|   } | ||||
|  | ||||
|   /// Create a copy of SnSticker | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @override | ||||
|   @pragma('vm:prefer-inline') | ||||
|   $SnAttachmentCopyWith<$Res> get attachment { | ||||
|     return $SnAttachmentCopyWith<$Res>(_value.attachment, (value) { | ||||
|       return _then(_value.copyWith(attachment: value) as $Val); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /// Create a copy of SnSticker | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @override | ||||
|   @pragma('vm:prefer-inline') | ||||
|   $SnStickerPackCopyWith<$Res> get pack { | ||||
|     return $SnStickerPackCopyWith<$Res>(_value.pack, (value) { | ||||
|       return _then(_value.copyWith(pack: value) as $Val); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class _$$SnStickerImplCopyWith<$Res> | ||||
|     implements $SnStickerCopyWith<$Res> { | ||||
|   factory _$$SnStickerImplCopyWith( | ||||
|           _$SnStickerImpl value, $Res Function(_$SnStickerImpl) then) = | ||||
|       __$$SnStickerImplCopyWithImpl<$Res>; | ||||
|   @override | ||||
|   @useResult | ||||
|   $Res call( | ||||
|       {int id, | ||||
|       DateTime createdAt, | ||||
|       DateTime updatedAt, | ||||
|       DateTime? deletedAt, | ||||
|       String alias, | ||||
|       String name, | ||||
|       int attachmentId, | ||||
|       SnAttachment attachment, | ||||
|       int packId, | ||||
|       SnStickerPack pack, | ||||
|       int accountId}); | ||||
|  | ||||
|   @override | ||||
|   $SnAttachmentCopyWith<$Res> get attachment; | ||||
|   @override | ||||
|   $SnStickerPackCopyWith<$Res> get pack; | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class __$$SnStickerImplCopyWithImpl<$Res> | ||||
|     extends _$SnStickerCopyWithImpl<$Res, _$SnStickerImpl> | ||||
|     implements _$$SnStickerImplCopyWith<$Res> { | ||||
|   __$$SnStickerImplCopyWithImpl( | ||||
|       _$SnStickerImpl _value, $Res Function(_$SnStickerImpl) _then) | ||||
|       : super(_value, _then); | ||||
|  | ||||
|   /// Create a copy of SnSticker | ||||
|   /// 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? alias = null, | ||||
|     Object? name = null, | ||||
|     Object? attachmentId = null, | ||||
|     Object? attachment = null, | ||||
|     Object? packId = null, | ||||
|     Object? pack = null, | ||||
|     Object? accountId = null, | ||||
|   }) { | ||||
|     return _then(_$SnStickerImpl( | ||||
|       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 DateTime?, | ||||
|       alias: null == alias | ||||
|           ? _value.alias | ||||
|           : alias // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       name: null == name | ||||
|           ? _value.name | ||||
|           : name // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       attachmentId: null == attachmentId | ||||
|           ? _value.attachmentId | ||||
|           : attachmentId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|       attachment: null == attachment | ||||
|           ? _value.attachment | ||||
|           : attachment // ignore: cast_nullable_to_non_nullable | ||||
|               as SnAttachment, | ||||
|       packId: null == packId | ||||
|           ? _value.packId | ||||
|           : packId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|       pack: null == pack | ||||
|           ? _value.pack | ||||
|           : pack // ignore: cast_nullable_to_non_nullable | ||||
|               as SnStickerPack, | ||||
|       accountId: null == accountId | ||||
|           ? _value.accountId | ||||
|           : accountId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|     )); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| @JsonSerializable() | ||||
| class _$SnStickerImpl implements _SnSticker { | ||||
|   const _$SnStickerImpl( | ||||
|       {required this.id, | ||||
|       required this.createdAt, | ||||
|       required this.updatedAt, | ||||
|       required this.deletedAt, | ||||
|       required this.alias, | ||||
|       required this.name, | ||||
|       required this.attachmentId, | ||||
|       required this.attachment, | ||||
|       required this.packId, | ||||
|       required this.pack, | ||||
|       required this.accountId}); | ||||
|  | ||||
|   factory _$SnStickerImpl.fromJson(Map<String, dynamic> json) => | ||||
|       _$$SnStickerImplFromJson(json); | ||||
|  | ||||
|   @override | ||||
|   final int id; | ||||
|   @override | ||||
|   final DateTime createdAt; | ||||
|   @override | ||||
|   final DateTime updatedAt; | ||||
|   @override | ||||
|   final DateTime? deletedAt; | ||||
|   @override | ||||
|   final String alias; | ||||
|   @override | ||||
|   final String name; | ||||
|   @override | ||||
|   final int attachmentId; | ||||
|   @override | ||||
|   final SnAttachment attachment; | ||||
|   @override | ||||
|   final int packId; | ||||
|   @override | ||||
|   final SnStickerPack pack; | ||||
|   @override | ||||
|   final int accountId; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return 'SnSticker(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, alias: $alias, name: $name, attachmentId: $attachmentId, attachment: $attachment, packId: $packId, pack: $pack, accountId: $accountId)'; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   bool operator ==(Object other) { | ||||
|     return identical(this, other) || | ||||
|         (other.runtimeType == runtimeType && | ||||
|             other is _$SnStickerImpl && | ||||
|             (identical(other.id, id) || other.id == id) && | ||||
|             (identical(other.createdAt, createdAt) || | ||||
|                 other.createdAt == createdAt) && | ||||
|             (identical(other.updatedAt, updatedAt) || | ||||
|                 other.updatedAt == updatedAt) && | ||||
|             (identical(other.deletedAt, deletedAt) || | ||||
|                 other.deletedAt == deletedAt) && | ||||
|             (identical(other.alias, alias) || other.alias == alias) && | ||||
|             (identical(other.name, name) || other.name == name) && | ||||
|             (identical(other.attachmentId, attachmentId) || | ||||
|                 other.attachmentId == attachmentId) && | ||||
|             (identical(other.attachment, attachment) || | ||||
|                 other.attachment == attachment) && | ||||
|             (identical(other.packId, packId) || other.packId == packId) && | ||||
|             (identical(other.pack, pack) || other.pack == pack) && | ||||
|             (identical(other.accountId, accountId) || | ||||
|                 other.accountId == accountId)); | ||||
|   } | ||||
|  | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   @override | ||||
|   int get hashCode => Object.hash( | ||||
|       runtimeType, | ||||
|       id, | ||||
|       createdAt, | ||||
|       updatedAt, | ||||
|       deletedAt, | ||||
|       alias, | ||||
|       name, | ||||
|       attachmentId, | ||||
|       attachment, | ||||
|       packId, | ||||
|       pack, | ||||
|       accountId); | ||||
|  | ||||
|   /// Create a copy of SnSticker | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   @override | ||||
|   @pragma('vm:prefer-inline') | ||||
|   _$$SnStickerImplCopyWith<_$SnStickerImpl> get copyWith => | ||||
|       __$$SnStickerImplCopyWithImpl<_$SnStickerImpl>(this, _$identity); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return _$$SnStickerImplToJson( | ||||
|       this, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| abstract class _SnSticker implements SnSticker { | ||||
|   const factory _SnSticker( | ||||
|       {required final int id, | ||||
|       required final DateTime createdAt, | ||||
|       required final DateTime updatedAt, | ||||
|       required final DateTime? deletedAt, | ||||
|       required final String alias, | ||||
|       required final String name, | ||||
|       required final int attachmentId, | ||||
|       required final SnAttachment attachment, | ||||
|       required final int packId, | ||||
|       required final SnStickerPack pack, | ||||
|       required final int accountId}) = _$SnStickerImpl; | ||||
|  | ||||
|   factory _SnSticker.fromJson(Map<String, dynamic> json) = | ||||
|       _$SnStickerImpl.fromJson; | ||||
|  | ||||
|   @override | ||||
|   int get id; | ||||
|   @override | ||||
|   DateTime get createdAt; | ||||
|   @override | ||||
|   DateTime get updatedAt; | ||||
|   @override | ||||
|   DateTime? get deletedAt; | ||||
|   @override | ||||
|   String get alias; | ||||
|   @override | ||||
|   String get name; | ||||
|   @override | ||||
|   int get attachmentId; | ||||
|   @override | ||||
|   SnAttachment get attachment; | ||||
|   @override | ||||
|   int get packId; | ||||
|   @override | ||||
|   SnStickerPack get pack; | ||||
|   @override | ||||
|   int get accountId; | ||||
|  | ||||
|   /// Create a copy of SnSticker | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @override | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   _$$SnStickerImplCopyWith<_$SnStickerImpl> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
|  | ||||
| SnStickerPack _$SnStickerPackFromJson(Map<String, dynamic> json) { | ||||
|   return _SnStickerPack.fromJson(json); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| mixin _$SnStickerPack { | ||||
|   int get id => throw _privateConstructorUsedError; | ||||
|   DateTime get createdAt => throw _privateConstructorUsedError; | ||||
|   DateTime get updatedAt => throw _privateConstructorUsedError; | ||||
|   DateTime? get deletedAt => throw _privateConstructorUsedError; | ||||
|   String get prefix => throw _privateConstructorUsedError; | ||||
|   String get name => throw _privateConstructorUsedError; | ||||
|   String get description => throw _privateConstructorUsedError; | ||||
|   List<SnSticker>? get stickers => throw _privateConstructorUsedError; | ||||
|   int get accountId => throw _privateConstructorUsedError; | ||||
|  | ||||
|   /// Serializes this SnStickerPack to a JSON map. | ||||
|   Map<String, dynamic> toJson() => throw _privateConstructorUsedError; | ||||
|  | ||||
|   /// Create a copy of SnStickerPack | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   $SnStickerPackCopyWith<SnStickerPack> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class $SnStickerPackCopyWith<$Res> { | ||||
|   factory $SnStickerPackCopyWith( | ||||
|           SnStickerPack value, $Res Function(SnStickerPack) then) = | ||||
|       _$SnStickerPackCopyWithImpl<$Res, SnStickerPack>; | ||||
|   @useResult | ||||
|   $Res call( | ||||
|       {int id, | ||||
|       DateTime createdAt, | ||||
|       DateTime updatedAt, | ||||
|       DateTime? deletedAt, | ||||
|       String prefix, | ||||
|       String name, | ||||
|       String description, | ||||
|       List<SnSticker>? stickers, | ||||
|       int accountId}); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class _$SnStickerPackCopyWithImpl<$Res, $Val extends SnStickerPack> | ||||
|     implements $SnStickerPackCopyWith<$Res> { | ||||
|   _$SnStickerPackCopyWithImpl(this._value, this._then); | ||||
|  | ||||
|   // ignore: unused_field | ||||
|   final $Val _value; | ||||
|   // ignore: unused_field | ||||
|   final $Res Function($Val) _then; | ||||
|  | ||||
|   /// Create a copy of SnStickerPack | ||||
|   /// 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? prefix = null, | ||||
|     Object? name = null, | ||||
|     Object? description = null, | ||||
|     Object? stickers = freezed, | ||||
|     Object? accountId = null, | ||||
|   }) { | ||||
|     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 DateTime?, | ||||
|       prefix: null == prefix | ||||
|           ? _value.prefix | ||||
|           : prefix // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       name: null == name | ||||
|           ? _value.name | ||||
|           : name // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       description: null == description | ||||
|           ? _value.description | ||||
|           : description // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       stickers: freezed == stickers | ||||
|           ? _value.stickers | ||||
|           : stickers // ignore: cast_nullable_to_non_nullable | ||||
|               as List<SnSticker>?, | ||||
|       accountId: null == accountId | ||||
|           ? _value.accountId | ||||
|           : accountId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|     ) as $Val); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class _$$SnStickerPackImplCopyWith<$Res> | ||||
|     implements $SnStickerPackCopyWith<$Res> { | ||||
|   factory _$$SnStickerPackImplCopyWith( | ||||
|           _$SnStickerPackImpl value, $Res Function(_$SnStickerPackImpl) then) = | ||||
|       __$$SnStickerPackImplCopyWithImpl<$Res>; | ||||
|   @override | ||||
|   @useResult | ||||
|   $Res call( | ||||
|       {int id, | ||||
|       DateTime createdAt, | ||||
|       DateTime updatedAt, | ||||
|       DateTime? deletedAt, | ||||
|       String prefix, | ||||
|       String name, | ||||
|       String description, | ||||
|       List<SnSticker>? stickers, | ||||
|       int accountId}); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class __$$SnStickerPackImplCopyWithImpl<$Res> | ||||
|     extends _$SnStickerPackCopyWithImpl<$Res, _$SnStickerPackImpl> | ||||
|     implements _$$SnStickerPackImplCopyWith<$Res> { | ||||
|   __$$SnStickerPackImplCopyWithImpl( | ||||
|       _$SnStickerPackImpl _value, $Res Function(_$SnStickerPackImpl) _then) | ||||
|       : super(_value, _then); | ||||
|  | ||||
|   /// Create a copy of SnStickerPack | ||||
|   /// 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? prefix = null, | ||||
|     Object? name = null, | ||||
|     Object? description = null, | ||||
|     Object? stickers = freezed, | ||||
|     Object? accountId = null, | ||||
|   }) { | ||||
|     return _then(_$SnStickerPackImpl( | ||||
|       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 DateTime?, | ||||
|       prefix: null == prefix | ||||
|           ? _value.prefix | ||||
|           : prefix // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       name: null == name | ||||
|           ? _value.name | ||||
|           : name // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       description: null == description | ||||
|           ? _value.description | ||||
|           : description // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       stickers: freezed == stickers | ||||
|           ? _value._stickers | ||||
|           : stickers // ignore: cast_nullable_to_non_nullable | ||||
|               as List<SnSticker>?, | ||||
|       accountId: null == accountId | ||||
|           ? _value.accountId | ||||
|           : accountId // ignore: cast_nullable_to_non_nullable | ||||
|               as int, | ||||
|     )); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| @JsonSerializable() | ||||
| class _$SnStickerPackImpl implements _SnStickerPack { | ||||
|   const _$SnStickerPackImpl( | ||||
|       {required this.id, | ||||
|       required this.createdAt, | ||||
|       required this.updatedAt, | ||||
|       required this.deletedAt, | ||||
|       required this.prefix, | ||||
|       required this.name, | ||||
|       required this.description, | ||||
|       required final List<SnSticker>? stickers, | ||||
|       required this.accountId}) | ||||
|       : _stickers = stickers; | ||||
|  | ||||
|   factory _$SnStickerPackImpl.fromJson(Map<String, dynamic> json) => | ||||
|       _$$SnStickerPackImplFromJson(json); | ||||
|  | ||||
|   @override | ||||
|   final int id; | ||||
|   @override | ||||
|   final DateTime createdAt; | ||||
|   @override | ||||
|   final DateTime updatedAt; | ||||
|   @override | ||||
|   final DateTime? deletedAt; | ||||
|   @override | ||||
|   final String prefix; | ||||
|   @override | ||||
|   final String name; | ||||
|   @override | ||||
|   final String description; | ||||
|   final List<SnSticker>? _stickers; | ||||
|   @override | ||||
|   List<SnSticker>? get stickers { | ||||
|     final value = _stickers; | ||||
|     if (value == null) return null; | ||||
|     if (_stickers is EqualUnmodifiableListView) return _stickers; | ||||
|     // ignore: implicit_dynamic_type | ||||
|     return EqualUnmodifiableListView(value); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   final int accountId; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return 'SnStickerPack(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, prefix: $prefix, name: $name, description: $description, stickers: $stickers, accountId: $accountId)'; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   bool operator ==(Object other) { | ||||
|     return identical(this, other) || | ||||
|         (other.runtimeType == runtimeType && | ||||
|             other is _$SnStickerPackImpl && | ||||
|             (identical(other.id, id) || other.id == id) && | ||||
|             (identical(other.createdAt, createdAt) || | ||||
|                 other.createdAt == createdAt) && | ||||
|             (identical(other.updatedAt, updatedAt) || | ||||
|                 other.updatedAt == updatedAt) && | ||||
|             (identical(other.deletedAt, deletedAt) || | ||||
|                 other.deletedAt == deletedAt) && | ||||
|             (identical(other.prefix, prefix) || other.prefix == prefix) && | ||||
|             (identical(other.name, name) || other.name == name) && | ||||
|             (identical(other.description, description) || | ||||
|                 other.description == description) && | ||||
|             const DeepCollectionEquality().equals(other._stickers, _stickers) && | ||||
|             (identical(other.accountId, accountId) || | ||||
|                 other.accountId == accountId)); | ||||
|   } | ||||
|  | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   @override | ||||
|   int get hashCode => Object.hash( | ||||
|       runtimeType, | ||||
|       id, | ||||
|       createdAt, | ||||
|       updatedAt, | ||||
|       deletedAt, | ||||
|       prefix, | ||||
|       name, | ||||
|       description, | ||||
|       const DeepCollectionEquality().hash(_stickers), | ||||
|       accountId); | ||||
|  | ||||
|   /// Create a copy of SnStickerPack | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   @override | ||||
|   @pragma('vm:prefer-inline') | ||||
|   _$$SnStickerPackImplCopyWith<_$SnStickerPackImpl> get copyWith => | ||||
|       __$$SnStickerPackImplCopyWithImpl<_$SnStickerPackImpl>(this, _$identity); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return _$$SnStickerPackImplToJson( | ||||
|       this, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| abstract class _SnStickerPack implements SnStickerPack { | ||||
|   const factory _SnStickerPack( | ||||
|       {required final int id, | ||||
|       required final DateTime createdAt, | ||||
|       required final DateTime updatedAt, | ||||
|       required final DateTime? deletedAt, | ||||
|       required final String prefix, | ||||
|       required final String name, | ||||
|       required final String description, | ||||
|       required final List<SnSticker>? stickers, | ||||
|       required final int accountId}) = _$SnStickerPackImpl; | ||||
|  | ||||
|   factory _SnStickerPack.fromJson(Map<String, dynamic> json) = | ||||
|       _$SnStickerPackImpl.fromJson; | ||||
|  | ||||
|   @override | ||||
|   int get id; | ||||
|   @override | ||||
|   DateTime get createdAt; | ||||
|   @override | ||||
|   DateTime get updatedAt; | ||||
|   @override | ||||
|   DateTime? get deletedAt; | ||||
|   @override | ||||
|   String get prefix; | ||||
|   @override | ||||
|   String get name; | ||||
|   @override | ||||
|   String get description; | ||||
|   @override | ||||
|   List<SnSticker>? get stickers; | ||||
|   @override | ||||
|   int get accountId; | ||||
|  | ||||
|   /// Create a copy of SnStickerPack | ||||
|   /// with the given fields replaced by the non-null parameter values. | ||||
|   @override | ||||
|   @JsonKey(includeFromJson: false, includeToJson: false) | ||||
|   _$$SnStickerPackImplCopyWith<_$SnStickerPackImpl> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
|   | ||||
| @@ -218,3 +218,66 @@ Map<String, dynamic> _$$SnAttachmentBoostImplToJson( | ||||
|       'attachment': instance.attachment.toJson(), | ||||
|       'account': instance.account, | ||||
|     }; | ||||
|  | ||||
| _$SnStickerImpl _$$SnStickerImplFromJson(Map<String, dynamic> json) => | ||||
|     _$SnStickerImpl( | ||||
|       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'] == null | ||||
|           ? null | ||||
|           : DateTime.parse(json['deleted_at'] as String), | ||||
|       alias: json['alias'] as String, | ||||
|       name: json['name'] as String, | ||||
|       attachmentId: (json['attachment_id'] as num).toInt(), | ||||
|       attachment: | ||||
|           SnAttachment.fromJson(json['attachment'] as Map<String, dynamic>), | ||||
|       packId: (json['pack_id'] as num).toInt(), | ||||
|       pack: SnStickerPack.fromJson(json['pack'] as Map<String, dynamic>), | ||||
|       accountId: (json['account_id'] as num).toInt(), | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$$SnStickerImplToJson(_$SnStickerImpl instance) => | ||||
|     <String, dynamic>{ | ||||
|       'id': instance.id, | ||||
|       'created_at': instance.createdAt.toIso8601String(), | ||||
|       'updated_at': instance.updatedAt.toIso8601String(), | ||||
|       'deleted_at': instance.deletedAt?.toIso8601String(), | ||||
|       'alias': instance.alias, | ||||
|       'name': instance.name, | ||||
|       'attachment_id': instance.attachmentId, | ||||
|       'attachment': instance.attachment.toJson(), | ||||
|       'pack_id': instance.packId, | ||||
|       'pack': instance.pack.toJson(), | ||||
|       'account_id': instance.accountId, | ||||
|     }; | ||||
|  | ||||
| _$SnStickerPackImpl _$$SnStickerPackImplFromJson(Map<String, dynamic> json) => | ||||
|     _$SnStickerPackImpl( | ||||
|       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'] == null | ||||
|           ? null | ||||
|           : DateTime.parse(json['deleted_at'] as String), | ||||
|       prefix: json['prefix'] as String, | ||||
|       name: json['name'] as String, | ||||
|       description: json['description'] as String, | ||||
|       stickers: (json['stickers'] as List<dynamic>?) | ||||
|           ?.map((e) => SnSticker.fromJson(e as Map<String, dynamic>)) | ||||
|           .toList(), | ||||
|       accountId: (json['account_id'] as num).toInt(), | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$$SnStickerPackImplToJson(_$SnStickerPackImpl instance) => | ||||
|     <String, dynamic>{ | ||||
|       'id': instance.id, | ||||
|       'created_at': instance.createdAt.toIso8601String(), | ||||
|       'updated_at': instance.updatedAt.toIso8601String(), | ||||
|       'deleted_at': instance.deletedAt?.toIso8601String(), | ||||
|       'prefix': instance.prefix, | ||||
|       'name': instance.name, | ||||
|       'description': instance.description, | ||||
|       'stickers': instance.stickers?.map((e) => e.toJson()).toList(), | ||||
|       'account_id': instance.accountId, | ||||
|     }; | ||||
|   | ||||
| @@ -312,11 +312,6 @@ class _AttachmentZoomViewState extends State<AttachmentZoomView> { | ||||
|                                 ]), | ||||
|                                 style: metaTextStyle, | ||||
|                               ).padding(right: 2), | ||||
|                             if (item.metadata['exif']?['ShutterSpeed'] != null) | ||||
|                               Text( | ||||
|                                 item.metadata['exif']?['ShutterSpeed'], | ||||
|                                 style: metaTextStyle, | ||||
|                               ).padding(right: 2), | ||||
|                             if (item.metadata['exif']?['ISO'] != null) | ||||
|                               Text( | ||||
|                                 'ISO${item.metadata['exif']?['ISO']}', | ||||
|   | ||||
| @@ -1,18 +1,16 @@ | ||||
| import 'dart:ui'; | ||||
|  | ||||
| import 'package:dismissible_page/dismissible_page.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_markdown/flutter_markdown.dart'; | ||||
| import 'package:go_router/go_router.dart'; | ||||
| import 'package:google_fonts/google_fonts.dart'; | ||||
| import 'package:markdown/markdown.dart' as markdown; | ||||
| import 'package:styled_widget/styled_widget.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:surface/providers/sn_network.dart'; | ||||
| import 'package:surface/providers/sn_sticker.dart'; | ||||
| import 'package:surface/types/attachment.dart'; | ||||
| import 'package:surface/widgets/attachment/attachment_item.dart'; | ||||
| import 'package:surface/widgets/universal_image.dart'; | ||||
| import 'package:syntax_highlight/syntax_highlight.dart'; | ||||
| import 'package:url_launcher/url_launcher_string.dart'; | ||||
| import 'package:path/path.dart'; | ||||
| import 'package:uuid/uuid.dart'; | ||||
|  | ||||
| import 'attachment/attachment_zoom.dart'; | ||||
| @@ -21,6 +19,7 @@ class MarkdownTextContent extends StatelessWidget { | ||||
|   final String content; | ||||
|   final bool isSelectable; | ||||
|   final bool isAutoWarp; | ||||
|   final bool isEnlargeSticker; | ||||
|   final TextScaler? textScaler; | ||||
|   final List<SnAttachment?>? attachments; | ||||
|  | ||||
| @@ -29,6 +28,7 @@ class MarkdownTextContent extends StatelessWidget { | ||||
|     required this.content, | ||||
|     this.isSelectable = false, | ||||
|     this.isAutoWarp = false, | ||||
|     this.isEnlargeSticker = false, | ||||
|     this.textScaler, | ||||
|     this.attachments, | ||||
|   }); | ||||
| @@ -42,32 +42,33 @@ class MarkdownTextContent extends StatelessWidget { | ||||
|       styleSheet: MarkdownStyleSheet.fromTheme( | ||||
|         Theme.of(context), | ||||
|       ).copyWith( | ||||
|           textScaler: textScaler, | ||||
|           blockquote: TextStyle( | ||||
|             color: Theme.of(context).colorScheme.onSurfaceVariant, | ||||
|           ), | ||||
|           blockquoteDecoration: BoxDecoration( | ||||
|             color: Theme.of(context).colorScheme.surfaceContainerHigh, | ||||
|             borderRadius: const BorderRadius.all(Radius.circular(4)), | ||||
|           ), | ||||
|           horizontalRuleDecoration: BoxDecoration( | ||||
|             border: Border( | ||||
|               top: BorderSide( | ||||
|                 width: 1.0, | ||||
|                 color: Theme.of(context).dividerColor, | ||||
|               ), | ||||
|             ), | ||||
|           ), | ||||
|           codeblockDecoration: BoxDecoration( | ||||
|             border: Border.all( | ||||
|         textScaler: textScaler, | ||||
|         blockquote: TextStyle( | ||||
|           color: Theme.of(context).colorScheme.onSurfaceVariant, | ||||
|         ), | ||||
|         blockquoteDecoration: BoxDecoration( | ||||
|           color: Theme.of(context).colorScheme.surfaceContainerHigh, | ||||
|           borderRadius: const BorderRadius.all(Radius.circular(4)), | ||||
|         ), | ||||
|         horizontalRuleDecoration: BoxDecoration( | ||||
|           border: Border( | ||||
|             top: BorderSide( | ||||
|               width: 1.0, | ||||
|               color: Theme.of(context).dividerColor, | ||||
|               width: 0.3, | ||||
|             ), | ||||
|             borderRadius: const BorderRadius.all(Radius.circular(4)), | ||||
|             color: Theme.of(context).colorScheme.surface.withOpacity(0.5), | ||||
|           )), | ||||
|           ), | ||||
|         ), | ||||
|         codeblockDecoration: BoxDecoration( | ||||
|           border: Border.all( | ||||
|             color: Theme.of(context).dividerColor, | ||||
|             width: 0.3, | ||||
|           ), | ||||
|           borderRadius: const BorderRadius.all(Radius.circular(4)), | ||||
|           color: Theme.of(context).colorScheme.surface.withOpacity(0.5), | ||||
|         ), | ||||
|         code: GoogleFonts.robotoMono(height: 1), | ||||
|       ), | ||||
|       builders: { | ||||
|         'code': _MarkdownTextCodeElement(), | ||||
|       }, | ||||
|       softLineBreak: true, | ||||
|       extensionSet: markdown.ExtensionSet( | ||||
| @@ -78,6 +79,7 @@ class MarkdownTextContent extends StatelessWidget { | ||||
|         <markdown.InlineSyntax>[ | ||||
|           if (isAutoWarp) markdown.LineBreakSyntax(), | ||||
|           _UserNameCardInlineSyntax(), | ||||
|           _CustomEmoteInlineSyntax(context), | ||||
|           markdown.AutolinkSyntax(), | ||||
|           markdown.AutolinkExtensionSyntax(), | ||||
|           markdown.CodeSyntax(), | ||||
| @@ -108,6 +110,38 @@ class MarkdownTextContent extends StatelessWidget { | ||||
|         if (url.startsWith('solink://')) { | ||||
|           final segments = url.replaceFirst('solink://', '').split('/'); | ||||
|           switch (segments[0]) { | ||||
|             case 'stickers': | ||||
|               final alias = segments[1]; | ||||
|               final st = context.read<SnStickerProvider>(); | ||||
|               final sn = context.read<SnNetworkProvider>(); | ||||
|               final double size = isEnlargeSticker ? 128 : 32; | ||||
|               return Container( | ||||
|                 width: size, | ||||
|                 height: size, | ||||
|                 decoration: BoxDecoration( | ||||
|                   borderRadius: const BorderRadius.all(Radius.circular(8)), | ||||
|                   color: Theme.of(context).colorScheme.surfaceContainerHigh, | ||||
|                 ), | ||||
|                 child: ClipRRect( | ||||
|                   borderRadius: const BorderRadius.all(Radius.circular(8)), | ||||
|                   child: FutureBuilder<SnSticker?>( | ||||
|                     future: st.lookupSticker(alias), | ||||
|                     builder: (context, snapshot) { | ||||
|                       if (snapshot.hasData) { | ||||
|                         return UniversalImage( | ||||
|                           sn.getAttachmentUrl(snapshot.data!.attachment.rid), | ||||
|                           fit: BoxFit.cover, | ||||
|                           width: size, | ||||
|                           height: size, | ||||
|                           cacheHeight: size, | ||||
|                           cacheWidth: size, | ||||
|                         ); | ||||
|                       } | ||||
|                       return const SizedBox.shrink(); | ||||
|                     }, | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             case 'attachments': | ||||
|               final attachment = attachments?.firstWhere( | ||||
|                 (ele) => ele?.rid == segments[1], | ||||
| @@ -194,45 +228,24 @@ class _UserNameCardInlineSyntax extends markdown.InlineSyntax { | ||||
|   } | ||||
| } | ||||
|  | ||||
| class _MarkdownTextCodeElement extends MarkdownElementBuilder { | ||||
|   @override | ||||
|   Widget? visitElementAfter( | ||||
|     markdown.Element element, | ||||
|     TextStyle? preferredStyle, | ||||
|   ) { | ||||
|     var language = ''; | ||||
| class _CustomEmoteInlineSyntax extends markdown.InlineSyntax { | ||||
|   final BuildContext context; | ||||
|  | ||||
|     if (element.attributes['class'] != null) { | ||||
|       String lg = element.attributes['class'] as String; | ||||
|       language = lg.substring(9).trim(); | ||||
|   _CustomEmoteInlineSyntax(this.context) : super(r':([-\w]+):'); | ||||
|  | ||||
|   @override | ||||
|   bool onMatch(markdown.InlineParser parser, Match match) { | ||||
|     final SnStickerProvider st = context.read<SnStickerProvider>(); | ||||
|     final alias = match[1]!.toUpperCase(); | ||||
|     if (st.hasNotSticker(alias)) { | ||||
|       parser.advanceBy(1); | ||||
|       return false; | ||||
|     } | ||||
|     return SizedBox( | ||||
|       child: FutureBuilder( | ||||
|         future: (() async { | ||||
|           final docPath = '../../../'; | ||||
|           final highlightingPath = join(docPath, 'assets/highlighting', language); | ||||
|           await Highlighter.initialize([highlightingPath]); | ||||
|           return Highlighter( | ||||
|             language: highlightingPath, | ||||
|             theme: PlatformDispatcher.instance.platformBrightness == Brightness.light | ||||
|                 ? await HighlighterTheme.loadLightTheme() | ||||
|                 : await HighlighterTheme.loadDarkTheme(), | ||||
|           ); | ||||
|         })(), | ||||
|         builder: (context, snapshot) { | ||||
|           if (snapshot.hasData) { | ||||
|             final highlighter = snapshot.data!; | ||||
|             return Text.rich( | ||||
|               highlighter.highlight(element.textContent.trim()), | ||||
|               style: GoogleFonts.robotoMono(), | ||||
|             ); | ||||
|           } | ||||
|           return Text( | ||||
|             element.textContent.trim(), | ||||
|             style: GoogleFonts.robotoMono(), | ||||
|           ); | ||||
|         }, | ||||
|       ), | ||||
|     ).padding(all: 8); | ||||
|  | ||||
|     final element = markdown.Element.empty('img'); | ||||
|     element.attributes['src'] = 'solink://stickers/$alias'; | ||||
|     parser.addNode(element); | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import 'package:styled_widget/styled_widget.dart'; | ||||
| import 'package:surface/providers/config.dart'; | ||||
| import 'package:surface/providers/sn_network.dart'; | ||||
| import 'package:surface/providers/userinfo.dart'; | ||||
| import 'package:surface/types/attachment.dart'; | ||||
| import 'package:surface/types/post.dart'; | ||||
| import 'package:surface/types/reaction.dart'; | ||||
| import 'package:surface/widgets/account/account_image.dart'; | ||||
| @@ -198,6 +199,10 @@ class PostItem extends StatelessWidget { | ||||
|       ).center(); | ||||
|     } | ||||
|  | ||||
|     final displayableAttachments = data.preload?.attachments | ||||
|         ?.where((ele) => ele?.mediaType != SnMediaType.image || data.type != 'article') | ||||
|         .toList(); | ||||
|  | ||||
|     return Column( | ||||
|       crossAxisAlignment: CrossAxisAlignment.center, | ||||
|       children: [ | ||||
| @@ -247,9 +252,9 @@ class PostItem extends StatelessWidget { | ||||
|             ], | ||||
|           ), | ||||
|         ), | ||||
|         if ((data.preload?.attachments?.isNotEmpty ?? false) && data.type != 'article') | ||||
|         if (displayableAttachments?.isNotEmpty ?? false) | ||||
|           AttachmentList( | ||||
|             data: data.preload!.attachments!, | ||||
|             data: displayableAttachments!, | ||||
|             bordered: true, | ||||
|             gridded: true, | ||||
|             maxHeight: showFullPost ? null : 480, | ||||
| @@ -876,6 +881,7 @@ class _PostContentBody extends StatelessWidget { | ||||
|     if (data.body['content'] == null) return const SizedBox.shrink(); | ||||
|     return MarkdownTextContent( | ||||
|       isSelectable: isSelectable, | ||||
|       isEnlargeSticker: true, | ||||
|       textScaler: isEnlarge ? TextScaler.linear(1.1) : null, | ||||
|       content: data.body['content'], | ||||
|       attachments: data.preload?.attachments, | ||||
|   | ||||
							
								
								
									
										44
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -708,10 +708,10 @@ packages: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
|       name: flutter_native_splash | ||||
|       sha256: "1152ab0067ca5a2ebeb862fe0a762057202cceb22b7e62692dcbabf6483891bb" | ||||
|       sha256: "7062602e0dbd29141fb8eb19220b5871ca650be5197ab9c1f193a28b17537bc7" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.3" | ||||
|     version: "2.4.4" | ||||
|   flutter_plugin_android_lifecycle: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -766,10 +766,10 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: flutter_webrtc | ||||
|       sha256: "3efe9828f19a07d29a51a726759ad0c70a840d231548a1c7d0332075a94db1df" | ||||
|       sha256: e82ffd0d0b79621c5554eed73509d7f5bd286d57fef29a573846785c65237fb1 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.12.5+hotfix.1" | ||||
|     version: "0.12.5+hotfix.2" | ||||
|   freezed: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
| @@ -902,10 +902,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: http_parser | ||||
|       sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360" | ||||
|       sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.1.1" | ||||
|     version: "4.1.2" | ||||
|   icons_launcher: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
| @@ -950,10 +950,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: image_picker_ios | ||||
|       sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b" | ||||
|       sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.8.12+1" | ||||
|     version: "0.8.12+2" | ||||
|   image_picker_linux: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1086,10 +1086,10 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: livekit_client | ||||
|       sha256: "7cdeb3eaeec7fb70a4cf88d9caabccbef9e3bd5f0b23c086320bc5c9acb2770b" | ||||
|       sha256: a19bcf8640b45e0730b1e3e3e78be7882dad680c6ebe8ae75294fd8d4612450d | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.3.4" | ||||
|     version: "2.3.4+hotfix.2" | ||||
|   logging: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1142,10 +1142,10 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: material_symbols_icons | ||||
|       sha256: "64404f47f8e0a9d20478468e5decef867a688660bad7173adcd20418d7f892c9" | ||||
|       sha256: "89aac72d25dd49303f71b3b1e70f8374791846729365b25bebc2a2531e5b86cd" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.2801.0" | ||||
|     version: "4.2801.1" | ||||
|   media_kit: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -1646,10 +1646,10 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: shared_preferences | ||||
|       sha256: "3c7e73920c694a436afaf65ab60ce3453d91f84208d761fbd83fc21182134d93" | ||||
|       sha256: a752ce92ea7540fc35a0d19722816e04d0e72828a4200e83a98cf1a1eb524c9a | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.3.4" | ||||
|     version: "2.3.5" | ||||
|   shared_preferences_android: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1795,10 +1795,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: sqflite_darwin | ||||
|       sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474" | ||||
|       sha256: "22adfd9a2c7d634041e96d6241e6e1c8138ca6817018afc5d443fef91dcefa9c" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.4.1" | ||||
|     version: "2.4.1+1" | ||||
|   sqflite_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1863,14 +1863,6 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.3.0+3" | ||||
|   syntax_highlight: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: syntax_highlight | ||||
|       sha256: ee33b6aa82cc722bb9b40152a792181dee222353b486c0255fde666a3e3a4997 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.4.0" | ||||
|   term_glyph: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -2131,10 +2123,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: win32 | ||||
|       sha256: "8b338d4486ab3fbc0ba0db9f9b4f5239b6697fcee427939a40e720cbb9ee0a69" | ||||
|       sha256: "154360849a56b7b67331c21f09a386562d88903f90a1099c5987afc1912e1f29" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "5.9.0" | ||||
|     version: "5.10.0" | ||||
|   win32_registry: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|   | ||||
| @@ -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: 2.2.1+44 | ||||
| version: 2.2.1+48 | ||||
|  | ||||
| environment: | ||||
|   sdk: ^3.5.4 | ||||
| @@ -54,7 +54,6 @@ dependencies: | ||||
|   flutter_markdown: ^0.7.4+1 | ||||
|   url_launcher: ^6.3.1 | ||||
|   flutter_animate: ^4.5.0 | ||||
|   syntax_highlight: ^0.4.0 | ||||
|   google_fonts: ^6.2.1 | ||||
|   path: ^1.9.0 | ||||
|   relative_time: ^5.0.0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user