💄 Realm shortcut

This commit is contained in:
LittleSheep 2024-05-07 23:38:12 +08:00
parent 3bcdc67285
commit a4f8c65aa5
5 changed files with 143 additions and 26 deletions

View File

@ -76,6 +76,7 @@
"postEditNotify": "You are about editing a post that already published.", "postEditNotify": "You are about editing a post that already published.",
"reactionAdded": "Your reaction has been added.", "reactionAdded": "Your reaction has been added.",
"reactionRemoved": "Your reaction has been removed.", "reactionRemoved": "Your reaction has been removed.",
"shortcutsEmpty": "Shortcuts are empty, looks like you didn't go anywhere recently...",
"realmNew": "New Realm", "realmNew": "New Realm",
"realmNewCreate": "Create a realm", "realmNewCreate": "Create a realm",
"realmNewJoin": "Join a exists realm", "realmNewJoin": "Join a exists realm",

View File

@ -76,6 +76,7 @@
"postEditNotify": "你正在修改一个已经发布了的帖子。", "postEditNotify": "你正在修改一个已经发布了的帖子。",
"reactionAdded": "你的反应已被添加。", "reactionAdded": "你的反应已被添加。",
"reactionRemoved": "你的反应已被移除。", "reactionRemoved": "你的反应已被移除。",
"shortcutsEmpty": "快捷方式空空如也,看起来最近你没去哪里呀~",
"realmNew": "新领域", "realmNew": "新领域",
"realmNewCreate": "创建新领域", "realmNewCreate": "创建新领域",
"realmNewJoin": "加入现有领域", "realmNewJoin": "加入现有领域",

View File

@ -5,12 +5,14 @@ import 'package:provider/provider.dart';
import 'package:solian/models/pagination.dart'; import 'package:solian/models/pagination.dart';
import 'package:solian/models/post.dart'; import 'package:solian/models/post.dart';
import 'package:solian/providers/auth.dart'; import 'package:solian/providers/auth.dart';
import 'package:solian/providers/realm.dart';
import 'package:solian/router.dart'; import 'package:solian/router.dart';
import 'package:solian/utils/service_url.dart'; import 'package:solian/utils/service_url.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:solian/utils/theme.dart'; import 'package:solian/utils/theme.dart';
import 'package:solian/widgets/realms/realm_shortcuts.dart';
import 'package:solian/widgets/scaffold.dart'; import 'package:solian/widgets/scaffold.dart';
import 'package:solian/widgets/notification_notifier.dart'; import 'package:solian/widgets/notification_notifier.dart';
import 'package:solian/widgets/posts/post.dart'; import 'package:solian/widgets/posts/post.dart';
@ -25,15 +27,20 @@ class ExplorePostScreen extends StatelessWidget {
fixedAppBarColor: SolianTheme.isLargeScreen(context), fixedAppBarColor: SolianTheme.isLargeScreen(context),
appBarActions: const [NotificationButton()], appBarActions: const [NotificationButton()],
title: AppLocalizations.of(context)!.explore, title: AppLocalizations.of(context)!.explore,
child: const ExplorePostWidget(), child: const ExplorePostWidget(showRealmShortcuts: true),
); );
} }
} }
class ExplorePostWidget extends StatefulWidget { class ExplorePostWidget extends StatefulWidget {
final String? realm; final String? realm;
final bool showRealmShortcuts;
const ExplorePostWidget({super.key, this.realm}); const ExplorePostWidget({
super.key,
this.realm,
this.showRealmShortcuts = false,
});
@override @override
State<ExplorePostWidget> createState() => _ExplorePostWidgetState(); State<ExplorePostWidget> createState() => _ExplorePostWidgetState();
@ -75,6 +82,16 @@ class _ExplorePostWidgetState extends State<ExplorePostWidget> {
void initState() { void initState() {
super.initState(); super.initState();
Future.delayed(Duration.zero, () async {
if (widget.showRealmShortcuts) {
final auth = context.read<AuthProvider>();
if (auth.client == null) {
await auth.loadClient();
}
context.read<RealmProvider>().fetch(auth);
}
});
_pagingController.addPageRequestListener((pageKey) => fetchFeed(pageKey)); _pagingController.addPageRequestListener((pageKey) => fetchFeed(pageKey));
} }
@ -106,24 +123,50 @@ class _ExplorePostWidgetState extends State<ExplorePostWidget> {
onRefresh: () => Future.sync( onRefresh: () => Future.sync(
() => _pagingController.refresh(), () => _pagingController.refresh(),
), ),
child: PagedListView<int, Post>( child: CustomScrollView(
pagingController: _pagingController, slivers: [
builderDelegate: PagedChildBuilderDelegate<Post>( widget.showRealmShortcuts
itemBuilder: (context, item, index) => PostItem( ? SliverToBoxAdapter(
item: item, child: FutureBuilder(
onUpdate: () => _pagingController.refresh(), future: auth.isAuthorized(),
onTap: () { builder: (context, snapshot) {
SolianRouter.router.pushNamed( if (!snapshot.hasData || snapshot.data != true) {
widget.realm == null ? 'posts.details' : 'realms.posts.details', return Container();
pathParameters: { }
'alias': item.alias,
'dataset': item.dataset, return Container(
...(widget.realm == null ? {} : {'realm': widget.realm!}), height: 120,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 0.3, color: Theme.of(context).dividerColor),
),
),
child: const RealmShortcuts(),
);
},
),
)
: SliverToBoxAdapter(child: Container()),
PagedSliverList<int, Post>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<Post>(
itemBuilder: (context, item, index) => PostItem(
item: item,
onUpdate: () => _pagingController.refresh(),
onTap: () {
SolianRouter.router.pushNamed(
widget.realm == null ? 'posts.details' : 'realms.posts.details',
pathParameters: {
'alias': item.alias,
'dataset': item.dataset,
...(widget.realm == null ? {} : {'realm': widget.realm!}),
},
);
}, },
); ),
}, ),
), ),
), ],
), ),
), ),
); );

