Compare commits
No commits in common. "d5cf2478d8051fb93c006cba5c392f4aaf7207b3" and "a75083d916dd246ccc691142bb2408d66cf9ad1b" have entirely different histories.
d5cf2478d8
...
a75083d916
@ -249,11 +249,8 @@ class SnNetworkProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAttachmentUrl(String ky, {bool preview = true}) {
|
String getAttachmentUrl(String ky) {
|
||||||
if (ky.startsWith("http")) return ky;
|
if (ky.startsWith("http")) return ky;
|
||||||
if (!preview) {
|
|
||||||
return '${client.options.baseUrl}/cgi/uc/attachments/$ky?preview=false';
|
|
||||||
}
|
|
||||||
return '${client.options.baseUrl}/cgi/uc/attachments/$ky';
|
return '${client.options.baseUrl}/cgi/uc/attachments/$ky';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import 'package:surface/providers/experience.dart';
|
|||||||
import 'package:surface/providers/relationship.dart';
|
import 'package:surface/providers/relationship.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/screens/abuse_report.dart';
|
import 'package:surface/screens/abuse_report.dart';
|
||||||
import 'package:surface/screens/account/punishments.dart';
|
|
||||||
import 'package:surface/types/account.dart';
|
import 'package:surface/types/account.dart';
|
||||||
import 'package:surface/types/check_in.dart';
|
import 'package:surface/types/check_in.dart';
|
||||||
import 'package:surface/types/post.dart';
|
import 'package:surface/types/post.dart';
|
||||||
@ -458,7 +457,7 @@ class _UserScreenState extends State<UserScreen>
|
|||||||
],
|
],
|
||||||
).padding(right: 8),
|
).padding(right: 8),
|
||||||
if (_account!.profile!.description.isNotEmpty)
|
if (_account!.profile!.description.isNotEmpty)
|
||||||
const Gap(4)
|
const Gap(12)
|
||||||
else
|
else
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
if (_account!.profile!.description.isNotEmpty)
|
if (_account!.profile!.description.isNotEmpty)
|
||||||
@ -504,8 +503,7 @@ class _UserScreenState extends State<UserScreen>
|
|||||||
],
|
],
|
||||||
).padding(vertical: 8, horizontal: 12),
|
).padding(vertical: 8, horizontal: 12),
|
||||||
),
|
),
|
||||||
if (_account!.badges.isNotEmpty) const Gap(8),
|
const Gap(8),
|
||||||
if (_account!.badges.isNotEmpty)
|
|
||||||
Wrap(
|
Wrap(
|
||||||
spacing: 4,
|
spacing: 4,
|
||||||
runSpacing: 4,
|
runSpacing: 4,
|
||||||
@ -621,17 +619,6 @@ class _UserScreenState extends State<UserScreen>
|
|||||||
],
|
],
|
||||||
).padding(all: 16),
|
).padding(all: 16),
|
||||||
),
|
),
|
||||||
if (_account?.punishments.isNotEmpty ?? false)
|
|
||||||
SliverToBoxAdapter(child: const Divider()),
|
|
||||||
if (_account?.punishments.isNotEmpty ?? false)
|
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
for (final ele in _account!.punishments)
|
|
||||||
PunishmentInfoCard(ele: ele),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (_account?.profile?.links.isNotEmpty ?? false)
|
if (_account?.profile?.links.isNotEmpty ?? false)
|
||||||
SliverToBoxAdapter(child: const Divider()),
|
SliverToBoxAdapter(child: const Divider()),
|
||||||
if (_account?.profile?.links.isNotEmpty ?? false)
|
if (_account?.profile?.links.isNotEmpty ?? false)
|
||||||
|
@ -107,28 +107,6 @@ class _PunishmentsScreenState extends State<PunishmentsScreen> {
|
|||||||
itemCount: _punishments?.length ?? 0,
|
itemCount: _punishments?.length ?? 0,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final ele = _punishments![index];
|
final ele = _punishments![index];
|
||||||
return PunishmentInfoCard(ele: ele);
|
|
||||||
},
|
|
||||||
separatorBuilder: (_, __) => const Gap(8),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PunishmentInfoCard extends StatelessWidget {
|
|
||||||
const PunishmentInfoCard({
|
|
||||||
super.key,
|
|
||||||
required this.ele,
|
|
||||||
});
|
|
||||||
|
|
||||||
final SnPunishment ele;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Card(
|
return Card(
|
||||||
margin: EdgeInsets.symmetric(horizontal: 8),
|
margin: EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -139,8 +117,10 @@ class PunishmentInfoCard extends StatelessWidget {
|
|||||||
Icon(kPunishmentIcons[ele.type], size: 20),
|
Icon(kPunishmentIcons[ele.type], size: 20),
|
||||||
const Gap(6),
|
const Gap(6),
|
||||||
Expanded(
|
Expanded(
|
||||||
child:
|
child: Text('punishmentType${ele.type}')
|
||||||
Text('punishmentType${ele.type}').tr().fontSize(16).bold(),
|
.tr()
|
||||||
|
.fontSize(16)
|
||||||
|
.bold(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -195,5 +175,13 @@ class PunishmentInfoCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
).padding(horizontal: 24, vertical: 16),
|
).padding(horizontal: 24, vertical: 16),
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (_, __) => const Gap(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ abstract class SnAccount with _$SnAccount {
|
|||||||
required String language,
|
required String language,
|
||||||
required SnAccountProfile? profile,
|
required SnAccountProfile? profile,
|
||||||
@Default([]) List<SnAccountBadge> badges,
|
@Default([]) List<SnAccountBadge> badges,
|
||||||
@Default([]) List<SnPunishment> punishments,
|
|
||||||
required DateTime? suspendedAt,
|
required DateTime? suspendedAt,
|
||||||
required int? affiliatedId,
|
required int? affiliatedId,
|
||||||
required int? affiliatedTo,
|
required int? affiliatedTo,
|
||||||
|
@ -29,7 +29,6 @@ mixin _$SnAccount {
|
|||||||
String get language;
|
String get language;
|
||||||
SnAccountProfile? get profile;
|
SnAccountProfile? get profile;
|
||||||
List<SnAccountBadge> get badges;
|
List<SnAccountBadge> get badges;
|
||||||
List<SnPunishment> get punishments;
|
|
||||||
DateTime? get suspendedAt;
|
DateTime? get suspendedAt;
|
||||||
int? get affiliatedId;
|
int? get affiliatedId;
|
||||||
int? get affiliatedTo;
|
int? get affiliatedTo;
|
||||||
@ -70,8 +69,6 @@ mixin _$SnAccount {
|
|||||||
other.language == language) &&
|
other.language == language) &&
|
||||||
(identical(other.profile, profile) || other.profile == profile) &&
|
(identical(other.profile, profile) || other.profile == profile) &&
|
||||||
const DeepCollectionEquality().equals(other.badges, badges) &&
|
const DeepCollectionEquality().equals(other.badges, badges) &&
|
||||||
const DeepCollectionEquality()
|
|
||||||
.equals(other.punishments, punishments) &&
|
|
||||||
(identical(other.suspendedAt, suspendedAt) ||
|
(identical(other.suspendedAt, suspendedAt) ||
|
||||||
other.suspendedAt == suspendedAt) &&
|
other.suspendedAt == suspendedAt) &&
|
||||||
(identical(other.affiliatedId, affiliatedId) ||
|
(identical(other.affiliatedId, affiliatedId) ||
|
||||||
@ -102,7 +99,6 @@ mixin _$SnAccount {
|
|||||||
language,
|
language,
|
||||||
profile,
|
profile,
|
||||||
const DeepCollectionEquality().hash(badges),
|
const DeepCollectionEquality().hash(badges),
|
||||||
const DeepCollectionEquality().hash(punishments),
|
|
||||||
suspendedAt,
|
suspendedAt,
|
||||||
affiliatedId,
|
affiliatedId,
|
||||||
affiliatedTo,
|
affiliatedTo,
|
||||||
@ -112,7 +108,7 @@ mixin _$SnAccount {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
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, punishments: $punishments, 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)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +132,6 @@ abstract mixin class $SnAccountCopyWith<$Res> {
|
|||||||
String language,
|
String language,
|
||||||
SnAccountProfile? profile,
|
SnAccountProfile? profile,
|
||||||
List<SnAccountBadge> badges,
|
List<SnAccountBadge> badges,
|
||||||
List<SnPunishment> punishments,
|
|
||||||
DateTime? suspendedAt,
|
DateTime? suspendedAt,
|
||||||
int? affiliatedId,
|
int? affiliatedId,
|
||||||
int? affiliatedTo,
|
int? affiliatedTo,
|
||||||
@ -172,7 +167,6 @@ class _$SnAccountCopyWithImpl<$Res> implements $SnAccountCopyWith<$Res> {
|
|||||||
Object? language = null,
|
Object? language = null,
|
||||||
Object? profile = freezed,
|
Object? profile = freezed,
|
||||||
Object? badges = null,
|
Object? badges = null,
|
||||||
Object? punishments = null,
|
|
||||||
Object? suspendedAt = freezed,
|
Object? suspendedAt = freezed,
|
||||||
Object? affiliatedId = freezed,
|
Object? affiliatedId = freezed,
|
||||||
Object? affiliatedTo = freezed,
|
Object? affiliatedTo = freezed,
|
||||||
@ -236,10 +230,6 @@ class _$SnAccountCopyWithImpl<$Res> implements $SnAccountCopyWith<$Res> {
|
|||||||
? _self.badges
|
? _self.badges
|
||||||
: badges // ignore: cast_nullable_to_non_nullable
|
: badges // ignore: cast_nullable_to_non_nullable
|
||||||
as List<SnAccountBadge>,
|
as List<SnAccountBadge>,
|
||||||
punishments: null == punishments
|
|
||||||
? _self.punishments
|
|
||||||
: punishments // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<SnPunishment>,
|
|
||||||
suspendedAt: freezed == suspendedAt
|
suspendedAt: freezed == suspendedAt
|
||||||
? _self.suspendedAt
|
? _self.suspendedAt
|
||||||
: suspendedAt // ignore: cast_nullable_to_non_nullable
|
: suspendedAt // ignore: cast_nullable_to_non_nullable
|
||||||
@ -296,7 +286,6 @@ class _SnAccount extends SnAccount {
|
|||||||
required this.language,
|
required this.language,
|
||||||
required this.profile,
|
required this.profile,
|
||||||
final List<SnAccountBadge> badges = const [],
|
final List<SnAccountBadge> badges = const [],
|
||||||
final List<SnPunishment> punishments = const [],
|
|
||||||
required this.suspendedAt,
|
required this.suspendedAt,
|
||||||
required this.affiliatedId,
|
required this.affiliatedId,
|
||||||
required this.affiliatedTo,
|
required this.affiliatedTo,
|
||||||
@ -305,7 +294,6 @@ class _SnAccount extends SnAccount {
|
|||||||
: _contacts = contacts,
|
: _contacts = contacts,
|
||||||
_permNodes = permNodes,
|
_permNodes = permNodes,
|
||||||
_badges = badges,
|
_badges = badges,
|
||||||
_punishments = punishments,
|
|
||||||
super._();
|
super._();
|
||||||
factory _SnAccount.fromJson(Map<String, dynamic> json) =>
|
factory _SnAccount.fromJson(Map<String, dynamic> json) =>
|
||||||
_$SnAccountFromJson(json);
|
_$SnAccountFromJson(json);
|
||||||
@ -362,15 +350,6 @@ class _SnAccount extends SnAccount {
|
|||||||
return EqualUnmodifiableListView(_badges);
|
return EqualUnmodifiableListView(_badges);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<SnPunishment> _punishments;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
List<SnPunishment> get punishments {
|
|
||||||
if (_punishments is EqualUnmodifiableListView) return _punishments;
|
|
||||||
// ignore: implicit_dynamic_type
|
|
||||||
return EqualUnmodifiableListView(_punishments);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final DateTime? suspendedAt;
|
final DateTime? suspendedAt;
|
||||||
@override
|
@override
|
||||||
@ -422,8 +401,6 @@ class _SnAccount extends SnAccount {
|
|||||||
other.language == language) &&
|
other.language == language) &&
|
||||||
(identical(other.profile, profile) || other.profile == profile) &&
|
(identical(other.profile, profile) || other.profile == profile) &&
|
||||||
const DeepCollectionEquality().equals(other._badges, _badges) &&
|
const DeepCollectionEquality().equals(other._badges, _badges) &&
|
||||||
const DeepCollectionEquality()
|
|
||||||
.equals(other._punishments, _punishments) &&
|
|
||||||
(identical(other.suspendedAt, suspendedAt) ||
|
(identical(other.suspendedAt, suspendedAt) ||
|
||||||
other.suspendedAt == suspendedAt) &&
|
other.suspendedAt == suspendedAt) &&
|
||||||
(identical(other.affiliatedId, affiliatedId) ||
|
(identical(other.affiliatedId, affiliatedId) ||
|
||||||
@ -454,7 +431,6 @@ class _SnAccount extends SnAccount {
|
|||||||
language,
|
language,
|
||||||
profile,
|
profile,
|
||||||
const DeepCollectionEquality().hash(_badges),
|
const DeepCollectionEquality().hash(_badges),
|
||||||
const DeepCollectionEquality().hash(_punishments),
|
|
||||||
suspendedAt,
|
suspendedAt,
|
||||||
affiliatedId,
|
affiliatedId,
|
||||||
affiliatedTo,
|
affiliatedTo,
|
||||||
@ -464,7 +440,7 @@ class _SnAccount extends SnAccount {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
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, punishments: $punishments, 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)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,7 +467,6 @@ abstract mixin class _$SnAccountCopyWith<$Res>
|
|||||||
String language,
|
String language,
|
||||||
SnAccountProfile? profile,
|
SnAccountProfile? profile,
|
||||||
List<SnAccountBadge> badges,
|
List<SnAccountBadge> badges,
|
||||||
List<SnPunishment> punishments,
|
|
||||||
DateTime? suspendedAt,
|
DateTime? suspendedAt,
|
||||||
int? affiliatedId,
|
int? affiliatedId,
|
||||||
int? affiliatedTo,
|
int? affiliatedTo,
|
||||||
@ -528,7 +503,6 @@ class __$SnAccountCopyWithImpl<$Res> implements _$SnAccountCopyWith<$Res> {
|
|||||||
Object? language = null,
|
Object? language = null,
|
||||||
Object? profile = freezed,
|
Object? profile = freezed,
|
||||||
Object? badges = null,
|
Object? badges = null,
|
||||||
Object? punishments = null,
|
|
||||||
Object? suspendedAt = freezed,
|
Object? suspendedAt = freezed,
|
||||||
Object? affiliatedId = freezed,
|
Object? affiliatedId = freezed,
|
||||||
Object? affiliatedTo = freezed,
|
Object? affiliatedTo = freezed,
|
||||||
@ -592,10 +566,6 @@ class __$SnAccountCopyWithImpl<$Res> implements _$SnAccountCopyWith<$Res> {
|
|||||||
? _self._badges
|
? _self._badges
|
||||||
: badges // ignore: cast_nullable_to_non_nullable
|
: badges // ignore: cast_nullable_to_non_nullable
|
||||||
as List<SnAccountBadge>,
|
as List<SnAccountBadge>,
|
||||||
punishments: null == punishments
|
|
||||||
? _self._punishments
|
|
||||||
: punishments // ignore: cast_nullable_to_non_nullable
|
|
||||||
as List<SnPunishment>,
|
|
||||||
suspendedAt: freezed == suspendedAt
|
suspendedAt: freezed == suspendedAt
|
||||||
? _self.suspendedAt
|
? _self.suspendedAt
|
||||||
: suspendedAt // ignore: cast_nullable_to_non_nullable
|
: suspendedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -32,10 +32,6 @@ _SnAccount _$SnAccountFromJson(Map<String, dynamic> json) => _SnAccount(
|
|||||||
?.map((e) => SnAccountBadge.fromJson(e as Map<String, dynamic>))
|
?.map((e) => SnAccountBadge.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const [],
|
const [],
|
||||||
punishments: (json['punishments'] as List<dynamic>?)
|
|
||||||
?.map((e) => SnPunishment.fromJson(e as Map<String, dynamic>))
|
|
||||||
.toList() ??
|
|
||||||
const [],
|
|
||||||
suspendedAt: json['suspended_at'] == null
|
suspendedAt: json['suspended_at'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['suspended_at'] as String),
|
: DateTime.parse(json['suspended_at'] as String),
|
||||||
@ -61,7 +57,6 @@ Map<String, dynamic> _$SnAccountToJson(_SnAccount instance) =>
|
|||||||
'language': instance.language,
|
'language': instance.language,
|
||||||
'profile': instance.profile?.toJson(),
|
'profile': instance.profile?.toJson(),
|
||||||
'badges': instance.badges.map((e) => e.toJson()).toList(),
|
'badges': instance.badges.map((e) => e.toJson()).toList(),
|
||||||
'punishments': instance.punishments.map((e) => e.toJson()).toList(),
|
|
||||||
'suspended_at': instance.suspendedAt?.toIso8601String(),
|
'suspended_at': instance.suspendedAt?.toIso8601String(),
|
||||||
'affiliated_id': instance.affiliatedId,
|
'affiliated_id': instance.affiliatedId,
|
||||||
'affiliated_to': instance.affiliatedTo,
|
'affiliated_to': instance.affiliatedTo,
|
||||||
|
@ -22,14 +22,12 @@ class AccountPopoverCard extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return Column(
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (data.banner.isNotEmpty)
|
if (data.banner.isNotEmpty)
|
||||||
ClipRRect(
|
Container(
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
child: Container(
|
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 7,
|
aspectRatio: 16 / 7,
|
||||||
@ -39,10 +37,8 @@ class AccountPopoverCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
).padding(all: 16)
|
|
||||||
else
|
|
||||||
const Gap(16),
|
|
||||||
// Top padding
|
// Top padding
|
||||||
|
Gap(16),
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -71,8 +67,7 @@ class AccountPopoverCard extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
icon: const Icon(Symbols.chevron_right),
|
icon: const Icon(Symbols.chevron_right),
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
visualDensity:
|
visualDensity: const VisualDensity(horizontal: -4, vertical: -4),
|
||||||
const VisualDensity(horizontal: -4, vertical: -4),
|
|
||||||
),
|
),
|
||||||
const Gap(8)
|
const Gap(8)
|
||||||
],
|
],
|
||||||
@ -91,9 +86,7 @@ class AccountPopoverCard extends StatelessWidget {
|
|||||||
data.profile?.description ?? '',
|
data.profile?.description ?? '',
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
).padding(horizontal: 26, bottom: 8)
|
).padding(horizontal: 26, bottom: 8),
|
||||||
else
|
|
||||||
const Gap(12),
|
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -111,8 +104,7 @@ class AccountPopoverCard extends StatelessWidget {
|
|||||||
child: LinearProgressIndicator(
|
child: LinearProgressIndicator(
|
||||||
value: calcLevelUpProgress(data.profile?.experience ?? 0),
|
value: calcLevelUpProgress(data.profile?.experience ?? 0),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
backgroundColor:
|
backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
Theme.of(context).colorScheme.surfaceContainer,
|
|
||||||
).alignment(Alignment.centerLeft),
|
).alignment(Alignment.centerLeft),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -164,9 +156,8 @@ class AccountPopoverCard extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
// Bottom padding
|
// Bottom padding
|
||||||
const Gap(64),
|
const Gap(16),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,8 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: widget.data
|
children: widget.data
|
||||||
.mapIndexed(
|
.mapIndexed(
|
||||||
(idx, ele) => AspectRatio(
|
(idx, ele) => GestureDetector(
|
||||||
|
child: AspectRatio(
|
||||||
aspectRatio: ele?.data['ratio']?.toDouble() ?? 1,
|
aspectRatio: ele?.data['ratio']?.toDouble() ?? 1,
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: constraints,
|
constraints: constraints,
|
||||||
@ -179,21 +180,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
heroTag: heroTags[idx],
|
heroTag: heroTags[idx],
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
filterQuality: widget.filterQuality,
|
filterQuality: widget.filterQuality,
|
||||||
onZoom: () {
|
|
||||||
context.pushTransparentRoute(
|
|
||||||
AttachmentZoomView(
|
|
||||||
data: widget.data
|
|
||||||
.where((ele) =>
|
|
||||||
ele != null &&
|
|
||||||
ele.mediaType == SnMediaType.image)
|
|
||||||
.cast(),
|
|
||||||
initialIndex: idx,
|
|
||||||
heroTags: heroTags,
|
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.black.withOpacity(0.7),
|
|
||||||
rootNavigator: true,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -224,6 +211,26 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio:
|
aspectRatio:
|
||||||
(widget.data[idx]?.data['ratio'] ?? 1).toDouble(),
|
(widget.data[idx]?.data['ratio'] ?? 1).toDouble(),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.data[idx]?.mediaType !=
|
||||||
|
SnMediaType.image) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context.pushTransparentRoute(
|
||||||
|
AttachmentZoomView(
|
||||||
|
data: widget.data
|
||||||
|
.where((ele) =>
|
||||||
|
ele != null &&
|
||||||
|
ele.mediaType == SnMediaType.image)
|
||||||
|
.cast(),
|
||||||
|
initialIndex: idx,
|
||||||
|
heroTags: heroTags,
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.black.withOpacity(0.7),
|
||||||
|
rootNavigator: true,
|
||||||
|
);
|
||||||
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
@ -242,23 +249,6 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
data: widget.data[idx],
|
data: widget.data[idx],
|
||||||
heroTag: heroTags[idx],
|
heroTag: heroTags[idx],
|
||||||
filterQuality: widget.filterQuality,
|
filterQuality: widget.filterQuality,
|
||||||
onZoom: () {
|
|
||||||
context.pushTransparentRoute(
|
|
||||||
AttachmentZoomView(
|
|
||||||
data: widget.data
|
|
||||||
.where((ele) =>
|
|
||||||
ele != null &&
|
|
||||||
ele.mediaType ==
|
|
||||||
SnMediaType.image)
|
|
||||||
.cast(),
|
|
||||||
initialIndex: idx,
|
|
||||||
heroTags: heroTags,
|
|
||||||
),
|
|
||||||
backgroundColor:
|
|
||||||
Colors.black.withOpacity(0.7),
|
|
||||||
rootNavigator: true,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -272,6 +262,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (context, index) => const Gap(8),
|
separatorBuilder: (context, index) => const Gap(8),
|
||||||
|
@ -181,10 +181,7 @@ class _AttachmentZoomViewState extends State<AttachmentZoomView> {
|
|||||||
scaleState == PhotoViewScaleState.initial);
|
scaleState == PhotoViewScaleState.initial);
|
||||||
},
|
},
|
||||||
imageProvider: UniversalImage.provider(
|
imageProvider: UniversalImage.provider(
|
||||||
sn.getAttachmentUrl(
|
sn.getAttachmentUrl(widget.data.first.rid),
|
||||||
widget.data.first.rid,
|
|
||||||
preview: false,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -202,10 +199,7 @@ class _AttachmentZoomViewState extends State<AttachmentZoomView> {
|
|||||||
widget.heroTags?.elementAt(idx) ?? uuid.v4();
|
widget.heroTags?.elementAt(idx) ?? uuid.v4();
|
||||||
return PhotoViewGalleryPageOptions(
|
return PhotoViewGalleryPageOptions(
|
||||||
imageProvider: UniversalImage.provider(
|
imageProvider: UniversalImage.provider(
|
||||||
sn.getAttachmentUrl(
|
sn.getAttachmentUrl(widget.data.elementAt(idx).rid),
|
||||||
widget.data.elementAt(idx).rid,
|
|
||||||
preview: false,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
heroAttributes: PhotoViewHeroAttributes(
|
heroAttributes: PhotoViewHeroAttributes(
|
||||||
tag: 'attachment-${widget.data.first.rid}-$heroTag',
|
tag: 'attachment-${widget.data.first.rid}-$heroTag',
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_context_menu/flutter_context_menu.dart';
|
import 'package:flutter_context_menu/flutter_context_menu.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:popover/popover.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
import 'package:surface/providers/config.dart';
|
||||||
@ -117,9 +120,20 @@ class ChatMessage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (user == null) return;
|
if (user == null) return;
|
||||||
showModalBottomSheet(
|
showPopover(
|
||||||
|
backgroundColor:
|
||||||
|
Theme.of(context).colorScheme.surface,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AccountPopoverCard(data: user),
|
transition: PopoverTransition.other,
|
||||||
|
bodyBuilder: (context) => SizedBox(
|
||||||
|
width: math.min(
|
||||||
|
400, MediaQuery.of(context).size.width - 10),
|
||||||
|
child: AccountPopoverCard(data: user),
|
||||||
|
),
|
||||||
|
direction: PopoverDirection.bottom,
|
||||||
|
arrowHeight: 5,
|
||||||
|
arrowWidth: 15,
|
||||||
|
arrowDxOffset: -190,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -12,6 +12,7 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:popover/popover.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:relative_time/relative_time.dart';
|
import 'package:relative_time/relative_time.dart';
|
||||||
@ -1273,11 +1274,20 @@ class _PostAvatar extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showModalBottomSheet(
|
showPopover(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => PublisherPopoverCard(
|
transition: PopoverTransition.other,
|
||||||
|
bodyBuilder: (context) => SizedBox(
|
||||||
|
width: math.min(400, MediaQuery.of(context).size.width - 10),
|
||||||
|
child: PublisherPopoverCard(
|
||||||
data: data.publisher,
|
data: data.publisher,
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
direction: PopoverDirection.bottom,
|
||||||
|
arrowHeight: 5,
|
||||||
|
arrowWidth: 15,
|
||||||
|
arrowDxOffset: -190,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -24,14 +24,12 @@ class PublisherPopoverCard extends StatelessWidget {
|
|||||||
|
|
||||||
final user = data.type == 0 ? ud.getFromCache(data.accountId) : null;
|
final user = data.type == 0 ? ud.getFromCache(data.accountId) : null;
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return Column(
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (data.banner.isNotEmpty)
|
if (data.banner.isNotEmpty)
|
||||||
ClipRRect(
|
Container(
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
child: Container(
|
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 7,
|
aspectRatio: 16 / 7,
|
||||||
@ -41,8 +39,6 @@ class PublisherPopoverCard extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
).padding(all: 16)
|
|
||||||
else
|
|
||||||
// Top padding
|
// Top padding
|
||||||
Gap(16),
|
Gap(16),
|
||||||
Row(
|
Row(
|
||||||
@ -74,8 +70,7 @@ class PublisherPopoverCard extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
icon: const Icon(Symbols.chevron_right),
|
icon: const Icon(Symbols.chevron_right),
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
visualDensity:
|
visualDensity: const VisualDensity(horizontal: -4, vertical: -4),
|
||||||
const VisualDensity(horizontal: -4, vertical: -4),
|
|
||||||
),
|
),
|
||||||
const Gap(8)
|
const Gap(8)
|
||||||
],
|
],
|
||||||
@ -103,10 +98,7 @@ class PublisherPopoverCard extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text('publisherSocialPoint')
|
Text('publisherSocialPoint').tr().fontSize(13).opacity(0.75),
|
||||||
.tr()
|
|
||||||
.fontSize(13)
|
|
||||||
.opacity(0.75),
|
|
||||||
Text((data.totalUpvote - data.totalDownvote).toString()),
|
Text((data.totalUpvote - data.totalDownvote).toString()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -122,10 +114,7 @@ class PublisherPopoverCard extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text('publisherTotalUpvote')
|
Text('publisherTotalUpvote').tr().fontSize(13).opacity(0.75),
|
||||||
.tr()
|
|
||||||
.fontSize(13)
|
|
||||||
.opacity(0.75),
|
|
||||||
Text(data.totalUpvote.toString()),
|
Text(data.totalUpvote.toString()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -152,9 +141,8 @@ class PublisherPopoverCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
).padding(horizontal: 16),
|
).padding(horizontal: 16),
|
||||||
// Bottom padding
|
// Bottom padding
|
||||||
const Gap(64),
|
const Gap(16),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user