Compare commits
No commits in common. "a20c2598fcb773c3f5959b85c79c5b4edbab75e2" and "46919dec31beeeeb05baf86c8348b361d23def81" have entirely different histories.
a20c2598fc
...
46919dec31
@ -532,7 +532,7 @@
|
|||||||
"aboutScreenContactUsTitle": "联系我们",
|
"aboutScreenContactUsTitle": "联系我们",
|
||||||
"aboutScreenLicenseTitle": "许可证",
|
"aboutScreenLicenseTitle": "许可证",
|
||||||
"aboutScreenLicenseContent": "GNU Affero General Public License v3.0",
|
"aboutScreenLicenseContent": "GNU Affero General Public License v3.0",
|
||||||
"aboutScreenCopyright": "版权所有 © 索尔辛茨 {}",
|
"aboutScreenCopyright": "版权所有 © Solsynth {}",
|
||||||
"aboutScreenMadeWith": "由 Solar Network Team 用 ❤︎️ 制作",
|
"aboutScreenMadeWith": "由 Solar Network Team 用 ❤︎️ 制作",
|
||||||
"aboutScreenFailedToLoadPackageInfo": "加载包信息失败:{error}",
|
"aboutScreenFailedToLoadPackageInfo": "加载包信息失败:{error}",
|
||||||
"copiedToClipboard": "已复制到剪贴板",
|
"copiedToClipboard": "已复制到剪贴板",
|
||||||
|
@ -221,7 +221,7 @@ class IslandApp extends HookConsumerWidget {
|
|||||||
Future(() {
|
Future(() {
|
||||||
userNotifier.fetchUser().then((_) {
|
userNotifier.fetchUser().then((_) {
|
||||||
final user = ref.watch(userInfoProvider);
|
final user = ref.watch(userInfoProvider);
|
||||||
if (user.value != null) {
|
if (user.hasValue) {
|
||||||
final apiClient = ref.read(apiClientProvider);
|
final apiClient = ref.read(apiClientProvider);
|
||||||
subscribePushNotification(apiClient);
|
subscribePushNotification(apiClient);
|
||||||
final wsNotifier = ref.read(websocketStateProvider.notifier);
|
final wsNotifier = ref.read(websocketStateProvider.notifier);
|
||||||
|
@ -18,13 +18,8 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
|||||||
final user = SnAccount.fromJson(response.data);
|
final user = SnAccount.fromJson(response.data);
|
||||||
state = AsyncValue.data(user);
|
state = AsyncValue.data(user);
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
log(
|
log("[UserInfo] Failed to fetch user info: $error");
|
||||||
"[UserInfo] Failed to fetch user info...",
|
state = AsyncValue.error(error, stackTrace);
|
||||||
name: 'UserInfoNotifier',
|
|
||||||
error: error,
|
|
||||||
stackTrace: stackTrace,
|
|
||||||
);
|
|
||||||
state = AsyncValue.data(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
notificationUnreadCountNotifierProvider,
|
notificationUnreadCountNotifierProvider,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (user.value == null || user.value == null) {
|
if (!user.hasValue || user.value == null) {
|
||||||
return _UnauthorizedAccountScreen();
|
return _UnauthorizedAccountScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,23 +367,12 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
Row(
|
TextButton(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
onPressed: () {
|
||||||
children: [
|
context.push('/settings');
|
||||||
TextButton(
|
},
|
||||||
onPressed: () {
|
child: Text('appSettings').tr(),
|
||||||
context.push('/about');
|
).center(),
|
||||||
},
|
|
||||||
child: Text('about').tr(),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
context.push('/settings');
|
|
||||||
},
|
|
||||||
child: Text('appSettings').tr(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
).center(),
|
).center(),
|
||||||
|
@ -82,7 +82,7 @@ class EventCalanderScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
|
|
||||||
// Show user profile if viewing someone else's calendar
|
// Show user profile if viewing someone else's calendar
|
||||||
if (name != 'me' && user.value != null)
|
if (name != 'me' && user.hasValue)
|
||||||
AccountNameplate(name: name),
|
AccountNameplate(name: name),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -106,7 +106,7 @@ class EventCalanderScreen extends HookConsumerWidget {
|
|||||||
).padding(horizontal: 8, vertical: 4),
|
).padding(horizontal: 8, vertical: 4),
|
||||||
|
|
||||||
// Show user profile if viewing someone else's calendar
|
// Show user profile if viewing someone else's calendar
|
||||||
if (name != 'me' && user.value != null)
|
if (name != 'me' && user.hasValue)
|
||||||
AccountNameplate(name: name),
|
AccountNameplate(name: name),
|
||||||
Gap(MediaQuery.of(context).padding.bottom + 16),
|
Gap(MediaQuery.of(context).padding.bottom + 16),
|
||||||
],
|
],
|
||||||
|
@ -72,8 +72,6 @@ Future<Color?> accountAppbarForcegroundColor(Ref ref, String uname) async {
|
|||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<SnChatRoom?> accountDirectChat(Ref ref, String uname) async {
|
Future<SnChatRoom?> accountDirectChat(Ref ref, String uname) async {
|
||||||
final userInfo = ref.watch(userInfoProvider);
|
|
||||||
if (userInfo.value == null) return null;
|
|
||||||
final account = await ref.watch(accountProvider(uname).future);
|
final account = await ref.watch(accountProvider(uname).future);
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
try {
|
try {
|
||||||
@ -89,8 +87,6 @@ Future<SnChatRoom?> accountDirectChat(Ref ref, String uname) async {
|
|||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<SnRelationship?> accountRelationship(Ref ref, String uname) async {
|
Future<SnRelationship?> accountRelationship(Ref ref, String uname) async {
|
||||||
final userInfo = ref.watch(userInfoProvider);
|
|
||||||
if (userInfo.value == null) return null;
|
|
||||||
final account = await ref.watch(accountProvider(uname).future);
|
final account = await ref.watch(accountProvider(uname).future);
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
try {
|
try {
|
||||||
@ -223,8 +219,6 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
final user = ref.watch(userInfoProvider);
|
|
||||||
|
|
||||||
return account.when(
|
return account.when(
|
||||||
data:
|
data:
|
||||||
(data) => AppScaffold(
|
(data) => AppScaffold(
|
||||||
@ -385,60 +379,56 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
).padding(horizontal: 24),
|
).padding(horizontal: 24),
|
||||||
),
|
),
|
||||||
|
|
||||||
if (user.value != null)
|
SliverToBoxAdapter(
|
||||||
SliverToBoxAdapter(
|
child: const Divider(height: 1).padding(top: 24, bottom: 12),
|
||||||
child: const Divider(
|
),
|
||||||
height: 1,
|
SliverToBoxAdapter(
|
||||||
).padding(top: 24, bottom: 12),
|
child: Row(
|
||||||
),
|
spacing: 8,
|
||||||
if (user.value != null)
|
children: [
|
||||||
SliverToBoxAdapter(
|
Expanded(
|
||||||
child: Row(
|
child: FilledButton.icon(
|
||||||
spacing: 8,
|
style: ButtonStyle(
|
||||||
children: [
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
Expanded(
|
accountRelationship.value == null
|
||||||
child: FilledButton.icon(
|
? null
|
||||||
style: ButtonStyle(
|
: Theme.of(context).colorScheme.secondary,
|
||||||
backgroundColor: WidgetStatePropertyAll(
|
|
||||||
accountRelationship.value == null
|
|
||||||
? null
|
|
||||||
: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
foregroundColor: WidgetStatePropertyAll(
|
|
||||||
accountRelationship.value == null
|
|
||||||
? null
|
|
||||||
: Theme.of(context).colorScheme.onSecondary,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: relationshipAction,
|
foregroundColor: WidgetStatePropertyAll(
|
||||||
label:
|
accountRelationship.value == null
|
||||||
Text(
|
? null
|
||||||
accountRelationship.value == null
|
: Theme.of(context).colorScheme.onSecondary,
|
||||||
? 'addFriendShort'
|
),
|
||||||
: 'added',
|
),
|
||||||
).tr(),
|
onPressed: relationshipAction,
|
||||||
icon:
|
label:
|
||||||
|
Text(
|
||||||
accountRelationship.value == null
|
accountRelationship.value == null
|
||||||
? const Icon(Symbols.person_add)
|
? 'addFriendShort'
|
||||||
: const Icon(Symbols.person_check),
|
: 'added',
|
||||||
),
|
).tr(),
|
||||||
|
icon:
|
||||||
|
accountRelationship.value == null
|
||||||
|
? const Icon(Symbols.person_add)
|
||||||
|
: const Icon(Symbols.person_check),
|
||||||
),
|
),
|
||||||
Expanded(
|
),
|
||||||
child: FilledButton.icon(
|
Expanded(
|
||||||
onPressed: directMessageAction,
|
child: FilledButton.icon(
|
||||||
icon: const Icon(Symbols.message),
|
onPressed: directMessageAction,
|
||||||
label:
|
icon: const Icon(Symbols.message),
|
||||||
Text(
|
label:
|
||||||
accountChat.value == null
|
Text(
|
||||||
? 'createDirectMessage'
|
accountChat.value == null
|
||||||
: 'gotoDirectMessage',
|
? 'createDirectMessage'
|
||||||
maxLines: 1,
|
: 'gotoDirectMessage',
|
||||||
).tr(),
|
maxLines: 1,
|
||||||
),
|
).tr(),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
).padding(horizontal: 16),
|
],
|
||||||
),
|
).padding(horizontal: 16),
|
||||||
|
),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: const Divider(height: 1).padding(top: 12),
|
child: const Divider(height: 1).padding(top: 12),
|
||||||
),
|
),
|
||||||
|
@ -51,59 +51,54 @@ class _ArticleDetailContent extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Center(
|
child: Column(
|
||||||
child: ConstrainedBox(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
constraints: const BoxConstraints(maxWidth: 560),
|
children: [
|
||||||
child: Column(
|
if (article.preview?.imageUrl != null)
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
Image.network(
|
||||||
children: [
|
article.preview!.imageUrl!,
|
||||||
if (article.preview?.imageUrl != null)
|
width: double.infinity,
|
||||||
Image.network(
|
height: 200,
|
||||||
article.preview!.imageUrl!,
|
fit: BoxFit.cover,
|
||||||
width: double.infinity,
|
),
|
||||||
height: 200,
|
Padding(
|
||||||
fit: BoxFit.cover,
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
article.title,
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall,
|
||||||
),
|
),
|
||||||
Padding(
|
const SizedBox(height: 8),
|
||||||
padding: const EdgeInsets.all(16.0),
|
if (article.feed?.title != null)
|
||||||
child: Column(
|
Text(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
article.feed!.title,
|
||||||
children: [
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
Text(
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
article.title,
|
|
||||||
style: Theme.of(context).textTheme.headlineSmall,
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
),
|
||||||
if (article.feed?.title != null)
|
const Divider(height: 32),
|
||||||
Text(
|
if (article.content != null)
|
||||||
article.feed!.title,
|
...MarkdownTextContent.buildGenerator(
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
isDark: Theme.of(context).brightness == Brightness.dark,
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
).buildWidgets(markdownContent)
|
||||||
),
|
else if (article.preview?.description != null)
|
||||||
|
Text(article.preview!.description!),
|
||||||
|
const Gap(24),
|
||||||
|
FilledButton(
|
||||||
|
onPressed:
|
||||||
|
() => launchUrlString(
|
||||||
|
article.url,
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
),
|
),
|
||||||
const Divider(height: 32),
|
child: const Text('Read Full Article'),
|
||||||
if (article.content != null)
|
|
||||||
...MarkdownTextContent.buildGenerator(
|
|
||||||
isDark: Theme.of(context).brightness == Brightness.dark,
|
|
||||||
).buildWidgets(markdownContent)
|
|
||||||
else if (article.preview?.description != null)
|
|
||||||
Text(article.preview!.description!),
|
|
||||||
const Gap(24),
|
|
||||||
FilledButton(
|
|
||||||
onPressed:
|
|
||||||
() => launchUrlString(
|
|
||||||
article.url,
|
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
child: const Text('Read Full Article'),
|
|
||||||
),
|
|
||||||
Gap(MediaQuery.of(context).padding.bottom),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
Gap(MediaQuery.of(context).padding.bottom),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -126,21 +126,16 @@ class ArticlesScreen extends ConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text(title ?? 'Articles')),
|
appBar: AppBar(title: Text(title ?? 'Articles')),
|
||||||
body: Center(
|
body: CustomScrollView(
|
||||||
child: ConstrainedBox(
|
slivers: [
|
||||||
constraints: const BoxConstraints(maxWidth: 560),
|
SliverPadding(
|
||||||
child: CustomScrollView(
|
padding: const EdgeInsets.only(top: 8, left: 8, right: 8),
|
||||||
slivers: [
|
sliver: SliverArticlesList(
|
||||||
SliverPadding(
|
feedId: feedId,
|
||||||
padding: const EdgeInsets.only(top: 8, left: 8, right: 8),
|
publisherId: publisherId,
|
||||||
sliver: SliverArticlesList(
|
),
|
||||||
feedId: feedId,
|
|
||||||
publisherId: publisherId,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ class _ActivityListView extends HookConsumerWidget {
|
|||||||
|
|
||||||
return CustomScrollView(
|
return CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
if (user.value != null && !contentOnly)
|
if (user.hasValue && !contentOnly)
|
||||||
SliverToBoxAdapter(child: CheckInWidget()),
|
SliverToBoxAdapter(child: CheckInWidget()),
|
||||||
SliverList.builder(
|
SliverList.builder(
|
||||||
itemCount: widgetCount,
|
itemCount: widgetCount,
|
||||||
|
@ -59,7 +59,7 @@ class AccountStatusCreationSheet extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
options: Options(method: initialStatus == null ? 'POST' : 'PATCH'),
|
options: Options(method: initialStatus == null ? 'POST' : 'PATCH'),
|
||||||
);
|
);
|
||||||
if (user.value != null) {
|
if (user.hasValue) {
|
||||||
ref.invalidate(accountStatusProvider(user.value!.name));
|
ref.invalidate(accountStatusProvider(user.value!.name));
|
||||||
}
|
}
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
|
@ -350,7 +350,7 @@ class _WebSocketIndicator extends HookConsumerWidget {
|
|||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
duration: Duration(milliseconds: 1850),
|
duration: Duration(milliseconds: 1850),
|
||||||
top:
|
top:
|
||||||
user.value == null ||
|
!user.hasValue ||
|
||||||
user.value == null ||
|
user.value == null ||
|
||||||
websocketState == WebSocketState.connected()
|
websocketState == WebSocketState.connected()
|
||||||
? -indicatorHeight
|
? -indicatorHeight
|
||||||
@ -362,7 +362,7 @@ class _WebSocketIndicator extends HookConsumerWidget {
|
|||||||
child: IgnorePointer(
|
child: IgnorePointer(
|
||||||
child: Material(
|
child: Material(
|
||||||
elevation:
|
elevation:
|
||||||
user.value == null || websocketState == WebSocketState.connected()
|
!user.hasValue || websocketState == WebSocketState.connected()
|
||||||
? 0
|
? 0
|
||||||
: 4,
|
: 4,
|
||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
|
@ -56,7 +56,7 @@ class PostItem extends HookConsumerWidget {
|
|||||||
|
|
||||||
final user = ref.watch(userInfoProvider);
|
final user = ref.watch(userInfoProvider);
|
||||||
final isAuthor = useMemoized(
|
final isAuthor = useMemoized(
|
||||||
() => user.value != null && user.value?.id == item.publisher.accountId,
|
() => user.hasValue && user.value?.id == item.publisher.accountId,
|
||||||
[user],
|
[user],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user