View File

@ -32,14 +32,16 @@ class RealmScreen extends StatelessWidget {
), ),
] ]
: [], : [],
appBarLeading: SolianTheme.isLargeScreen(context) appBarLeading: IconButton(
? IconButton( icon: const Icon(Icons.arrow_back),
icon: const Icon(Icons.arrow_back), onPressed: () {
onPressed: () { if (SolianTheme.isLargeScreen(context)) {
realm.clearFocus(); realm.clearFocus();
}, } else if (SolianRouter.router.canPop()) {
) SolianRouter.router.pop();
: null, }
},
),
child: RealmWidget( child: RealmWidget(
alias: alias, alias: alias,
), ),

View File

@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/providers/realm.dart';
import 'package:solian/router.dart';
import 'package:solian/utils/theme.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class RealmShortcuts extends StatelessWidget {
const RealmShortcuts({super.key});
@override
Widget build(BuildContext context) {
final auth = context.read<AuthProvider>();
final realm = context.watch<RealmProvider>();
if (realm.realms.isEmpty) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 280,
child: Text(
AppLocalizations.of(context)!.shortcutsEmpty,
style: const TextStyle(fontWeight: FontWeight.normal, fontSize: 16),
textAlign: TextAlign.center,
),
)
],
);
}
return ListView.builder(
itemCount: realm.realms.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final element = realm.realms[index];
return InkWell(
child: SizedBox(
width: 80,
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Padding(
padding: EdgeInsets.only(top: 16, bottom: 8),
child: CircleAvatar(
backgroundColor: Colors.teal,
child: Icon(Icons.supervised_user_circle, color: Colors.white),
),
),
Text(element.name, textAlign: TextAlign.center),
],
),
),
onTap: () async {
if (SolianTheme.isLargeScreen(context)) {
await realm.fetchSingle(auth, element.alias);
}
SolianRouter.router.pushNamed(
'realms.details',
pathParameters: {'realm': element.alias},
);
},
);
},
);
}
}