Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Menu item to view a community in a specific instance other than the originating instance #254

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@
"@pinned": {},
"by": "by",
"@by": {},
"view_on": "View on another instance",
"@view_on": {},
"foreign_community_info": "Loading the community in the other instance. Note that if this is the first time the community is being viewed in the instance, this process may take a while.",
"@foreign_community_info": {},

"error": "Error: {error_text}",
"@error" :{
Expand Down
13 changes: 9 additions & 4 deletions lib/hooks/logged_in_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:lemmy_api_client/v3.dart';

import '../pages/settings/settings.dart';
import '../stores/accounts_store.dart';
import '../util/goto.dart';
import 'stores.dart';

Expand Down Expand Up @@ -36,14 +37,18 @@ VoidCallback Function(
}

VoidCallback Function(
void Function(Jwt token) action, [
void Function(UserData userData) action, [
String? message,
]) useLoggedInAction(String instanceHost) {
]) useLoggedInAction(String instanceHost, {void Function()? fallback}) {
final context = useContext();
final store = useAccountsStore();

return (action, [message]) {
if (store.isAnonymousFor(instanceHost)) {
if (fallback != null && !store.hasNoAccount) {
return fallback;
}

return () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
duration: const Duration(seconds: 7),
Expand All @@ -55,7 +60,7 @@ VoidCallback Function(
));
};
}
final token = store.defaultUserDataFor(instanceHost)!.jwt;
return () => action(token);
final userData = store.defaultUserDataFor(instanceHost)!;
return () => action(userData);
};
}
5 changes: 3 additions & 2 deletions lib/pages/communities_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../hooks/delayed_loading.dart';
import '../hooks/logged_in_action.dart';
import '../hooks/refreshable.dart';
import '../hooks/stores.dart';
import '../stores/accounts_store.dart';
import '../util/extensions/api.dart';
import '../util/extensions/iterators.dart';
import '../util/goto.dart';
Expand Down Expand Up @@ -256,14 +257,14 @@ class _CommunitySubscribeToggle extends HookWidget {
final delayed = useDelayedLoading();
final loggedInAction = useLoggedInAction(instanceHost);

handleTap(Jwt token) async {
handleTap(UserData userData) async {
delayed.start();

try {
await LemmyApiV3(instanceHost).run(FollowCommunity(
communityId: communityId,
follow: !subbed.value,
auth: token.raw,
auth: userData.jwt.raw,
));
subbed.value = !subbed.value;
} on Exception catch (err) {
Expand Down
9 changes: 3 additions & 6 deletions lib/pages/community/community.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ class CommunityPage extends HookWidget {
? FailedToLoad(
refresh: () => store.refresh(context
.read<AccountsStore>()
.defaultUserDataFor(store.instanceHost)
?.jwt),
.defaultUserDataFor(store.instanceHost)),
message: communityState.errorTerm!.tr(context),
)
: const CircularProgressIndicator.adaptive()),
Expand Down Expand Up @@ -166,10 +165,8 @@ class CommunityPage extends HookWidget {
builder: (context) {
return MobxProvider.value(
value: store
..refresh(context
.read<AccountsStore>()
.defaultUserDataFor(instanceHost)
?.jwt),
..refresh(
context.read<AccountsStore>().defaultUserDataFor(instanceHost)),
child: const CommunityPage(),
);
},
Expand Down
3 changes: 1 addition & 2 deletions lib/pages/community/community_about_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ class CommmunityAboutTab extends StatelessWidget {
onRefresh: () async {
await context.read<CommunityStore>().refresh(context
.read<AccountsStore>()
.defaultUserDataFor(fullCommunityView.instanceHost)
?.jwt);
.defaultUserDataFor(fullCommunityView.instanceHost));
},
child: ListView(
padding: const EdgeInsets.only(top: 20),
Expand Down
7 changes: 5 additions & 2 deletions lib/pages/community/community_follow_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:lemmy_api_client/v3.dart';
import '../../hooks/logged_in_action.dart';
import '../../l10n/l10n.dart';
import '../../util/observer_consumers.dart';
import '../view_on_menu.dart';
import 'community_store.dart';

class CommunityFollowButton extends HookWidget {
Expand All @@ -16,8 +17,10 @@ class CommunityFollowButton extends HookWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);

final loggedInAction =
useLoggedInAction(context.read<CommunityStore>().instanceHost);
final loggedInAction = useLoggedInAction(
context.read<CommunityStore>().instanceHost, fallback: () {
ViewOnMenu.openForCommunity(context, communityView);
});

return ObserverBuilder<CommunityStore>(builder: (context, store) {
return ElevatedButtonTheme(
Expand Down
10 changes: 8 additions & 2 deletions lib/pages/community/community_more_menu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../../util/mobx_provider.dart';
import '../../util/observer_consumers.dart';
import '../../widgets/bottom_modal.dart';
import '../../widgets/info_table_popup.dart';
import '../view_on_menu.dart';
import 'community_store.dart';

class CommunityMoreMenu extends HookWidget {
Expand All @@ -33,6 +34,11 @@ class CommunityMoreMenu extends HookWidget {
context: context,
),
),
ListTile(
leading: const Icon(Icons.travel_explore),
title: Text(L10n.of(context).view_on),
onTap: () => ViewOnMenu.openForCommunity(context, communityView),
),
ObserverBuilder<CommunityStore>(builder: (context, store) {
return ListTile(
leading: store.blockingState.isLoading
Expand All @@ -42,8 +48,8 @@ class CommunityMoreMenu extends HookWidget {
'${fullCommunityView.communityView.blocked ? L10n.of(context).unblock : L10n.of(context).block} ${communityView.community.preferredName}'),
onTap: store.blockingState.isLoading
? null
: loggedInAction((token) {
store.block(token);
: loggedInAction((userData) {
store.block(userData);
Navigator.of(context).pop();
}),
);
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/community/community_overview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class CommunityOverview extends StatelessWidget {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Text(
community.community.title,
'${community.community.title}${community.community.instanceHost != community.community.originInstanceHost ? ' (via ${community.community.instanceHost})' : ''}',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w300,
Expand Down
13 changes: 7 additions & 6 deletions lib/pages/community/community_store.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:lemmy_api_client/v3.dart';
import 'package:mobx/mobx.dart';

import '../../stores/accounts_store.dart';
import '../../util/async_store.dart';

part 'community_store.g.dart';
Expand All @@ -26,19 +27,19 @@ abstract class _CommunityStore with Store {
final blockingState = AsyncStore<BlockedCommunity>();

@action
Future<void> refresh(Jwt? token) async {
Future<void> refresh(UserData? userData) async {
await communityState.runLemmy(
instanceHost,
GetCommunity(
auth: token?.raw,
auth: userData?.jwt.raw,
id: id,
name: communityName,
),
refresh: true,
);
}

Future<void> block(Jwt token) async {
Future<void> block(UserData userData) async {
final state = communityState.asyncState;
if (state is! AsyncStateData<FullCommunityView>) {
throw StateError('communityState should be ready at this point');
Expand All @@ -49,7 +50,7 @@ abstract class _CommunityStore with Store {
BlockCommunity(
communityId: state.data.communityView.community.id,
block: !state.data.communityView.blocked,
auth: token.raw,
auth: userData.jwt.raw,
),
);

Expand All @@ -60,7 +61,7 @@ abstract class _CommunityStore with Store {
}

@action
Future<void> subscribe(Jwt token) async {
Future<void> subscribe(UserData userData) async {
final state = communityState.asyncState;

if (state is! AsyncStateData<FullCommunityView>) {
Expand All @@ -81,7 +82,7 @@ abstract class _CommunityStore with Store {
return true;
}
}(),
auth: token.raw,
auth: userData.jwt.raw,
),
);

Expand Down
8 changes: 4 additions & 4 deletions lib/pages/community/community_store.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions lib/pages/community/federated_community.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:lemmy_api_client/v3.dart';

import '../../l10n/l10n.dart';
import '../../stores/accounts_store.dart';
import 'community.dart';

class FederatedCommunityPage extends HookWidget {
final UserData userData;
final String community;

const FederatedCommunityPage(this.userData, this.community);

@override
Widget build(BuildContext context) {
final lemmyApi = LemmyApiV3(userData.instanceHost);

return FutureBuilder(
future: lemmyApi
.run(ResolveObject(q: community, auth: userData.jwt.raw))
.then((data) {
Navigator.of(context).pop();
Navigator.of(context).push(CommunityPage.fromIdRoute(
userData.instanceHost, data.community!.community.id));
}),
builder: (context, snapshot) {
return Scaffold(
appBar: AppBar(),
body: Container(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Container(height: 36),
const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
],
),
Container(height: 24),
Text(
snapshot.hasError
? 'Error: ${snapshot.error}'
: L10n.of(context).foreign_community_info,
textAlign: TextAlign.center,
),
],
)));
},
);
}
}
4 changes: 2 additions & 2 deletions lib/pages/create_post/create_post.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ class CreatePostPage extends HookWidget {
text: context.read<CreatePostStore>().body);
final titleFocusNode = useFocusNode();

handleSubmit(Jwt token) async {
handleSubmit(UserData userData) async {
if (formKey.currentState!.validate()) {
await context.read<CreatePostStore>().submit(token);
await context.read<CreatePostStore>().submit(userData);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/pages/create_post/create_post_community_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class CreatePostCommunityPicker extends HookWidget {
suggestionsCallback: (pattern) async {
final communities = await store.searchCommunities(
pattern,
context.defaultJwt(store.instanceHost),
context.defaultUserData(store.instanceHost),
);

return communities ?? [];
Expand Down
17 changes: 9 additions & 8 deletions lib/pages/create_post/create_post_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:lemmy_api_client/pictrs.dart';
import 'package:lemmy_api_client/v3.dart';
import 'package:mobx/mobx.dart';

import '../../stores/accounts_store.dart';
import '../../util/async_store.dart';
import '../../util/pictrs.dart';

Expand Down Expand Up @@ -52,7 +53,7 @@ abstract class _CreatePostStore with Store {
@action
Future<List<CommunityView>?> searchCommunities(
String searchTerm,
Jwt? token,
UserData? userData,
) {
if (searchTerm.isEmpty) {
return searchCommunitiesState.runLemmy(
Expand All @@ -61,7 +62,7 @@ abstract class _CreatePostStore with Store {
type: PostListingType.all,
sort: SortType.topAll,
limit: 10,
auth: token?.raw,
auth: userData?.jwt.raw,
),
);
} else {
Expand All @@ -72,14 +73,14 @@ abstract class _CreatePostStore with Store {
sort: SortType.topAll,
listingType: PostListingType.all,
limit: 10,
auth: token?.raw,
auth: userData?.jwt.raw,
),
);
}
}

@action
Future<void> submit(Jwt token) async {
Future<void> submit(UserData token) async {
await submitState.runLemmy(
instanceHost,
isEdit
Expand All @@ -89,28 +90,28 @@ abstract class _CreatePostStore with Store {
nsfw: nsfw,
name: title,
postId: postToEdit!.id,
auth: token.raw,
auth: token.jwt.raw,
)
: CreatePost(
url: url.isEmpty ? null : url,
body: body.isEmpty ? null : body,
nsfw: nsfw,
name: title,
communityId: selectedCommunity!.community.id,
auth: token.raw,
auth: token.jwt.raw,
),
);
}

@action
Future<void> uploadImage(String filePath, Jwt token) async {
Future<void> uploadImage(String filePath, UserData userData) async {
final instanceHost = this.instanceHost;

final upload = await imageUploadState.run(
() => PictrsApi(instanceHost)
.upload(
filePath: filePath,
auth: token.raw,
auth: userData.jwt.raw,
)
.then((value) => value.files.single),
);
Expand Down
Loading