diff --git a/lib/models/user.dart b/lib/models/user.dart index 2d1e25e..1b0b1f2 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -25,6 +25,15 @@ sealed class SnAccount with _$SnAccount { _$SnAccountFromJson(json); } +@freezed +sealed class ProfileLink with _$ProfileLink { + const factory ProfileLink({required String name, required String url}) = + _ProfileLink; + + factory ProfileLink.fromJson(Map json) => + _$ProfileLinkFromJson(json); +} + @freezed sealed class SnAccountProfile with _$SnAccountProfile { const factory SnAccountProfile({ @@ -38,7 +47,7 @@ sealed class SnAccountProfile with _$SnAccountProfile { @Default('') String location, @Default('') String timeZone, DateTime? birthday, - @Default({}) Map links, + @Default([]) List links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, required int experience, diff --git a/lib/models/user.freezed.dart b/lib/models/user.freezed.dart index 89dafbb..4e21529 100644 --- a/lib/models/user.freezed.dart +++ b/lib/models/user.freezed.dart @@ -347,10 +347,270 @@ $SnWalletSubscriptionRefCopyWith<$Res>? get perkSubscription { } +/// @nodoc +mixin _$ProfileLink { + + String get name; String get url; +/// Create a copy of ProfileLink +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ProfileLinkCopyWith get copyWith => _$ProfileLinkCopyWithImpl(this as ProfileLink, _$identity); + + /// Serializes this ProfileLink to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ProfileLink&&(identical(other.name, name) || other.name == name)&&(identical(other.url, url) || other.url == url)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,name,url); + +@override +String toString() { + return 'ProfileLink(name: $name, url: $url)'; +} + + +} + +/// @nodoc +abstract mixin class $ProfileLinkCopyWith<$Res> { + factory $ProfileLinkCopyWith(ProfileLink value, $Res Function(ProfileLink) _then) = _$ProfileLinkCopyWithImpl; +@useResult +$Res call({ + String name, String url +}); + + + + +} +/// @nodoc +class _$ProfileLinkCopyWithImpl<$Res> + implements $ProfileLinkCopyWith<$Res> { + _$ProfileLinkCopyWithImpl(this._self, this._then); + + final ProfileLink _self; + final $Res Function(ProfileLink) _then; + +/// Create a copy of ProfileLink +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? url = null,}) { + return _then(_self.copyWith( +name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable +as String, + )); +} + +} + + +/// Adds pattern-matching-related methods to [ProfileLink]. +extension ProfileLinkPatterns on ProfileLink { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _ProfileLink value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ProfileLink() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _ProfileLink value) $default,){ +final _that = this; +switch (_that) { +case _ProfileLink(): +return $default(_that);} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ProfileLink value)? $default,){ +final _that = this; +switch (_that) { +case _ProfileLink() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String name, String url)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ProfileLink() when $default != null: +return $default(_that.name,_that.url);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String name, String url) $default,) {final _that = this; +switch (_that) { +case _ProfileLink(): +return $default(_that.name,_that.url);} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String name, String url)? $default,) {final _that = this; +switch (_that) { +case _ProfileLink() when $default != null: +return $default(_that.name,_that.url);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _ProfileLink implements ProfileLink { + const _ProfileLink({required this.name, required this.url}); + factory _ProfileLink.fromJson(Map json) => _$ProfileLinkFromJson(json); + +@override final String name; +@override final String url; + +/// Create a copy of ProfileLink +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ProfileLinkCopyWith<_ProfileLink> get copyWith => __$ProfileLinkCopyWithImpl<_ProfileLink>(this, _$identity); + +@override +Map toJson() { + return _$ProfileLinkToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProfileLink&&(identical(other.name, name) || other.name == name)&&(identical(other.url, url) || other.url == url)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,name,url); + +@override +String toString() { + return 'ProfileLink(name: $name, url: $url)'; +} + + +} + +/// @nodoc +abstract mixin class _$ProfileLinkCopyWith<$Res> implements $ProfileLinkCopyWith<$Res> { + factory _$ProfileLinkCopyWith(_ProfileLink value, $Res Function(_ProfileLink) _then) = __$ProfileLinkCopyWithImpl; +@override @useResult +$Res call({ + String name, String url +}); + + + + +} +/// @nodoc +class __$ProfileLinkCopyWithImpl<$Res> + implements _$ProfileLinkCopyWith<$Res> { + __$ProfileLinkCopyWithImpl(this._self, this._then); + + final _ProfileLink _self; + final $Res Function(_ProfileLink) _then; + +/// Create a copy of ProfileLink +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? url = null,}) { + return _then(_ProfileLink( +name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + + /// @nodoc mixin _$SnAccountProfile { - String get id; String get firstName; String get middleName; String get lastName; String get bio; String get gender; String get pronouns; String get location; String get timeZone; DateTime? get birthday; Map get links; DateTime? get lastSeenAt; SnAccountBadge? get activeBadge; int get experience; int get level; double get levelingProgress; SnCloudFile? get picture; SnCloudFile? get background; SnVerificationMark? get verification; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; + String get id; String get firstName; String get middleName; String get lastName; String get bio; String get gender; String get pronouns; String get location; String get timeZone; DateTime? get birthday; List get links; DateTime? get lastSeenAt; SnAccountBadge? get activeBadge; int get experience; int get level; double get levelingProgress; SnCloudFile? get picture; SnCloudFile? get background; SnVerificationMark? get verification; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; /// Create a copy of SnAccountProfile /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -383,7 +643,7 @@ abstract mixin class $SnAccountProfileCopyWith<$Res> { factory $SnAccountProfileCopyWith(SnAccountProfile value, $Res Function(SnAccountProfile) _then) = _$SnAccountProfileCopyWithImpl; @useResult $Res call({ - String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, Map links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt + String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, List links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt }); @@ -413,7 +673,7 @@ as String,location: null == location ? _self.location : location // ignore: cast as String,timeZone: null == timeZone ? _self.timeZone : timeZone // ignore: cast_nullable_to_non_nullable as String,birthday: freezed == birthday ? _self.birthday : birthday // ignore: cast_nullable_to_non_nullable as DateTime?,links: null == links ? _self.links : links // ignore: cast_nullable_to_non_nullable -as Map,lastSeenAt: freezed == lastSeenAt ? _self.lastSeenAt : lastSeenAt // ignore: cast_nullable_to_non_nullable +as List,lastSeenAt: freezed == lastSeenAt ? _self.lastSeenAt : lastSeenAt // ignore: cast_nullable_to_non_nullable as DateTime?,activeBadge: freezed == activeBadge ? _self.activeBadge : activeBadge // ignore: cast_nullable_to_non_nullable as SnAccountBadge?,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable @@ -554,7 +814,7 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, Map links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, List links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _SnAccountProfile() when $default != null: return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.createdAt,_that.updatedAt,_that.deletedAt);case _: @@ -575,7 +835,7 @@ return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.b /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, Map links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, List links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this; switch (_that) { case _SnAccountProfile(): return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.createdAt,_that.updatedAt,_that.deletedAt);} @@ -592,7 +852,7 @@ return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.b /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, Map links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, List links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this; switch (_that) { case _SnAccountProfile() when $default != null: return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.createdAt,_that.updatedAt,_that.deletedAt);case _: @@ -607,7 +867,7 @@ return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.b @JsonSerializable() class _SnAccountProfile implements SnAccountProfile { - const _SnAccountProfile({required this.id, this.firstName = '', this.middleName = '', this.lastName = '', this.bio = '', this.gender = '', this.pronouns = '', this.location = '', this.timeZone = '', this.birthday, final Map links = const {}, this.lastSeenAt, this.activeBadge, required this.experience, required this.level, required this.levelingProgress, required this.picture, required this.background, required this.verification, required this.createdAt, required this.updatedAt, required this.deletedAt}): _links = links; + const _SnAccountProfile({required this.id, this.firstName = '', this.middleName = '', this.lastName = '', this.bio = '', this.gender = '', this.pronouns = '', this.location = '', this.timeZone = '', this.birthday, final List links = const [], this.lastSeenAt, this.activeBadge, required this.experience, required this.level, required this.levelingProgress, required this.picture, required this.background, required this.verification, required this.createdAt, required this.updatedAt, required this.deletedAt}): _links = links; factory _SnAccountProfile.fromJson(Map json) => _$SnAccountProfileFromJson(json); @override final String id; @@ -620,11 +880,11 @@ class _SnAccountProfile implements SnAccountProfile { @override@JsonKey() final String location; @override@JsonKey() final String timeZone; @override final DateTime? birthday; - final Map _links; -@override@JsonKey() Map get links { - if (_links is EqualUnmodifiableMapView) return _links; + final List _links; +@override@JsonKey() List get links { + if (_links is EqualUnmodifiableListView) return _links; // ignore: implicit_dynamic_type - return EqualUnmodifiableMapView(_links); + return EqualUnmodifiableListView(_links); } @override final DateTime? lastSeenAt; @@ -672,7 +932,7 @@ abstract mixin class _$SnAccountProfileCopyWith<$Res> implements $SnAccountProfi factory _$SnAccountProfileCopyWith(_SnAccountProfile value, $Res Function(_SnAccountProfile) _then) = __$SnAccountProfileCopyWithImpl; @override @useResult $Res call({ - String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, Map links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt + String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, List links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt }); @@ -702,7 +962,7 @@ as String,location: null == location ? _self.location : location // ignore: cast as String,timeZone: null == timeZone ? _self.timeZone : timeZone // ignore: cast_nullable_to_non_nullable as String,birthday: freezed == birthday ? _self.birthday : birthday // ignore: cast_nullable_to_non_nullable as DateTime?,links: null == links ? _self._links : links // ignore: cast_nullable_to_non_nullable -as Map,lastSeenAt: freezed == lastSeenAt ? _self.lastSeenAt : lastSeenAt // ignore: cast_nullable_to_non_nullable +as List,lastSeenAt: freezed == lastSeenAt ? _self.lastSeenAt : lastSeenAt // ignore: cast_nullable_to_non_nullable as DateTime?,activeBadge: freezed == activeBadge ? _self.activeBadge : activeBadge // ignore: cast_nullable_to_non_nullable as SnAccountBadge?,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable diff --git a/lib/models/user.g.dart b/lib/models/user.g.dart index 7b3416e..2967516 100644 --- a/lib/models/user.g.dart +++ b/lib/models/user.g.dart @@ -47,6 +47,12 @@ Map _$SnAccountToJson(_SnAccount instance) => 'deleted_at': instance.deletedAt?.toIso8601String(), }; +_ProfileLink _$ProfileLinkFromJson(Map json) => + _ProfileLink(name: json['name'] as String, url: json['url'] as String); + +Map _$ProfileLinkToJson(_ProfileLink instance) => + {'name': instance.name, 'url': instance.url}; + _SnAccountProfile _$SnAccountProfileFromJson(Map json) => _SnAccountProfile( id: json['id'] as String, @@ -63,10 +69,10 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map json) => ? null : DateTime.parse(json['birthday'] as String), links: - (json['links'] as Map?)?.map( - (k, e) => MapEntry(k, e as String), - ) ?? - const {}, + (json['links'] as List?) + ?.map((e) => ProfileLink.fromJson(e as Map)) + .toList() ?? + const [], lastSeenAt: json['last_seen_at'] == null ? null @@ -116,7 +122,7 @@ Map _$SnAccountProfileToJson(_SnAccountProfile instance) => 'location': instance.location, 'time_zone': instance.timeZone, 'birthday': instance.birthday?.toIso8601String(), - 'links': instance.links, + 'links': instance.links.map((e) => e.toJson()).toList(), 'last_seen_at': instance.lastSeenAt?.toIso8601String(), 'active_badge': instance.activeBadge?.toJson(), 'experience': instance.experience, diff --git a/lib/screens/account/me/update.dart b/lib/screens/account/me/update.dart index 0b48849..5b00f78 100644 --- a/lib/screens/account/me/update.dart +++ b/lib/screens/account/me/update.dart @@ -7,6 +7,7 @@ import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:image_picker/image_picker.dart'; import 'package:island/models/file.dart'; +import 'package:island/models/user.dart'; import 'package:island/pods/config.dart'; import 'package:island/pods/network.dart'; import 'package:island/pods/userinfo.dart'; @@ -95,11 +96,7 @@ class UpdateProfileScreen extends HookConsumerWidget { final usernameController = useTextEditingController(text: user.value!.name); final nicknameController = useTextEditingController(text: user.value!.nick); final language = useState(user.value!.language); - final links = useState>>( - user.value!.profile.links.entries - .map((e) => {'key': e.key, 'value': e.value}) - .toList(), - ); + final links = useState>(user.value!.profile.links); void updateBasicInfo() async { if (!formKeyBasicInfo.currentState!.validate()) return; @@ -171,7 +168,7 @@ class UpdateProfileScreen extends HookConsumerWidget { 'location': locationController.text, 'time_zone': timeZoneController.text, 'birthday': birthday.value?.toUtc().toIso8601String(), - 'links': {for (var e in links.value) e['key']!: e['value']!}, + 'links': links.value, }, ); final userNotifier = ref.read(userInfoProvider.notifier); @@ -575,13 +572,15 @@ class UpdateProfileScreen extends HookConsumerWidget { children: [ Expanded( child: TextFormField( - initialValue: links.value[i]['key'], + initialValue: links.value[i].name, decoration: InputDecoration( labelText: 'linkKey'.tr(), isDense: true, ), onChanged: (value) { - links.value[i]['key'] = value; + links.value[i] = links.value[i].copyWith( + name: value, + ); }, onTapOutside: (_) => @@ -592,13 +591,15 @@ class UpdateProfileScreen extends HookConsumerWidget { const Gap(8), Expanded( child: TextFormField( - initialValue: links.value[i]['value'], + initialValue: links.value[i].url, decoration: InputDecoration( labelText: 'linkValue'.tr(), isDense: true, ), onChanged: (value) { - links.value[i]['value'] = value; + links.value[i] = links.value[i].copyWith( + url: value, + ); }, onTapOutside: (_) => @@ -620,7 +621,7 @@ class UpdateProfileScreen extends HookConsumerWidget { child: FilledButton.icon( onPressed: () { links.value = List.from(links.value) - ..add({'key': '', 'value': ''}); + ..add(ProfileLink(name: '', url: '')); }, label: Text('addLink').tr(), icon: const Icon(Symbols.add), diff --git a/lib/screens/account/profile.dart b/lib/screens/account/profile.dart index e3a1705..280c8e3 100644 --- a/lib/screens/account/profile.dart +++ b/lib/screens/account/profile.dart @@ -357,17 +357,17 @@ class AccountProfileScreen extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('links').tr().bold().padding(horizontal: 24, top: 12, bottom: 4), - for (final link in data.profile.links.entries) + for (final link in data.profile.links) ListTile( - title: Text(link.key.capitalizeEachWord()), - subtitle: Text(link.value), + title: Text(link.name.capitalizeEachWord()), + subtitle: Text(link.url), contentPadding: EdgeInsets.symmetric(horizontal: 24), trailing: const Icon(Symbols.chevron_right), shape: RoundedRectangleBorder( borderRadius: const BorderRadius.all(Radius.circular(8)), ), onTap: () { - launchUrlString(link.value); + launchUrlString(link.url); }, ), ], diff --git a/lib/screens/creators/stickers/pack_detail.g.dart b/lib/screens/creators/stickers/pack_detail.g.dart index f4bdd66..08dae19 100644 --- a/lib/screens/creators/stickers/pack_detail.g.dart +++ b/lib/screens/creators/stickers/pack_detail.g.dart @@ -151,7 +151,7 @@ class _StickerPackContentProviderElement } String _$stickerPackStickerHash() => - r'36f524c047e632236d5597aaaa8678ed86599602'; + r'5c553666b3a63530bdebae4b7cd52f303c5ab3a0'; /// See also [stickerPackSticker]. @ProviderFor(stickerPackSticker)