✨ Enhanced profile edit
This commit is contained in:
@ -108,8 +108,7 @@ void main() async {
|
||||
}
|
||||
|
||||
if (!kIsWeb && Platform.isAndroid) {
|
||||
final ImagePickerPlatform imagePickerImplementation =
|
||||
ImagePickerPlatform.instance;
|
||||
final ImagePickerPlatform imagePickerImplementation = ImagePickerPlatform.instance;
|
||||
if (imagePickerImplementation is ImagePickerAndroid) {
|
||||
imagePickerImplementation.useAndroidPhotoPicker = true;
|
||||
}
|
||||
@ -228,8 +227,7 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
||||
if (prefs.containsKey('first_boot_time')) {
|
||||
final rawTime = prefs.getString('first_boot_time');
|
||||
final time = DateTime.tryParse(rawTime ?? '');
|
||||
if (time != null &&
|
||||
time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
|
||||
if (time != null && time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
|
||||
final inAppReview = InAppReview.instance;
|
||||
if (prefs.getBool('rating_requested') == true) return;
|
||||
if (await inAppReview.isAvailable()) {
|
||||
@ -260,18 +258,12 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
||||
final remoteVersionString = resp.data?['tag_name'] ?? '0.0.0+0';
|
||||
final remoteVersion = Version.parse(remoteVersionString.split('+').first);
|
||||
final localVersion = Version.parse(localVersionString.split('+').first);
|
||||
final remoteBuildNumber =
|
||||
int.tryParse(remoteVersionString.split('+').last) ?? 0;
|
||||
final localBuildNumber =
|
||||
int.tryParse(localVersionString.split('+').last) ?? 0;
|
||||
logging.info(
|
||||
"[Update] Local: $localVersionString, Remote: $remoteVersionString");
|
||||
if ((remoteVersion > localVersion ||
|
||||
remoteBuildNumber > localBuildNumber) &&
|
||||
mounted) {
|
||||
final remoteBuildNumber = int.tryParse(remoteVersionString.split('+').last) ?? 0;
|
||||
final localBuildNumber = int.tryParse(localVersionString.split('+').last) ?? 0;
|
||||
logging.info("[Update] Local: $localVersionString, Remote: $remoteVersionString");
|
||||
if ((remoteVersion > localVersion || remoteBuildNumber > localBuildNumber) && mounted) {
|
||||
final config = context.read<ConfigProvider>();
|
||||
config.setUpdate(
|
||||
remoteVersionString, resp.data?['body'] ?? 'No changelog');
|
||||
config.setUpdate(remoteVersionString, resp.data?['body'] ?? 'No changelog');
|
||||
logging.info("[Update] Update available: $remoteVersionString");
|
||||
}
|
||||
} catch (e) {
|
||||
@ -363,9 +355,7 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
||||
Future<void> _trayInitialization() async {
|
||||
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
|
||||
|
||||
final icon = Platform.isWindows
|
||||
? 'assets/icon/tray-icon.ico'
|
||||
: 'assets/icon/tray-icon.png';
|
||||
final icon = Platform.isWindows ? 'assets/icon/tray-icon.ico' : 'assets/icon/tray-icon.png';
|
||||
final appVersion = await PackageInfo.fromPlatform();
|
||||
|
||||
trayManager.addListener(this);
|
||||
|
@ -45,8 +45,7 @@ class AccountScreen extends StatelessWidget {
|
||||
? Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
AutoResizeUniversalImage(sn.getAttachmentUrl(ua.user!.banner),
|
||||
fit: BoxFit.cover),
|
||||
AutoResizeUniversalImage(sn.getAttachmentUrl(ua.user!.banner), fit: BoxFit.cover),
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
@ -80,9 +79,7 @@ class AccountScreen extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: ua.isAuthorized
|
||||
? _AuthorizedAccountScreen()
|
||||
: _UnauthorizedAccountScreen(),
|
||||
child: ua.isAuthorized ? _AuthorizedAccountScreen() : _UnauthorizedAccountScreen(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -118,15 +115,19 @@ class _AuthorizedAccountScreen extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: [
|
||||
Text(ua.user!.nick)
|
||||
.textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||
Text(ua.user!.nick).textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||
const Gap(4),
|
||||
Text('@${ua.user!.name}')
|
||||
.textStyle(Theme.of(context).textTheme.bodySmall!),
|
||||
Text('@${ua.user!.name}').textStyle(Theme.of(context).textTheme.bodySmall!),
|
||||
],
|
||||
),
|
||||
Text(ua.user!.description)
|
||||
.textStyle(Theme.of(context).textTheme.bodyMedium!),
|
||||
Text(
|
||||
(ua.user!.profile?.description.isNotEmpty ?? false)
|
||||
? ua.user!.profile!.description
|
||||
: 'userNoDescription'.tr(),
|
||||
style: (ua.user!.profile?.description.isEmpty ?? true)
|
||||
? TextStyle(fontStyle: FontStyle.italic)
|
||||
: null,
|
||||
).textStyle(Theme.of(context).textTheme.bodyMedium!),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -225,9 +226,7 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
|
||||
child: Icon(Symbols.waving_hand, size: 28),
|
||||
),
|
||||
const Gap(8),
|
||||
Text('accountIntroTitle')
|
||||
.tr()
|
||||
.textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||
Text('accountIntroTitle').tr().textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||
Text('accountIntroSubtitle').tr(),
|
||||
],
|
||||
).padding(all: 20),
|
||||
|
@ -6,6 +6,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_timezone/flutter_timezone.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
@ -36,11 +37,16 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
final _firstNameController = TextEditingController();
|
||||
final _lastNameController = TextEditingController();
|
||||
final _descriptionController = TextEditingController();
|
||||
final _timezoneController = TextEditingController();
|
||||
final _genderController = TextEditingController();
|
||||
final _pronounsController = TextEditingController();
|
||||
final _locationController = TextEditingController();
|
||||
final _birthdayController = TextEditingController();
|
||||
|
||||
String? _avatar;
|
||||
String? _banner;
|
||||
DateTime? _birthday;
|
||||
List<(String, String)>? _links;
|
||||
|
||||
bool _isBusy = false;
|
||||
|
||||
@ -51,15 +57,21 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
final prof = ua.user!;
|
||||
_usernameController.text = prof.name;
|
||||
_nicknameController.text = prof.nick;
|
||||
_descriptionController.text = prof.description;
|
||||
_descriptionController.text = prof.profile!.description;
|
||||
_firstNameController.text = prof.profile!.firstName;
|
||||
_lastNameController.text = prof.profile!.lastName;
|
||||
_timezoneController.text = prof.profile!.timeZone;
|
||||
_genderController.text = prof.profile!.gender;
|
||||
_pronounsController.text = prof.profile!.pronouns;
|
||||
_locationController.text = prof.profile!.location;
|
||||
_avatar = prof.avatar;
|
||||
_banner = prof.banner;
|
||||
if (prof.profile!.birthday != null) {
|
||||
_links = prof.profile!.links.entries.map((ele) => (ele.key, ele.value)).toList();
|
||||
_birthday = prof.profile!.birthday?.toLocal();
|
||||
if(_birthday != null) {
|
||||
_birthdayController.text = DateFormat(_kDateFormat).format(
|
||||
prof.profile!.birthday!.toLocal(),
|
||||
);
|
||||
prof.profile!.birthday!.toLocal(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,7 +178,14 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
'description': _descriptionController.value.text,
|
||||
'first_name': _firstNameController.value.text,
|
||||
'last_name': _lastNameController.value.text,
|
||||
'time_zone': _timezoneController.value.text,
|
||||
'gender': _genderController.value.text,
|
||||
'pronouns': _pronounsController.value.text,
|
||||
'location': _locationController.value.text,
|
||||
'birthday': _birthday?.toUtc().toIso8601String(),
|
||||
'links': {
|
||||
for (final link in _links!.where((ele) => ele.$1.isNotEmpty && ele.$2.isNotEmpty)) link.$1: link.$2
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@ -197,6 +216,10 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
_firstNameController.dispose();
|
||||
_lastNameController.dispose();
|
||||
_descriptionController.dispose();
|
||||
_timezoneController.dispose();
|
||||
_genderController.dispose();
|
||||
_pronounsController.dispose();
|
||||
_locationController.dispose();
|
||||
_birthdayController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
@ -262,6 +285,7 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
).padding(horizontal: padding),
|
||||
const Gap(8 + 28),
|
||||
Column(
|
||||
spacing: 4,
|
||||
children: [
|
||||
TextField(
|
||||
readOnly: true,
|
||||
@ -271,16 +295,16 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
labelText: 'fieldUsername'.tr(),
|
||||
helperText: 'fieldUsernameCannotEditHint'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _nicknameController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldNickname'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
@ -291,6 +315,7 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldFirstName'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
@ -302,11 +327,38 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldLastName'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: TextField(
|
||||
controller: _genderController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldGender'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
const Gap(4),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: TextField(
|
||||
controller: _pronounsController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldPronouns'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _descriptionController,
|
||||
keyboardType: TextInputType.multiline,
|
||||
@ -316,8 +368,51 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldDescription'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _timezoneController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldTimeZone'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
const Gap(4),
|
||||
StyledWidget(IconButton(
|
||||
icon: const Icon(Symbols.calendar_month),
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () async {
|
||||
_timezoneController.text = await FlutterTimezone.getLocalTimezone();
|
||||
},
|
||||
)).padding(top: 6),
|
||||
const Gap(4),
|
||||
StyledWidget(IconButton(
|
||||
icon: const Icon(Symbols.clear),
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
onPressed: () {
|
||||
_timezoneController.clear();
|
||||
},
|
||||
)).padding(top: 6),
|
||||
],
|
||||
),
|
||||
TextField(
|
||||
controller: _locationController,
|
||||
decoration: InputDecoration(
|
||||
border: const UnderlineInputBorder(),
|
||||
labelText: 'fieldLocation'.tr(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _birthdayController,
|
||||
readOnly: true,
|
||||
@ -327,6 +422,75 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
),
|
||||
onTap: () => _selectBirthday(),
|
||||
),
|
||||
if (_links != null)
|
||||
Card(
|
||||
margin: const EdgeInsets.only(top: 16, bottom: 4),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'fieldLinks'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(fontSize: 17),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
visualDensity: VisualDensity(horizontal: -4, vertical: -4),
|
||||
icon: const Icon(Symbols.add),
|
||||
onPressed: () {
|
||||
setState(() => _links!.add(('', '')));
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(8),
|
||||
for (var idx = 0; idx < _links!.length; idx++)
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: TextFormField(
|
||||
initialValue: _links![idx].$1,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
border: const OutlineInputBorder(),
|
||||
labelText: 'fieldLinkName'.tr(),
|
||||
),
|
||||
onChanged: (value) {
|
||||
_links![idx] = (value, _links![idx].$2);
|
||||
},
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: TextFormField(
|
||||
initialValue: _links![idx].$2,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
border: const OutlineInputBorder(),
|
||||
labelText: 'fieldLinkUrl'.tr(),
|
||||
),
|
||||
onChanged: (value) {
|
||||
_links![idx] = (_links![idx].$1, value);
|
||||
},
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
).padding(horizontal: padding + 8),
|
||||
const Gap(12),
|
||||
@ -340,6 +504,7 @@ class _ProfileEditScreenState extends State<ProfileEditScreen> {
|
||||
),
|
||||
],
|
||||
).padding(horizontal: padding),
|
||||
Gap(MediaQuery.of(context).padding.bottom),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -406,7 +406,7 @@ class _UserScreenState extends State<UserScreen>
|
||||
],
|
||||
).padding(right: 8),
|
||||
const Gap(12),
|
||||
Text(_account!.description).padding(horizontal: 8),
|
||||
Text(_account!.profile!.description).padding(horizontal: 8),
|
||||
const Gap(4),
|
||||
Card(
|
||||
child: Row(
|
||||
|
@ -97,7 +97,7 @@ class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen>
|
||||
_banner = ua.user!.banner;
|
||||
_nickController.text = ua.user!.nick;
|
||||
_nameController.text = ua.user!.name;
|
||||
_descriptionController.text = ua.user!.description;
|
||||
_descriptionController.text = ua.user!.profile!.description;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ class _PublisherNewPersonalState extends State<_PublisherNewPersonal> {
|
||||
|
||||
_nameController.text = ua.user!.name;
|
||||
_nickController.text = ua.user!.nick;
|
||||
_descriptionController.text = ua.user!.description;
|
||||
_descriptionController.text = ua.user!.profile!.description;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -16,7 +16,6 @@ abstract class SnAccount with _$SnAccount {
|
||||
required List<SnAccountContact>? contacts,
|
||||
@Default("") String avatar,
|
||||
@Default("") String banner,
|
||||
required String description,
|
||||
required String name,
|
||||
required String nick,
|
||||
@Default({}) Map<String, dynamic> permNodes,
|
||||
@ -57,15 +56,21 @@ abstract class SnAccountContact with _$SnAccountContact {
|
||||
abstract class SnAccountProfile with _$SnAccountProfile {
|
||||
const factory SnAccountProfile({
|
||||
required int id,
|
||||
required int accountId,
|
||||
required DateTime? birthday,
|
||||
required DateTime createdAt,
|
||||
required DateTime updatedAt,
|
||||
required DateTime? deletedAt,
|
||||
required int experience,
|
||||
required String firstName,
|
||||
required String lastName,
|
||||
required String description,
|
||||
required String timeZone,
|
||||
required String location,
|
||||
required String pronouns,
|
||||
required String gender,
|
||||
@Default({}) Map<String, String> links,
|
||||
required int experience,
|
||||
required DateTime? lastSeenAt,
|
||||
required DateTime updatedAt,
|
||||
required DateTime? birthday,
|
||||
required int accountId,
|
||||
}) = _SnAccountProfile;
|
||||
|
||||
factory SnAccountProfile.fromJson(Map<String, Object?> json) =>
|
||||
|
@ -23,7 +23,6 @@ mixin _$SnAccount {
|
||||
List<SnAccountContact>? get contacts;
|
||||
String get avatar;
|
||||
String get banner;
|
||||
String get description;
|
||||
String get name;
|
||||
String get nick;
|
||||
Map<String, dynamic> get permNodes;
|
||||
@ -63,8 +62,6 @@ mixin _$SnAccount {
|
||||
const DeepCollectionEquality().equals(other.contacts, contacts) &&
|
||||
(identical(other.avatar, avatar) || other.avatar == avatar) &&
|
||||
(identical(other.banner, banner) || other.banner == banner) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.nick, nick) || other.nick == nick) &&
|
||||
const DeepCollectionEquality().equals(other.permNodes, permNodes) &&
|
||||
@ -96,7 +93,6 @@ mixin _$SnAccount {
|
||||
const DeepCollectionEquality().hash(contacts),
|
||||
avatar,
|
||||
banner,
|
||||
description,
|
||||
name,
|
||||
nick,
|
||||
const DeepCollectionEquality().hash(permNodes),
|
||||
@ -112,7 +108,7 @@ mixin _$SnAccount {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnAccount(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, confirmedAt: $confirmedAt, contacts: $contacts, avatar: $avatar, banner: $banner, description: $description, name: $name, nick: $nick, permNodes: $permNodes, language: $language, profile: $profile, badges: $badges, suspendedAt: $suspendedAt, affiliatedId: $affiliatedId, affiliatedTo: $affiliatedTo, automatedBy: $automatedBy, automatedId: $automatedId)';
|
||||
return 'SnAccount(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, confirmedAt: $confirmedAt, contacts: $contacts, avatar: $avatar, banner: $banner, name: $name, nick: $nick, permNodes: $permNodes, language: $language, profile: $profile, badges: $badges, suspendedAt: $suspendedAt, affiliatedId: $affiliatedId, affiliatedTo: $affiliatedTo, automatedBy: $automatedBy, automatedId: $automatedId)';
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +126,6 @@ abstract mixin class $SnAccountCopyWith<$Res> {
|
||||
List<SnAccountContact>? contacts,
|
||||
String avatar,
|
||||
String banner,
|
||||
String description,
|
||||
String name,
|
||||
String nick,
|
||||
Map<String, dynamic> permNodes,
|
||||
@ -166,7 +161,6 @@ class _$SnAccountCopyWithImpl<$Res> implements $SnAccountCopyWith<$Res> {
|
||||
Object? contacts = freezed,
|
||||
Object? avatar = null,
|
||||
Object? banner = null,
|
||||
Object? description = null,
|
||||
Object? name = null,
|
||||
Object? nick = null,
|
||||
Object? permNodes = null,
|
||||
@ -212,10 +206,6 @@ class _$SnAccountCopyWithImpl<$Res> implements $SnAccountCopyWith<$Res> {
|
||||
? _self.banner
|
||||
: banner // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _self.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
name: null == name
|
||||
? _self.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
@ -290,7 +280,6 @@ class _SnAccount extends SnAccount {
|
||||
required final List<SnAccountContact>? contacts,
|
||||
this.avatar = "",
|
||||
this.banner = "",
|
||||
required this.description,
|
||||
required this.name,
|
||||
required this.nick,
|
||||
final Map<String, dynamic> permNodes = const {},
|
||||
@ -336,8 +325,6 @@ class _SnAccount extends SnAccount {
|
||||
@JsonKey()
|
||||
final String banner;
|
||||
@override
|
||||
final String description;
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String nick;
|
||||
@ -406,8 +393,6 @@ class _SnAccount extends SnAccount {
|
||||
const DeepCollectionEquality().equals(other._contacts, _contacts) &&
|
||||
(identical(other.avatar, avatar) || other.avatar == avatar) &&
|
||||
(identical(other.banner, banner) || other.banner == banner) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.nick, nick) || other.nick == nick) &&
|
||||
const DeepCollectionEquality()
|
||||
@ -440,7 +425,6 @@ class _SnAccount extends SnAccount {
|
||||
const DeepCollectionEquality().hash(_contacts),
|
||||
avatar,
|
||||
banner,
|
||||
description,
|
||||
name,
|
||||
nick,
|
||||
const DeepCollectionEquality().hash(_permNodes),
|
||||
@ -456,7 +440,7 @@ class _SnAccount extends SnAccount {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnAccount(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, confirmedAt: $confirmedAt, contacts: $contacts, avatar: $avatar, banner: $banner, description: $description, name: $name, nick: $nick, permNodes: $permNodes, language: $language, profile: $profile, badges: $badges, suspendedAt: $suspendedAt, affiliatedId: $affiliatedId, affiliatedTo: $affiliatedTo, automatedBy: $automatedBy, automatedId: $automatedId)';
|
||||
return 'SnAccount(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, confirmedAt: $confirmedAt, contacts: $contacts, avatar: $avatar, banner: $banner, name: $name, nick: $nick, permNodes: $permNodes, language: $language, profile: $profile, badges: $badges, suspendedAt: $suspendedAt, affiliatedId: $affiliatedId, affiliatedTo: $affiliatedTo, automatedBy: $automatedBy, automatedId: $automatedId)';
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,7 +461,6 @@ abstract mixin class _$SnAccountCopyWith<$Res>
|
||||
List<SnAccountContact>? contacts,
|
||||
String avatar,
|
||||
String banner,
|
||||
String description,
|
||||
String name,
|
||||
String nick,
|
||||
Map<String, dynamic> permNodes,
|
||||
@ -514,7 +497,6 @@ class __$SnAccountCopyWithImpl<$Res> implements _$SnAccountCopyWith<$Res> {
|
||||
Object? contacts = freezed,
|
||||
Object? avatar = null,
|
||||
Object? banner = null,
|
||||
Object? description = null,
|
||||
Object? name = null,
|
||||
Object? nick = null,
|
||||
Object? permNodes = null,
|
||||
@ -560,10 +542,6 @@ class __$SnAccountCopyWithImpl<$Res> implements _$SnAccountCopyWith<$Res> {
|
||||
? _self.banner
|
||||
: banner // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _self.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
name: null == name
|
||||
? _self.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
@ -954,15 +932,21 @@ class __$SnAccountContactCopyWithImpl<$Res>
|
||||
/// @nodoc
|
||||
mixin _$SnAccountProfile {
|
||||
int get id;
|
||||
int get accountId;
|
||||
DateTime? get birthday;
|
||||
DateTime get createdAt;
|
||||
DateTime get updatedAt;
|
||||
DateTime? get deletedAt;
|
||||
int get experience;
|
||||
String get firstName;
|
||||
String get lastName;
|
||||
String get description;
|
||||
String get timeZone;
|
||||
String get location;
|
||||
String get pronouns;
|
||||
String get gender;
|
||||
Map<String, String> get links;
|
||||
int get experience;
|
||||
DateTime? get lastSeenAt;
|
||||
DateTime get updatedAt;
|
||||
DateTime? get birthday;
|
||||
int get accountId;
|
||||
|
||||
/// Create a copy of SnAccountProfile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@ -981,24 +965,34 @@ mixin _$SnAccountProfile {
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is SnAccountProfile &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.accountId, accountId) ||
|
||||
other.accountId == accountId) &&
|
||||
(identical(other.birthday, birthday) ||
|
||||
other.birthday == birthday) &&
|
||||
(identical(other.createdAt, createdAt) ||
|
||||
other.createdAt == createdAt) &&
|
||||
(identical(other.updatedAt, updatedAt) ||
|
||||
other.updatedAt == updatedAt) &&
|
||||
(identical(other.deletedAt, deletedAt) ||
|
||||
other.deletedAt == deletedAt) &&
|
||||
(identical(other.experience, experience) ||
|
||||
other.experience == experience) &&
|
||||
(identical(other.firstName, firstName) ||
|
||||
other.firstName == firstName) &&
|
||||
(identical(other.lastName, lastName) ||
|
||||
other.lastName == lastName) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
(identical(other.timeZone, timeZone) ||
|
||||
other.timeZone == timeZone) &&
|
||||
(identical(other.location, location) ||
|
||||
other.location == location) &&
|
||||
(identical(other.pronouns, pronouns) ||
|
||||
other.pronouns == pronouns) &&
|
||||
(identical(other.gender, gender) || other.gender == gender) &&
|
||||
const DeepCollectionEquality().equals(other.links, links) &&
|
||||
(identical(other.experience, experience) ||
|
||||
other.experience == experience) &&
|
||||
(identical(other.lastSeenAt, lastSeenAt) ||
|
||||
other.lastSeenAt == lastSeenAt) &&
|
||||
(identical(other.updatedAt, updatedAt) ||
|
||||
other.updatedAt == updatedAt));
|
||||
(identical(other.birthday, birthday) ||
|
||||
other.birthday == birthday) &&
|
||||
(identical(other.accountId, accountId) ||
|
||||
other.accountId == accountId));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -1006,19 +1000,25 @@ mixin _$SnAccountProfile {
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
id,
|
||||
accountId,
|
||||
birthday,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
deletedAt,
|
||||
experience,
|
||||
firstName,
|
||||
lastName,
|
||||
description,
|
||||
timeZone,
|
||||
location,
|
||||
pronouns,
|
||||
gender,
|
||||
const DeepCollectionEquality().hash(links),
|
||||
experience,
|
||||
lastSeenAt,
|
||||
updatedAt);
|
||||
birthday,
|
||||
accountId);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnAccountProfile(id: $id, accountId: $accountId, birthday: $birthday, createdAt: $createdAt, deletedAt: $deletedAt, experience: $experience, firstName: $firstName, lastName: $lastName, lastSeenAt: $lastSeenAt, updatedAt: $updatedAt)';
|
||||
return 'SnAccountProfile(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, firstName: $firstName, lastName: $lastName, description: $description, timeZone: $timeZone, location: $location, pronouns: $pronouns, gender: $gender, links: $links, experience: $experience, lastSeenAt: $lastSeenAt, birthday: $birthday, accountId: $accountId)';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1030,15 +1030,21 @@ abstract mixin class $SnAccountProfileCopyWith<$Res> {
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
int accountId,
|
||||
DateTime? birthday,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime? deletedAt,
|
||||
int experience,
|
||||
String firstName,
|
||||
String lastName,
|
||||
String description,
|
||||
String timeZone,
|
||||
String location,
|
||||
String pronouns,
|
||||
String gender,
|
||||
Map<String, String> links,
|
||||
int experience,
|
||||
DateTime? lastSeenAt,
|
||||
DateTime updatedAt});
|
||||
DateTime? birthday,
|
||||
int accountId});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -1055,41 +1061,39 @@ class _$SnAccountProfileCopyWithImpl<$Res>
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? accountId = null,
|
||||
Object? birthday = freezed,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
Object? deletedAt = freezed,
|
||||
Object? experience = null,
|
||||
Object? firstName = null,
|
||||
Object? lastName = null,
|
||||
Object? description = null,
|
||||
Object? timeZone = null,
|
||||
Object? location = null,
|
||||
Object? pronouns = null,
|
||||
Object? gender = null,
|
||||
Object? links = null,
|
||||
Object? experience = null,
|
||||
Object? lastSeenAt = freezed,
|
||||
Object? updatedAt = null,
|
||||
Object? birthday = freezed,
|
||||
Object? accountId = null,
|
||||
}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id
|
||||
? _self.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
accountId: null == accountId
|
||||
? _self.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
birthday: freezed == birthday
|
||||
? _self.birthday
|
||||
: birthday // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
createdAt: null == createdAt
|
||||
? _self.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
? _self.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
deletedAt: freezed == deletedAt
|
||||
? _self.deletedAt
|
||||
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
experience: null == experience
|
||||
? _self.experience
|
||||
: experience // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
firstName: null == firstName
|
||||
? _self.firstName
|
||||
: firstName // ignore: cast_nullable_to_non_nullable
|
||||
@ -1098,14 +1102,46 @@ class _$SnAccountProfileCopyWithImpl<$Res>
|
||||
? _self.lastName
|
||||
: lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _self.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
timeZone: null == timeZone
|
||||
? _self.timeZone
|
||||
: timeZone // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
location: null == location
|
||||
? _self.location
|
||||
: location // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
pronouns: null == pronouns
|
||||
? _self.pronouns
|
||||
: pronouns // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
gender: null == gender
|
||||
? _self.gender
|
||||
: gender // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
links: null == links
|
||||
? _self.links
|
||||
: links // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>,
|
||||
experience: null == experience
|
||||
? _self.experience
|
||||
: experience // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
lastSeenAt: freezed == lastSeenAt
|
||||
? _self.lastSeenAt
|
||||
: lastSeenAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
updatedAt: null == updatedAt
|
||||
? _self.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
birthday: freezed == birthday
|
||||
? _self.birthday
|
||||
: birthday // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
accountId: null == accountId
|
||||
? _self.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -1115,38 +1151,64 @@ class _$SnAccountProfileCopyWithImpl<$Res>
|
||||
class _SnAccountProfile implements SnAccountProfile {
|
||||
const _SnAccountProfile(
|
||||
{required this.id,
|
||||
required this.accountId,
|
||||
required this.birthday,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.deletedAt,
|
||||
required this.experience,
|
||||
required this.firstName,
|
||||
required this.lastName,
|
||||
required this.description,
|
||||
required this.timeZone,
|
||||
required this.location,
|
||||
required this.pronouns,
|
||||
required this.gender,
|
||||
final Map<String, String> links = const {},
|
||||
required this.experience,
|
||||
required this.lastSeenAt,
|
||||
required this.updatedAt});
|
||||
required this.birthday,
|
||||
required this.accountId})
|
||||
: _links = links;
|
||||
factory _SnAccountProfile.fromJson(Map<String, dynamic> json) =>
|
||||
_$SnAccountProfileFromJson(json);
|
||||
|
||||
@override
|
||||
final int id;
|
||||
@override
|
||||
final int accountId;
|
||||
@override
|
||||
final DateTime? birthday;
|
||||
@override
|
||||
final DateTime createdAt;
|
||||
@override
|
||||
final DateTime? deletedAt;
|
||||
final DateTime updatedAt;
|
||||
@override
|
||||
final int experience;
|
||||
final DateTime? deletedAt;
|
||||
@override
|
||||
final String firstName;
|
||||
@override
|
||||
final String lastName;
|
||||
@override
|
||||
final String description;
|
||||
@override
|
||||
final String timeZone;
|
||||
@override
|
||||
final String location;
|
||||
@override
|
||||
final String pronouns;
|
||||
@override
|
||||
final String gender;
|
||||
final Map<String, String> _links;
|
||||
@override
|
||||
@JsonKey()
|
||||
Map<String, String> get links {
|
||||
if (_links is EqualUnmodifiableMapView) return _links;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(_links);
|
||||
}
|
||||
|
||||
@override
|
||||
final int experience;
|
||||
@override
|
||||
final DateTime? lastSeenAt;
|
||||
@override
|
||||
final DateTime updatedAt;
|
||||
final DateTime? birthday;
|
||||
@override
|
||||
final int accountId;
|
||||
|
||||
/// Create a copy of SnAccountProfile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@ -1169,24 +1231,34 @@ class _SnAccountProfile implements SnAccountProfile {
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _SnAccountProfile &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.accountId, accountId) ||
|
||||
other.accountId == accountId) &&
|
||||
(identical(other.birthday, birthday) ||
|
||||
other.birthday == birthday) &&
|
||||
(identical(other.createdAt, createdAt) ||
|
||||
other.createdAt == createdAt) &&
|
||||
(identical(other.updatedAt, updatedAt) ||
|
||||
other.updatedAt == updatedAt) &&
|
||||
(identical(other.deletedAt, deletedAt) ||
|
||||
other.deletedAt == deletedAt) &&
|
||||
(identical(other.experience, experience) ||
|
||||
other.experience == experience) &&
|
||||
(identical(other.firstName, firstName) ||
|
||||
other.firstName == firstName) &&
|
||||
(identical(other.lastName, lastName) ||
|
||||
other.lastName == lastName) &&
|
||||
(identical(other.description, description) ||
|
||||
other.description == description) &&
|
||||
(identical(other.timeZone, timeZone) ||
|
||||
other.timeZone == timeZone) &&
|
||||
(identical(other.location, location) ||
|
||||
other.location == location) &&
|
||||
(identical(other.pronouns, pronouns) ||
|
||||
other.pronouns == pronouns) &&
|
||||
(identical(other.gender, gender) || other.gender == gender) &&
|
||||
const DeepCollectionEquality().equals(other._links, _links) &&
|
||||
(identical(other.experience, experience) ||
|
||||
other.experience == experience) &&
|
||||
(identical(other.lastSeenAt, lastSeenAt) ||
|
||||
other.lastSeenAt == lastSeenAt) &&
|
||||
(identical(other.updatedAt, updatedAt) ||
|
||||
other.updatedAt == updatedAt));
|
||||
(identical(other.birthday, birthday) ||
|
||||
other.birthday == birthday) &&
|
||||
(identical(other.accountId, accountId) ||
|
||||
other.accountId == accountId));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -1194,19 +1266,25 @@ class _SnAccountProfile implements SnAccountProfile {
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
id,
|
||||
accountId,
|
||||
birthday,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
deletedAt,
|
||||
experience,
|
||||
firstName,
|
||||
lastName,
|
||||
description,
|
||||
timeZone,
|
||||
location,
|
||||
pronouns,
|
||||
gender,
|
||||
const DeepCollectionEquality().hash(_links),
|
||||
experience,
|
||||
lastSeenAt,
|
||||
updatedAt);
|
||||
birthday,
|
||||
accountId);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnAccountProfile(id: $id, accountId: $accountId, birthday: $birthday, createdAt: $createdAt, deletedAt: $deletedAt, experience: $experience, firstName: $firstName, lastName: $lastName, lastSeenAt: $lastSeenAt, updatedAt: $updatedAt)';
|
||||
return 'SnAccountProfile(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, firstName: $firstName, lastName: $lastName, description: $description, timeZone: $timeZone, location: $location, pronouns: $pronouns, gender: $gender, links: $links, experience: $experience, lastSeenAt: $lastSeenAt, birthday: $birthday, accountId: $accountId)';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1220,15 +1298,21 @@ abstract mixin class _$SnAccountProfileCopyWith<$Res>
|
||||
@useResult
|
||||
$Res call(
|
||||
{int id,
|
||||
int accountId,
|
||||
DateTime? birthday,
|
||||
DateTime createdAt,
|
||||
DateTime updatedAt,
|
||||
DateTime? deletedAt,
|
||||
int experience,
|
||||
String firstName,
|
||||
String lastName,
|
||||
String description,
|
||||
String timeZone,
|
||||
String location,
|
||||
String pronouns,
|
||||
String gender,
|
||||
Map<String, String> links,
|
||||
int experience,
|
||||
DateTime? lastSeenAt,
|
||||
DateTime updatedAt});
|
||||
DateTime? birthday,
|
||||
int accountId});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -1245,41 +1329,39 @@ class __$SnAccountProfileCopyWithImpl<$Res>
|
||||
@pragma('vm:prefer-inline')
|
||||
$Res call({
|
||||
Object? id = null,
|
||||
Object? accountId = null,
|
||||
Object? birthday = freezed,
|
||||
Object? createdAt = null,
|
||||
Object? updatedAt = null,
|
||||
Object? deletedAt = freezed,
|
||||
Object? experience = null,
|
||||
Object? firstName = null,
|
||||
Object? lastName = null,
|
||||
Object? description = null,
|
||||
Object? timeZone = null,
|
||||
Object? location = null,
|
||||
Object? pronouns = null,
|
||||
Object? gender = null,
|
||||
Object? links = null,
|
||||
Object? experience = null,
|
||||
Object? lastSeenAt = freezed,
|
||||
Object? updatedAt = null,
|
||||
Object? birthday = freezed,
|
||||
Object? accountId = null,
|
||||
}) {
|
||||
return _then(_SnAccountProfile(
|
||||
id: null == id
|
||||
? _self.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
accountId: null == accountId
|
||||
? _self.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
birthday: freezed == birthday
|
||||
? _self.birthday
|
||||
: birthday // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
createdAt: null == createdAt
|
||||
? _self.createdAt
|
||||
: createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
updatedAt: null == updatedAt
|
||||
? _self.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
deletedAt: freezed == deletedAt
|
||||
? _self.deletedAt
|
||||
: deletedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
experience: null == experience
|
||||
? _self.experience
|
||||
: experience // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
firstName: null == firstName
|
||||
? _self.firstName
|
||||
: firstName // ignore: cast_nullable_to_non_nullable
|
||||
@ -1288,14 +1370,46 @@ class __$SnAccountProfileCopyWithImpl<$Res>
|
||||
? _self.lastName
|
||||
: lastName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
description: null == description
|
||||
? _self.description
|
||||
: description // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
timeZone: null == timeZone
|
||||
? _self.timeZone
|
||||
: timeZone // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
location: null == location
|
||||
? _self.location
|
||||
: location // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
pronouns: null == pronouns
|
||||
? _self.pronouns
|
||||
: pronouns // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
gender: null == gender
|
||||
? _self.gender
|
||||
: gender // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
links: null == links
|
||||
? _self._links
|
||||
: links // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>,
|
||||
experience: null == experience
|
||||
? _self.experience
|
||||
: experience // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
lastSeenAt: freezed == lastSeenAt
|
||||
? _self.lastSeenAt
|
||||
: lastSeenAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
updatedAt: null == updatedAt
|
||||
? _self.updatedAt
|
||||
: updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
birthday: freezed == birthday
|
||||
? _self.birthday
|
||||
: birthday // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
accountId: null == accountId
|
||||
? _self.accountId
|
||||
: accountId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ _SnAccount _$SnAccountFromJson(Map<String, dynamic> json) => _SnAccount(
|
||||
.toList(),
|
||||
avatar: json['avatar'] as String? ?? "",
|
||||
banner: json['banner'] as String? ?? "",
|
||||
description: json['description'] as String,
|
||||
name: json['name'] as String,
|
||||
nick: json['nick'] as String,
|
||||
permNodes: json['perm_nodes'] as Map<String, dynamic>? ?? const {},
|
||||
@ -52,7 +51,6 @@ Map<String, dynamic> _$SnAccountToJson(_SnAccount instance) =>
|
||||
'contacts': instance.contacts?.map((e) => e.toJson()).toList(),
|
||||
'avatar': instance.avatar,
|
||||
'banner': instance.banner,
|
||||
'description': instance.description,
|
||||
'name': instance.name,
|
||||
'nick': instance.nick,
|
||||
'perm_nodes': instance.permNodes,
|
||||
@ -101,35 +99,50 @@ Map<String, dynamic> _$SnAccountContactToJson(_SnAccountContact instance) =>
|
||||
_SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
|
||||
_SnAccountProfile(
|
||||
id: (json['id'] as num).toInt(),
|
||||
accountId: (json['account_id'] as num).toInt(),
|
||||
birthday: json['birthday'] == null
|
||||
? null
|
||||
: DateTime.parse(json['birthday'] as String),
|
||||
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),
|
||||
experience: (json['experience'] as num).toInt(),
|
||||
firstName: json['first_name'] as String,
|
||||
lastName: json['last_name'] as String,
|
||||
description: json['description'] as String,
|
||||
timeZone: json['time_zone'] as String,
|
||||
location: json['location'] as String,
|
||||
pronouns: json['pronouns'] as String,
|
||||
gender: json['gender'] as String,
|
||||
links: (json['links'] as Map<String, dynamic>?)?.map(
|
||||
(k, e) => MapEntry(k, e as String),
|
||||
) ??
|
||||
const {},
|
||||
experience: (json['experience'] as num).toInt(),
|
||||
lastSeenAt: json['last_seen_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['last_seen_at'] as String),
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
birthday: json['birthday'] == null
|
||||
? null
|
||||
: DateTime.parse(json['birthday'] as String),
|
||||
accountId: (json['account_id'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SnAccountProfileToJson(_SnAccountProfile instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'account_id': instance.accountId,
|
||||
'birthday': instance.birthday?.toIso8601String(),
|
||||
'created_at': instance.createdAt.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||
'experience': instance.experience,
|
||||
'first_name': instance.firstName,
|
||||
'last_name': instance.lastName,
|
||||
'description': instance.description,
|
||||
'time_zone': instance.timeZone,
|
||||
'location': instance.location,
|
||||
'pronouns': instance.pronouns,
|
||||
'gender': instance.gender,
|
||||
'links': instance.links,
|
||||
'experience': instance.experience,
|
||||
'last_seen_at': instance.lastSeenAt?.toIso8601String(),
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'birthday': instance.birthday?.toIso8601String(),
|
||||
'account_id': instance.accountId,
|
||||
};
|
||||
|
||||
_SnRelationship _$SnRelationshipFromJson(Map<String, dynamic> json) =>
|
||||
|
@ -92,10 +92,9 @@ class OpenablePostItem extends StatelessWidget {
|
||||
openColor: Colors.transparent,
|
||||
openElevation: 0,
|
||||
transitionType: ContainerTransitionType.fade,
|
||||
closedColor:
|
||||
Theme.of(context).colorScheme.surfaceContainerLow.withOpacity(
|
||||
cfg.prefs.getBool(kAppBackgroundStoreKey) == true ? 0.75 : 1,
|
||||
),
|
||||
closedColor: Theme.of(context).colorScheme.surfaceContainerLow.withOpacity(
|
||||
cfg.prefs.getBool(kAppBackgroundStoreKey) == true ? 0.75 : 1,
|
||||
),
|
||||
closedShape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
),
|
||||
@ -136,11 +135,9 @@ class PostItem extends StatelessWidget {
|
||||
final box = context.findRenderObject() as RenderBox?;
|
||||
final url = 'https://solsynth.dev/posts/${data.id}';
|
||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||
Share.shareUri(Uri.parse(url),
|
||||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||
Share.shareUri(Uri.parse(url), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||
} else {
|
||||
Share.share(url,
|
||||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||
Share.share(url, sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,8 +155,7 @@ class PostItem extends StatelessWidget {
|
||||
child: MultiProvider(
|
||||
providers: [
|
||||
Provider<SnNetworkProvider>(create: (_) => context.read()),
|
||||
ChangeNotifierProvider<ConfigProvider>(
|
||||
create: (_) => context.read()),
|
||||
ChangeNotifierProvider<ConfigProvider>(create: (_) => context.read()),
|
||||
],
|
||||
child: ResponsiveBreakpoints.builder(
|
||||
breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
|
||||
@ -187,8 +183,7 @@ class PostItem extends StatelessWidget {
|
||||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
||||
);
|
||||
} else {
|
||||
await FileSaver.instance.saveFile(
|
||||
name: 'Solar Network Post #${data.id}.png', file: imageFile);
|
||||
await FileSaver.instance.saveFile(name: 'Solar Network Post #${data.id}.png', file: imageFile);
|
||||
}
|
||||
|
||||
await imageFile.delete();
|
||||
@ -202,9 +197,7 @@ class PostItem extends StatelessWidget {
|
||||
final isAuthor = ua.isAuthorized && data.publisher.accountId == ua.user?.id;
|
||||
|
||||
// Video full view
|
||||
if (showFullPost &&
|
||||
data.type == 'video' &&
|
||||
ResponsiveBreakpoints.of(context).largerThan(TABLET)) {
|
||||
if (showFullPost && data.type == 'video' && ResponsiveBreakpoints.of(context).largerThan(TABLET)) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -224,8 +217,7 @@ class PostItem extends StatelessWidget {
|
||||
if (onDeleted != null) {}
|
||||
},
|
||||
).padding(bottom: 8),
|
||||
if (data.preload?.video != null)
|
||||
_PostVideoPlayer(data: data).padding(bottom: 8),
|
||||
if (data.preload?.video != null) _PostVideoPlayer(data: data).padding(bottom: 8),
|
||||
_PostHeadline(data: data).padding(horizontal: 4, bottom: 8),
|
||||
_PostFeaturedComment(data: data),
|
||||
_PostBottomAction(
|
||||
@ -273,8 +265,7 @@ class PostItem extends StatelessWidget {
|
||||
if (onDeleted != null) {}
|
||||
},
|
||||
).padding(horizontal: 12, top: 8, bottom: 8),
|
||||
if (data.preload?.video != null)
|
||||
_PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
||||
if (data.preload?.video != null) _PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
margin: const EdgeInsets.only(bottom: 4, left: 12, right: 12),
|
||||
@ -317,13 +308,8 @@ class PostItem extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
Text('postArticle')
|
||||
.tr()
|
||||
.fontSize(13)
|
||||
.opacity(0.75)
|
||||
.padding(horizontal: 24, bottom: 8),
|
||||
_PostFeaturedComment(data: data, maxWidth: maxWidth)
|
||||
.padding(horizontal: 12),
|
||||
Text('postArticle').tr().fontSize(13).opacity(0.75).padding(horizontal: 24, bottom: 8),
|
||||
_PostFeaturedComment(data: data, maxWidth: maxWidth).padding(horizontal: 12),
|
||||
_PostBottomAction(
|
||||
data: data,
|
||||
showComments: showComments,
|
||||
@ -338,8 +324,7 @@ class PostItem extends StatelessWidget {
|
||||
}
|
||||
|
||||
final displayableAttachments = data.preload?.attachments
|
||||
?.where((ele) =>
|
||||
ele?.mediaType != SnMediaType.image || data.type != 'article')
|
||||
?.where((ele) => ele?.mediaType != SnMediaType.image || data.type != 'article')
|
||||
.toList();
|
||||
|
||||
final cfg = context.read<ConfigProvider>();
|
||||
@ -364,13 +349,9 @@ class PostItem extends StatelessWidget {
|
||||
if (onDeleted != null) onDeleted!();
|
||||
},
|
||||
).padding(horizontal: 12, vertical: 8),
|
||||
if (data.preload?.video != null)
|
||||
_PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
||||
if (data.type == 'question')
|
||||
_PostQuestionHint(data: data)
|
||||
.padding(horizontal: 16, bottom: 8),
|
||||
if (data.body['title'] != null ||
|
||||
data.body['description'] != null)
|
||||
if (data.preload?.video != null) _PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
||||
if (data.type == 'question') _PostQuestionHint(data: data).padding(horizontal: 16, bottom: 8),
|
||||
if (data.body['title'] != null || data.body['description'] != null)
|
||||
_PostHeadline(
|
||||
data: data,
|
||||
isEnlarge: data.type == 'article' && showFullPost,
|
||||
@ -384,8 +365,7 @@ class PostItem extends StatelessWidget {
|
||||
if (data.repostTo != null)
|
||||
_PostQuoteContent(child: data.repostTo!).padding(
|
||||
horizontal: 12,
|
||||
bottom:
|
||||
data.preload?.attachments?.isNotEmpty ?? false ? 12 : 0,
|
||||
bottom: data.preload?.attachments?.isNotEmpty ?? false ? 12 : 0,
|
||||
),
|
||||
if (data.visibility > 0)
|
||||
_PostVisibilityHint(data: data).padding(
|
||||
@ -397,9 +377,7 @@ class PostItem extends StatelessWidget {
|
||||
horizontal: 16,
|
||||
vertical: 4,
|
||||
),
|
||||
if (data.tags.isNotEmpty)
|
||||
_PostTagsList(data: data)
|
||||
.padding(horizontal: 16, top: 4, bottom: 6),
|
||||
if (data.tags.isNotEmpty) _PostTagsList(data: data).padding(horizontal: 16, top: 4, bottom: 6),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -412,16 +390,12 @@ class PostItem extends StatelessWidget {
|
||||
fit: showFullPost ? BoxFit.cover : BoxFit.contain,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
),
|
||||
if (data.preload?.poll != null)
|
||||
PostPoll(poll: data.preload!.poll!)
|
||||
.padding(horizontal: 12, vertical: 4),
|
||||
if (data.body['content'] != null &&
|
||||
(cfg.prefs.getBool(kAppExpandPostLink) ?? true))
|
||||
if (data.preload?.poll != null) PostPoll(poll: data.preload!.poll!).padding(horizontal: 12, vertical: 4),
|
||||
if (data.body['content'] != null && (cfg.prefs.getBool(kAppExpandPostLink) ?? true))
|
||||
LinkPreviewWidget(
|
||||
text: data.body['content'],
|
||||
).padding(horizontal: 4),
|
||||
_PostFeaturedComment(data: data, maxWidth: maxWidth)
|
||||
.padding(horizontal: 12),
|
||||
_PostFeaturedComment(data: data, maxWidth: maxWidth).padding(horizontal: 12),
|
||||
Container(
|
||||
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
|
||||
child: Column(
|
||||
@ -483,8 +457,7 @@ class PostShareImageWidget extends StatelessWidget {
|
||||
showMenu: false,
|
||||
isRelativeDate: false,
|
||||
).padding(horizontal: 16, bottom: 8),
|
||||
if (data.type == 'question')
|
||||
_PostQuestionHint(data: data).padding(horizontal: 16, bottom: 8),
|
||||
if (data.type == 'question') _PostQuestionHint(data: data).padding(horizontal: 16, bottom: 8),
|
||||
_PostHeadline(
|
||||
data: data,
|
||||
isEnlarge: data.type == 'article',
|
||||
@ -499,8 +472,7 @@ class PostShareImageWidget extends StatelessWidget {
|
||||
child: data.repostTo!,
|
||||
isRelativeDate: false,
|
||||
).padding(horizontal: 16, bottom: 8),
|
||||
if (data.type != 'article' &&
|
||||
(data.preload?.attachments?.isNotEmpty ?? false))
|
||||
if (data.type != 'article' && (data.preload?.attachments?.isNotEmpty ?? false))
|
||||
StyledWidget(AttachmentList(
|
||||
data: data.preload!.attachments!,
|
||||
columned: true,
|
||||
@ -509,8 +481,7 @@ class PostShareImageWidget extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (data.visibility > 0) _PostVisibilityHint(data: data),
|
||||
if (data.body['content_truncated'] == true)
|
||||
_PostTruncatedHint(data: data),
|
||||
if (data.body['content_truncated'] == true) _PostTruncatedHint(data: data),
|
||||
],
|
||||
).padding(horizontal: 16),
|
||||
_PostBottomAction(
|
||||
@ -570,8 +541,7 @@ class PostShareImageWidget extends StatelessWidget {
|
||||
version: QrVersions.auto,
|
||||
size: 100,
|
||||
gapless: true,
|
||||
embeddedImage:
|
||||
AssetImage('assets/icon/icon-light-radius.png'),
|
||||
embeddedImage: AssetImage('assets/icon/icon-light-radius.png'),
|
||||
embeddedImageStyle: QrEmbeddedImageStyle(
|
||||
size: Size(28, 28),
|
||||
),
|
||||
@ -602,11 +572,9 @@ class _PostQuestionHint extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Icon(data.body['answer'] == null ? Symbols.help : Symbols.check_circle,
|
||||
size: 20),
|
||||
Icon(data.body['answer'] == null ? Symbols.help : Symbols.check_circle, size: 20),
|
||||
const Gap(4),
|
||||
if (data.body['answer'] == null &&
|
||||
data.body['reward']?.toDouble() != null)
|
||||
if (data.body['answer'] == null && data.body['reward']?.toDouble() != null)
|
||||
Text('postQuestionUnansweredWithReward'.tr(args: [
|
||||
'${data.body['reward']}',
|
||||
])).opacity(0.75)
|
||||
@ -642,9 +610,7 @@ class _PostBottomAction extends StatelessWidget {
|
||||
);
|
||||
|
||||
final String? mostTypicalReaction = data.metric.reactionList.isNotEmpty
|
||||
? data.metric.reactionList.entries
|
||||
.reduce((a, b) => a.value > b.value ? a : b)
|
||||
.key
|
||||
? data.metric.reactionList.entries.reduce((a, b) => a.value > b.value ? a : b).key
|
||||
: null;
|
||||
|
||||
return Row(
|
||||
@ -658,8 +624,7 @@ class _PostBottomAction extends StatelessWidget {
|
||||
InkWell(
|
||||
child: Row(
|
||||
children: [
|
||||
if (mostTypicalReaction == null ||
|
||||
kTemplateReactions[mostTypicalReaction] == null)
|
||||
if (mostTypicalReaction == null || kTemplateReactions[mostTypicalReaction] == null)
|
||||
Icon(Symbols.add_reaction, size: 20, color: iconColor)
|
||||
else
|
||||
Text(
|
||||
@ -671,8 +636,7 @@ class _PostBottomAction extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
if (data.totalUpvote > 0 &&
|
||||
data.totalUpvote >= data.totalDownvote)
|
||||
if (data.totalUpvote > 0 && data.totalUpvote >= data.totalDownvote)
|
||||
Text('postReactionUpvote').plural(
|
||||
data.totalUpvote,
|
||||
)
|
||||
@ -691,12 +655,8 @@ class _PostBottomAction extends StatelessWidget {
|
||||
data: data,
|
||||
onChanged: (value, attr, delta) {
|
||||
onChanged(data.copyWith(
|
||||
totalUpvote: attr == 1
|
||||
? data.totalUpvote + delta
|
||||
: data.totalUpvote,
|
||||
totalDownvote: attr == 2
|
||||
? data.totalDownvote + delta
|
||||
: data.totalDownvote,
|
||||
totalUpvote: attr == 1 ? data.totalUpvote + delta : data.totalUpvote,
|
||||
totalDownvote: attr == 2 ? data.totalDownvote + delta : data.totalDownvote,
|
||||
metric: data.metric.copyWith(reactionList: value),
|
||||
));
|
||||
},
|
||||
@ -803,7 +763,7 @@ class _PostHeadline extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'articleWrittenAt'.tr(
|
||||
args: [DateFormat('y/M/d HH:mm').format(data.createdAt)],
|
||||
args: [DateFormat('y/M/d HH:mm').format(data.createdAt.toLocal())],
|
||||
),
|
||||
style: TextStyle(fontSize: 13),
|
||||
),
|
||||
@ -811,7 +771,7 @@ class _PostHeadline extends StatelessWidget {
|
||||
if (data.editedAt != null)
|
||||
Text(
|
||||
'articleEditedAt'.tr(
|
||||
args: [DateFormat('y/M/d HH:mm').format(data.editedAt!)],
|
||||
args: [DateFormat('y/M/d HH:mm').format(data.editedAt!.toLocal())],
|
||||
),
|
||||
style: TextStyle(fontSize: 13),
|
||||
),
|
||||
@ -944,10 +904,8 @@ class _PostContentHeader extends StatelessWidget {
|
||||
const Gap(4),
|
||||
Text(
|
||||
isRelativeDate
|
||||
? RelativeTime(context)
|
||||
.format(data.publishedAt ?? data.createdAt)
|
||||
: DateFormat('y/M/d HH:mm')
|
||||
.format(data.publishedAt ?? data.createdAt),
|
||||
? RelativeTime(context).format((data.publishedAt ?? data.createdAt).toLocal())
|
||||
: DateFormat('y/M/d HH:mm').format((data.publishedAt ?? data.createdAt).toLocal()),
|
||||
).fontSize(13),
|
||||
],
|
||||
).opacity(0.8),
|
||||
@ -965,10 +923,8 @@ class _PostContentHeader extends StatelessWidget {
|
||||
const Gap(4),
|
||||
Text(
|
||||
isRelativeDate
|
||||
? RelativeTime(context)
|
||||
.format(data.publishedAt ?? data.createdAt)
|
||||
: DateFormat('y/M/d HH:mm')
|
||||
.format(data.publishedAt ?? data.createdAt),
|
||||
? RelativeTime(context).format((data.publishedAt ?? data.createdAt).toLocal())
|
||||
: DateFormat('y/M/d HH:mm').format((data.publishedAt ?? data.createdAt).toLocal()),
|
||||
).fontSize(13),
|
||||
],
|
||||
).opacity(0.8),
|
||||
@ -1151,8 +1107,7 @@ class _PostContentBody extends StatelessWidget {
|
||||
if (data.body['content'] == null) return const SizedBox.shrink();
|
||||
final content = MarkdownTextContent(
|
||||
isAutoWarp: data.type == 'story',
|
||||
isEnlargeSticker:
|
||||
RegExp(r"^:([-\w]+):$").hasMatch(data.body['content'] ?? ''),
|
||||
isEnlargeSticker: RegExp(r"^:([-\w]+):$").hasMatch(data.body['content'] ?? ''),
|
||||
textScaler: isEnlarge ? TextScaler.linear(1.1) : null,
|
||||
content: data.body['content'],
|
||||
attachments: data.preload?.attachments,
|
||||
@ -1201,12 +1156,10 @@ class _PostQuoteContent extends StatelessWidget {
|
||||
onDeleted: () {},
|
||||
).padding(bottom: 4),
|
||||
_PostContentBody(data: child),
|
||||
if (child.visibility > 0)
|
||||
_PostVisibilityHint(data: child).padding(top: 4),
|
||||
if (child.visibility > 0) _PostVisibilityHint(data: child).padding(top: 4),
|
||||
],
|
||||
).padding(horizontal: 16),
|
||||
if (child.type != 'article' &&
|
||||
(child.preload?.attachments?.isNotEmpty ?? false))
|
||||
if (child.type != 'article' && (child.preload?.attachments?.isNotEmpty ?? false))
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(8),
|
||||
@ -1357,9 +1310,7 @@ class _PostTruncatedHint extends StatelessWidget {
|
||||
const Gap(4),
|
||||
Text('postReadEstimate').tr(args: [
|
||||
'${Duration(
|
||||
seconds: (data.body['content_length'] as num).toDouble() *
|
||||
60 ~/
|
||||
kHumanReadSpeed,
|
||||
seconds: (data.body['content_length'] as num).toDouble() * 60 ~/ kHumanReadSpeed,
|
||||
).inSeconds}s',
|
||||
]),
|
||||
],
|
||||
@ -1398,8 +1349,7 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
||||
// If this is a answered question, fetch the answer instead
|
||||
if (widget.data.type == 'question' && widget.data.body['answer'] != null) {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final resp =
|
||||
await sn.client.get('/cgi/co/posts/${widget.data.body['answer']}');
|
||||
final resp = await sn.client.get('/cgi/co/posts/${widget.data.body['answer']}');
|
||||
_isAnswer = true;
|
||||
setState(() => _featuredComment = SnPost.fromJson(resp.data));
|
||||
return;
|
||||
@ -1407,11 +1357,9 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
||||
|
||||
try {
|
||||
final sn = context.read<SnNetworkProvider>();
|
||||
final resp = await sn.client.get(
|
||||
'/cgi/co/posts/${widget.data.id}/replies/featured',
|
||||
queryParameters: {
|
||||
'take': 1,
|
||||
});
|
||||
final resp = await sn.client.get('/cgi/co/posts/${widget.data.id}/replies/featured', queryParameters: {
|
||||
'take': 1,
|
||||
});
|
||||
setState(() => _featuredComment = SnPost.fromJson(resp.data[0]));
|
||||
} catch (err) {
|
||||
if (!mounted) return;
|
||||
@ -1440,9 +1388,7 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
||||
width: double.infinity,
|
||||
child: Material(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
color: _isAnswer
|
||||
? Colors.green.withOpacity(0.5)
|
||||
: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
color: _isAnswer ? Colors.green.withOpacity(0.5) : Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
onTap: () {
|
||||
@ -1462,17 +1408,11 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Gap(2),
|
||||
Icon(_isAnswer ? Symbols.task_alt : Symbols.prompt_suggestion,
|
||||
size: 20),
|
||||
Icon(_isAnswer ? Symbols.task_alt : Symbols.prompt_suggestion, size: 20),
|
||||
const Gap(10),
|
||||
Text(
|
||||
_isAnswer
|
||||
? 'postQuestionAnswerTitle'
|
||||
: 'postFeaturedComment',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(fontSize: 15),
|
||||
_isAnswer ? 'postQuestionAnswerTitle' : 'postFeaturedComment',
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(fontSize: 15),
|
||||
).tr(),
|
||||
],
|
||||
),
|
||||
@ -1610,8 +1550,7 @@ class _PostGetInsightPopupState extends State<_PostGetInsightPopup> {
|
||||
}
|
||||
|
||||
RegExp cleanThinkingRegExp = RegExp(r'<think>[\s\S]*?</think>');
|
||||
setState(
|
||||
() => _response = out.replaceAll(cleanThinkingRegExp, '').trim());
|
||||
setState(() => _response = out.replaceAll(cleanThinkingRegExp, '').trim());
|
||||
} catch (err) {
|
||||
if (!mounted) return;
|
||||
context.showErrorDialog(err);
|
||||
@ -1634,16 +1573,11 @@ class _PostGetInsightPopupState extends State<_PostGetInsightPopup> {
|
||||
children: [
|
||||
const Icon(Symbols.book_4_spark, size: 24),
|
||||
const Gap(16),
|
||||
Text('postGetInsightTitle',
|
||||
style: Theme.of(context).textTheme.titleLarge)
|
||||
.tr(),
|
||||
Text('postGetInsightTitle', style: Theme.of(context).textTheme.titleLarge).tr(),
|
||||
],
|
||||
).padding(horizontal: 20, top: 16, bottom: 12),
|
||||
const Gap(4),
|
||||
Text('postGetInsightDescription',
|
||||
style: Theme.of(context).textTheme.bodySmall)
|
||||
.tr()
|
||||
.padding(horizontal: 20),
|
||||
Text('postGetInsightDescription', style: Theme.of(context).textTheme.bodySmall).tr().padding(horizontal: 20),
|
||||
const Gap(4),
|
||||
if (_response == null)
|
||||
Expanded(
|
||||
@ -1661,16 +1595,12 @@ class _PostGetInsightPopupState extends State<_PostGetInsightPopup> {
|
||||
leading: const Icon(Symbols.info),
|
||||
title: Text('aiThinkingProcess'.tr()),
|
||||
tilePadding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
collapsedBackgroundColor:
|
||||
Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
collapsedBackgroundColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
minTileHeight: 32,
|
||||
children: [
|
||||
SelectableText(
|
||||
_thinkingProcess!,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(fontStyle: FontStyle.italic),
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontStyle: FontStyle.italic),
|
||||
).padding(horizontal: 20, vertical: 8),
|
||||
],
|
||||
).padding(vertical: 8),
|
||||
@ -1707,8 +1637,7 @@ class _PostVideoPlayer extends StatelessWidget {
|
||||
aspectRatio: 16 / 9,
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: AttachmentItem(
|
||||
data: data.preload!.video!, heroTag: 'post-video-${data.id}'),
|
||||
child: AttachmentItem(data: data.preload!.video!, heroTag: 'post-video-${data.id}'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
Reference in New Issue
Block a user