Fix federation errors and rename all instanceUrl to instanceHost
This commit is contained in:
parent
a9e5113890
commit
58f964ab66
|
@ -14,13 +14,13 @@ import 'stores.dart';
|
|||
Function(
|
||||
Function(Jwt token) action, [
|
||||
String message,
|
||||
]) useLoggedInAction(String instanceUrl, {bool any = false}) {
|
||||
]) useLoggedInAction(String instanceHost, {bool any = false}) {
|
||||
final context = useContext();
|
||||
final store = useAccountsStore();
|
||||
|
||||
return (Function(Jwt token) action, [message]) {
|
||||
if (any && store.hasNoAccount ||
|
||||
!any && store.isAnonymousFor(instanceUrl)) {
|
||||
!any && store.isAnonymousFor(instanceHost)) {
|
||||
return () {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(message ?? 'you have to be logged in to do that'),
|
||||
|
@ -30,7 +30,7 @@ Function(
|
|||
));
|
||||
};
|
||||
}
|
||||
final token = store.defaultTokenFor(instanceUrl);
|
||||
final token = store.defaultTokenFor(instanceHost);
|
||||
return () => action(token);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@ import 'add_instance.dart';
|
|||
|
||||
/// A modal where an account can be added for a given instance
|
||||
class AddAccountPage extends HookWidget {
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
||||
|
||||
AddAccountPage({@required this.instanceUrl}) : assert(instanceUrl != null);
|
||||
AddAccountPage({@required this.instanceHost}) : assert(instanceHost != null);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -29,7 +29,7 @@ class AddAccountPage extends HookWidget {
|
|||
final accountsStore = useAccountsStore();
|
||||
|
||||
final loading = useDelayedLoading();
|
||||
final selectedInstance = useState(instanceUrl);
|
||||
final selectedInstance = useState(instanceHost);
|
||||
final icon = useState<String>(null);
|
||||
useEffect(() {
|
||||
LemmyApi(selectedInstance.value)
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:cached_network_image/cached_network_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/goto.dart';
|
||||
import '../widgets/markdown_text.dart';
|
||||
import '../widgets/sortable_infinite_list.dart';
|
||||
|
@ -44,12 +43,12 @@ class CommunitiesListPage extends StatelessWidget {
|
|||
opacity: 0.5,
|
||||
child: MarkdownText(
|
||||
community.description,
|
||||
instanceUrl: community.instanceUrl,
|
||||
instanceHost: community.instanceHost,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
onTap: () => goToCommunity.byId(
|
||||
context, community.instanceUrl, community.id),
|
||||
context, community.instanceHost, community.id),
|
||||
leading: community.icon != null
|
||||
? CachedNetworkImage(
|
||||
height: 50,
|
||||
|
|
|
@ -32,8 +32,8 @@ class CommunitiesTab extends HookWidget {
|
|||
final instancesSnap = useMemoFuture(() {
|
||||
final futures = accountsStore.loggedInInstances
|
||||
.map(
|
||||
(instanceUrl) =>
|
||||
LemmyApi(instanceUrl).v1.getSite().then((e) => e.site),
|
||||
(instanceHost) =>
|
||||
LemmyApi(instanceHost).v1.getSite().then((e) => e.site),
|
||||
)
|
||||
.toList();
|
||||
|
||||
|
@ -42,12 +42,13 @@ class CommunitiesTab extends HookWidget {
|
|||
final communitiesSnap = useMemoFuture(() {
|
||||
final futures = accountsStore.loggedInInstances
|
||||
.map(
|
||||
(instanceUrl) => LemmyApi(instanceUrl)
|
||||
(instanceHost) => LemmyApi(instanceHost)
|
||||
.v1
|
||||
.getUserDetails(
|
||||
sort: SortType.active,
|
||||
savedOnly: false,
|
||||
userId: accountsStore.defaultTokenFor(instanceUrl).payload.id,
|
||||
userId:
|
||||
accountsStore.defaultTokenFor(instanceHost).payload.id,
|
||||
)
|
||||
.then((e) => e.follows),
|
||||
)
|
||||
|
@ -208,7 +209,7 @@ class CommunitiesTab extends HookWidget {
|
|||
],
|
||||
),
|
||||
trailing: _CommunitySubscribeToggle(
|
||||
instanceUrl: comm.communityActorId.split('/')[2],
|
||||
instanceHost: comm.communityActorId.split('/')[2],
|
||||
communityId: comm.communityId,
|
||||
),
|
||||
),
|
||||
|
@ -223,11 +224,11 @@ class CommunitiesTab extends HookWidget {
|
|||
|
||||
class _CommunitySubscribeToggle extends HookWidget {
|
||||
final int communityId;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
|
||||
_CommunitySubscribeToggle(
|
||||
{@required this.instanceUrl, @required this.communityId})
|
||||
: assert(instanceUrl != null),
|
||||
{@required this.instanceHost, @required this.communityId})
|
||||
: assert(instanceHost != null),
|
||||
assert(communityId != null);
|
||||
|
||||
@override
|
||||
|
@ -241,10 +242,10 @@ class _CommunitySubscribeToggle extends HookWidget {
|
|||
delayed.start();
|
||||
|
||||
try {
|
||||
await LemmyApi(instanceUrl).v1.followCommunity(
|
||||
await LemmyApi(instanceHost).v1.followCommunity(
|
||||
communityId: communityId,
|
||||
follow: !subbed.value,
|
||||
auth: accountsStore.defaultTokenFor(instanceUrl).raw,
|
||||
auth: accountsStore.defaultTokenFor(instanceHost).raw,
|
||||
);
|
||||
subbed.value = !subbed.value;
|
||||
} on Exception catch (err) {
|
||||
|
|
|
@ -10,7 +10,6 @@ import '../hooks/delayed_loading.dart';
|
|||
import '../hooks/logged_in_action.dart';
|
||||
import '../hooks/memo_future.dart';
|
||||
import '../hooks/stores.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/goto.dart';
|
||||
import '../util/intl.dart';
|
||||
import '../util/more_icon.dart';
|
||||
|
@ -25,26 +24,26 @@ import '../widgets/sortable_infinite_list.dart';
|
|||
/// Displays posts, comments, and general info about the given community
|
||||
class CommunityPage extends HookWidget {
|
||||
final CommunityView _community;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final String communityName;
|
||||
final int communityId;
|
||||
|
||||
CommunityPage.fromName({
|
||||
@required this.communityName,
|
||||
@required this.instanceUrl,
|
||||
@required this.instanceHost,
|
||||
}) : assert(communityName != null),
|
||||
assert(instanceUrl != null),
|
||||
assert(instanceHost != null),
|
||||
communityId = null,
|
||||
_community = null;
|
||||
CommunityPage.fromId({
|
||||
@required this.communityId,
|
||||
@required this.instanceUrl,
|
||||
@required this.instanceHost,
|
||||
}) : assert(communityId != null),
|
||||
assert(instanceUrl != null),
|
||||
assert(instanceHost != null),
|
||||
communityName = null,
|
||||
_community = null;
|
||||
CommunityPage.fromCommunityView(this._community)
|
||||
: instanceUrl = _community.instanceUrl,
|
||||
: instanceHost = _community.instanceHost,
|
||||
communityId = _community.id,
|
||||
communityName = _community.name;
|
||||
|
||||
|
@ -54,15 +53,15 @@ class CommunityPage extends HookWidget {
|
|||
final accountsStore = useAccountsStore();
|
||||
|
||||
final fullCommunitySnap = useMemoFuture(() {
|
||||
final token = accountsStore.defaultTokenFor(instanceUrl);
|
||||
final token = accountsStore.defaultTokenFor(instanceHost);
|
||||
|
||||
if (communityId != null) {
|
||||
return LemmyApi(instanceUrl).v1.getCommunity(
|
||||
return LemmyApi(instanceHost).v1.getCommunity(
|
||||
id: communityId,
|
||||
auth: token?.raw,
|
||||
);
|
||||
} else {
|
||||
return LemmyApi(instanceUrl).v1.getCommunity(
|
||||
return LemmyApi(instanceHost).v1.getCommunity(
|
||||
name: communityName,
|
||||
auth: token?.raw,
|
||||
);
|
||||
|
@ -169,7 +168,7 @@ class CommunityPage extends HookWidget {
|
|||
],
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
background:
|
||||
_CommunityOverview(community, instanceUrl: instanceUrl),
|
||||
_CommunityOverview(community, instanceHost: instanceHost),
|
||||
),
|
||||
),
|
||||
SliverPersistentHeader(
|
||||
|
@ -191,7 +190,7 @@ class CommunityPage extends HookWidget {
|
|||
children: [
|
||||
InfinitePostList(
|
||||
fetcher: (page, batchSize, sort) =>
|
||||
LemmyApi(community.instanceUrl).v1.getPosts(
|
||||
LemmyApi(community.instanceHost).v1.getPosts(
|
||||
type: PostListingType.community,
|
||||
sort: sort,
|
||||
communityId: community.id,
|
||||
|
@ -201,10 +200,10 @@ class CommunityPage extends HookWidget {
|
|||
),
|
||||
InfiniteCommentList(
|
||||
fetcher: (page, batchSize, sortType) =>
|
||||
LemmyApi(community.instanceUrl).v1.getComments(
|
||||
LemmyApi(community.instanceHost).v1.getComments(
|
||||
communityId: community.id,
|
||||
auth: accountsStore
|
||||
.defaultTokenFor(community.instanceUrl)
|
||||
.defaultTokenFor(community.instanceHost)
|
||||
?.raw,
|
||||
type: CommentListingType.community,
|
||||
sort: sortType,
|
||||
|
@ -225,12 +224,12 @@ class CommunityPage extends HookWidget {
|
|||
|
||||
class _CommunityOverview extends StatelessWidget {
|
||||
final CommunityView community;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
|
||||
_CommunityOverview(
|
||||
this.community, {
|
||||
@required this.instanceUrl,
|
||||
}) : assert(instanceUrl != null),
|
||||
@required this.instanceHost,
|
||||
}) : assert(instanceHost != null),
|
||||
assert(goToInstance != null);
|
||||
|
||||
@override
|
||||
|
@ -316,10 +315,10 @@ class _CommunityOverview extends StatelessWidget {
|
|||
text: '@',
|
||||
style: TextStyle(fontWeight: FontWeight.w200)),
|
||||
TextSpan(
|
||||
text: instanceUrl,
|
||||
text: instanceHost,
|
||||
style: TextStyle(fontWeight: FontWeight.w600),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => goToInstance(context, instanceUrl)),
|
||||
..onTap = () => goToInstance(context, instanceHost)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -423,7 +422,7 @@ class _AboutTab extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: MarkdownText(community.description,
|
||||
instanceUrl: community.instanceUrl),
|
||||
instanceHost: community.instanceHost),
|
||||
),
|
||||
_Divider(),
|
||||
],
|
||||
|
@ -480,7 +479,7 @@ class _AboutTab extends StatelessWidget {
|
|||
for (final mod in moderators)
|
||||
ListTile(
|
||||
title: Text(mod.userPreferredUsername ?? '@${mod.userName}'),
|
||||
onTap: () => goToUser.byId(context, mod.instanceUrl, mod.userId),
|
||||
onTap: () => goToUser.byId(context, mod.instanceHost, mod.userId),
|
||||
),
|
||||
]
|
||||
],
|
||||
|
@ -530,14 +529,14 @@ class _FollowButton extends HookWidget {
|
|||
|
||||
final isSubbed = useState(community.subscribed ?? false);
|
||||
final delayed = useDelayedLoading(const Duration(milliseconds: 500));
|
||||
final loggedInAction = useLoggedInAction(community.instanceUrl);
|
||||
final loggedInAction = useLoggedInAction(community.instanceHost);
|
||||
|
||||
final colorOnTopOfAccent = textColorBasedOnBackground(theme.accentColor);
|
||||
|
||||
subscribe(Jwt token) async {
|
||||
delayed.start();
|
||||
try {
|
||||
await LemmyApi(community.instanceUrl).v1.followCommunity(
|
||||
await LemmyApi(community.instanceHost).v1.followCommunity(
|
||||
communityId: community.id,
|
||||
follow: !isSubbed.value,
|
||||
auth: token.raw);
|
||||
|
|
|
@ -9,7 +9,6 @@ import '../hooks/image_picker.dart';
|
|||
import '../hooks/logged_in_action.dart';
|
||||
import '../hooks/memo_future.dart';
|
||||
import '../hooks/stores.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/extensions/spaced.dart';
|
||||
import '../util/goto.dart';
|
||||
import '../util/pictrs.dart';
|
||||
|
@ -46,7 +45,7 @@ class CreatePost extends HookWidget {
|
|||
final bodyController = useTextEditingController();
|
||||
final accStore = useAccountsStore();
|
||||
final selectedInstance =
|
||||
useState(community?.instanceUrl ?? accStore.loggedInInstances.first);
|
||||
useState(community?.instanceHost ?? accStore.loggedInInstances.first);
|
||||
final selectedCommunity = useState(community);
|
||||
final showFancy = useState(false);
|
||||
final nsfw = useState(false);
|
||||
|
@ -203,7 +202,7 @@ class CreatePost extends HookWidget {
|
|||
padding: const EdgeInsets.all(16),
|
||||
child: MarkdownText(
|
||||
bodyController.text,
|
||||
instanceUrl: selectedInstance.value,
|
||||
instanceHost: selectedInstance.value,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -7,7 +7,6 @@ import 'package:lemmy_api_client/lemmy_api_client.dart';
|
|||
import '../hooks/logged_in_action.dart';
|
||||
import '../hooks/memo_future.dart';
|
||||
import '../hooks/stores.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/more_icon.dart';
|
||||
import '../widgets/comment_section.dart';
|
||||
import '../widgets/post.dart';
|
||||
|
@ -17,24 +16,24 @@ import '../widgets/write_comment.dart';
|
|||
/// Displays a post with its comment section
|
||||
class FullPostPage extends HookWidget {
|
||||
final int id;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final PostView post;
|
||||
|
||||
FullPostPage({@required this.id, @required this.instanceUrl})
|
||||
FullPostPage({@required this.id, @required this.instanceHost})
|
||||
: assert(id != null),
|
||||
assert(instanceUrl != null),
|
||||
assert(instanceHost != null),
|
||||
post = null;
|
||||
FullPostPage.fromPostView(this.post)
|
||||
: id = post.id,
|
||||
instanceUrl = post.instanceUrl;
|
||||
instanceHost = post.instanceHost;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final accStore = useAccountsStore();
|
||||
final fullPostSnap = useMemoFuture(() => LemmyApi(instanceUrl)
|
||||
final fullPostSnap = useMemoFuture(() => LemmyApi(instanceHost)
|
||||
.v1
|
||||
.getPost(id: id, auth: accStore.defaultTokenFor(instanceUrl)?.raw));
|
||||
final loggedInAction = useLoggedInAction(instanceUrl);
|
||||
.getPost(id: id, auth: accStore.defaultTokenFor(instanceHost)?.raw));
|
||||
final loggedInAction = useLoggedInAction(instanceHost);
|
||||
final newComments = useState(const <CommentView>[]);
|
||||
|
||||
// FALLBACK VIEW
|
||||
|
|
|
@ -118,10 +118,10 @@ class HomeTab extends HookWidget {
|
|||
? () => showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) =>
|
||||
AddAccountPage(instanceUrl: instance))
|
||||
AddAccountPage(instanceHost: instance))
|
||||
: () => pop(_SelectedList(
|
||||
listingType: PostListingType.subscribed,
|
||||
instanceUrl: instance,
|
||||
instanceHost: instance,
|
||||
)),
|
||||
leading: SizedBox(width: 20),
|
||||
),
|
||||
|
@ -129,7 +129,7 @@ class HomeTab extends HookWidget {
|
|||
title: Text('All'),
|
||||
onTap: () => pop(_SelectedList(
|
||||
listingType: PostListingType.all,
|
||||
instanceUrl: instance,
|
||||
instanceHost: instance,
|
||||
)),
|
||||
leading: SizedBox(width: 20),
|
||||
),
|
||||
|
@ -149,9 +149,9 @@ class HomeTab extends HookWidget {
|
|||
final first = selectedList.value.listingType == PostListingType.subscribed
|
||||
? 'Subscribed'
|
||||
: 'All';
|
||||
final last = selectedList.value.instanceUrl == null
|
||||
final last = selectedList.value.instanceHost == null
|
||||
? ''
|
||||
: '@${selectedList.value.instanceUrl}';
|
||||
: '@${selectedList.value.instanceHost}';
|
||||
return '$first$last';
|
||||
}();
|
||||
|
||||
|
@ -256,12 +256,12 @@ class InfiniteHomeList extends HookWidget {
|
|||
}();
|
||||
|
||||
final futures =
|
||||
instances.map((instanceUrl) => LemmyApi(instanceUrl).v1.getPosts(
|
||||
instances.map((instanceHost) => LemmyApi(instanceHost).v1.getPosts(
|
||||
type: listingType,
|
||||
sort: sort,
|
||||
page: page,
|
||||
limit: limit,
|
||||
auth: accStore.defaultTokenFor(instanceUrl)?.raw,
|
||||
auth: accStore.defaultTokenFor(instanceHost)?.raw,
|
||||
));
|
||||
final posts = await Future.wait(futures);
|
||||
final newPosts = <PostView>[];
|
||||
|
@ -277,13 +277,13 @@ class InfiniteHomeList extends HookWidget {
|
|||
}
|
||||
|
||||
Future<List<PostView>> Function(int, int) fetcherFromInstance(
|
||||
String instanceUrl, PostListingType listingType, SortType sort) =>
|
||||
(page, batchSize) => LemmyApi(instanceUrl).v1.getPosts(
|
||||
String instanceHost, PostListingType listingType, SortType sort) =>
|
||||
(page, batchSize) => LemmyApi(instanceHost).v1.getPosts(
|
||||
type: listingType,
|
||||
sort: sort,
|
||||
page: page,
|
||||
limit: batchSize,
|
||||
auth: accStore.defaultTokenFor(instanceUrl)?.raw,
|
||||
auth: accStore.defaultTokenFor(instanceHost)?.raw,
|
||||
);
|
||||
|
||||
return InfiniteScroll<PostView>(
|
||||
|
@ -303,11 +303,11 @@ class InfiniteHomeList extends HookWidget {
|
|||
],
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
fetchMore: selectedList.instanceUrl == null
|
||||
fetchMore: selectedList.instanceHost == null
|
||||
? (page, limit) =>
|
||||
generalFetcher(page, limit, sort.value, selectedList.listingType)
|
||||
: fetcherFromInstance(
|
||||
selectedList.instanceUrl,
|
||||
selectedList.instanceHost,
|
||||
selectedList.listingType,
|
||||
sort.value,
|
||||
),
|
||||
|
@ -318,13 +318,13 @@ class InfiniteHomeList extends HookWidget {
|
|||
}
|
||||
|
||||
class _SelectedList {
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final PostListingType listingType;
|
||||
_SelectedList({
|
||||
@required this.listingType,
|
||||
this.instanceUrl,
|
||||
this.instanceHost,
|
||||
});
|
||||
|
||||
String toString() =>
|
||||
'SelectedList({instanceUrl: $instanceUrl, listingType: $listingType})';
|
||||
'SelectedList({instanceHost: $instanceHost, listingType: $listingType})';
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||
|
||||
import '../hooks/stores.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/goto.dart';
|
||||
import '../util/more_icon.dart';
|
||||
import '../util/text_color.dart';
|
||||
|
@ -20,18 +19,18 @@ import 'users_list.dart';
|
|||
|
||||
/// Displays posts, comments, and general info about the given instance
|
||||
class InstancePage extends HookWidget {
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final Future<FullSiteView> siteFuture;
|
||||
final Future<List<CommunityView>> communitiesFuture;
|
||||
|
||||
void _share() =>
|
||||
Share.text('Share instance', 'https://$instanceUrl', 'text/plain');
|
||||
Share.text('Share instance', 'https://$instanceHost', 'text/plain');
|
||||
|
||||
InstancePage({@required this.instanceUrl})
|
||||
: assert(instanceUrl != null),
|
||||
siteFuture = LemmyApi(instanceUrl).v1.getSite(),
|
||||
InstancePage({@required this.instanceHost})
|
||||
: assert(instanceHost != null),
|
||||
siteFuture = LemmyApi(instanceHost).v1.getSite(),
|
||||
communitiesFuture =
|
||||
LemmyApi(instanceUrl).v1.listCommunities(sort: SortType.hot);
|
||||
LemmyApi(instanceHost).v1.listCommunities(sort: SortType.hot);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -70,7 +69,7 @@ class InstancePage extends HookWidget {
|
|||
|
||||
void _openMoreMenu(BuildContext c) {
|
||||
showInfoTablePopup(context, {
|
||||
'url': instanceUrl,
|
||||
'url': instanceHost,
|
||||
'creator': '@${site.site.creatorName}',
|
||||
'version': site.version,
|
||||
'enableDownvotes': site.site.enableDownvotes,
|
||||
|
@ -132,7 +131,7 @@ class InstancePage extends HookWidget {
|
|||
),
|
||||
Text(site.site.name,
|
||||
style: theme.textTheme.headline6),
|
||||
Text(instanceUrl, style: theme.textTheme.caption)
|
||||
Text(instanceHost, style: theme.textTheme.caption)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -159,26 +158,26 @@ class InstancePage extends HookWidget {
|
|||
children: [
|
||||
InfinitePostList(
|
||||
fetcher: (page, batchSize, sort) =>
|
||||
LemmyApi(instanceUrl).v1.getPosts(
|
||||
LemmyApi(instanceHost).v1.getPosts(
|
||||
// TODO: switch between all and subscribed
|
||||
type: PostListingType.all,
|
||||
sort: sort,
|
||||
limit: batchSize,
|
||||
page: page,
|
||||
auth: accStore.defaultTokenFor(instanceUrl)?.raw,
|
||||
auth: accStore.defaultTokenFor(instanceHost)?.raw,
|
||||
)),
|
||||
InfiniteCommentList(
|
||||
fetcher: (page, batchSize, sort) =>
|
||||
LemmyApi(instanceUrl).v1.getComments(
|
||||
LemmyApi(instanceHost).v1.getComments(
|
||||
type: CommentListingType.all,
|
||||
sort: sort,
|
||||
limit: batchSize,
|
||||
page: page,
|
||||
auth: accStore.defaultTokenFor(instanceUrl)?.raw,
|
||||
auth: accStore.defaultTokenFor(instanceHost)?.raw,
|
||||
)),
|
||||
_AboutTab(site,
|
||||
communitiesFuture: communitiesFuture,
|
||||
instanceUrl: instanceUrl),
|
||||
instanceHost: instanceHost),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -211,12 +210,12 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
|||
class _AboutTab extends HookWidget {
|
||||
final FullSiteView site;
|
||||
final Future<List<CommunityView>> communitiesFuture;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
|
||||
const _AboutTab(this.site,
|
||||
{@required this.communitiesFuture, @required this.instanceUrl})
|
||||
{@required this.communitiesFuture, @required this.instanceHost})
|
||||
: assert(communitiesFuture != null),
|
||||
assert(instanceUrl != null);
|
||||
assert(instanceHost != null);
|
||||
|
||||
void goToUser(int id) {
|
||||
print('GO TO USER $id');
|
||||
|
@ -245,11 +244,11 @@ class _AboutTab extends HookWidget {
|
|||
context,
|
||||
(_) => CommunitiesListPage(
|
||||
fetcher: (page, batchSize, sortType) =>
|
||||
LemmyApi(instanceUrl).v1.listCommunities(
|
||||
LemmyApi(instanceHost).v1.listCommunities(
|
||||
sort: sortType,
|
||||
limit: batchSize,
|
||||
page: page,
|
||||
auth: accStore.defaultTokenFor(instanceUrl)?.raw,
|
||||
auth: accStore.defaultTokenFor(instanceHost)?.raw,
|
||||
),
|
||||
title: 'Communities of ${site.site.name}',
|
||||
),
|
||||
|
@ -265,7 +264,7 @@ class _AboutTab extends HookWidget {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
child: MarkdownText(
|
||||
site.site.description,
|
||||
instanceUrl: instanceUrl,
|
||||
instanceHost: instanceHost,
|
||||
),
|
||||
),
|
||||
_Divider(),
|
||||
|
@ -296,7 +295,7 @@ class _AboutTab extends HookWidget {
|
|||
if (commSnap.hasData)
|
||||
...commSnap.data.take(6).map((e) => ListTile(
|
||||
onTap: () =>
|
||||
goToCommunity.byId(context, e.instanceUrl, e.id),
|
||||
goToCommunity.byId(context, e.instanceHost, e.id),
|
||||
title: Text(e.name),
|
||||
leading: e.icon != null
|
||||
? CachedNetworkImage(
|
||||
|
@ -345,7 +344,7 @@ class _AboutTab extends HookWidget {
|
|||
? '@${e.name}'
|
||||
: e.preferredUsername),
|
||||
subtitle: e.bio != null
|
||||
? MarkdownText(e.bio, instanceUrl: instanceUrl)
|
||||
? MarkdownText(e.bio, instanceHost: instanceHost)
|
||||
: null,
|
||||
onTap: () => goToUser(e.id),
|
||||
leading: e.avatar != null
|
||||
|
|
|
@ -85,9 +85,9 @@ class UserProfileTab extends HookWidget {
|
|||
builder: (ctx) {
|
||||
final userTags = <String>[];
|
||||
|
||||
accountsStore.tokens.forEach((instanceUrl, value) {
|
||||
accountsStore.tokens.forEach((instanceHost, value) {
|
||||
value.forEach((username, _) {
|
||||
userTags.add('$username@$instanceUrl');
|
||||
userTags.add('$username@$instanceHost');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -100,7 +100,7 @@ class UserProfileTab extends HookWidget {
|
|||
value: tag,
|
||||
title: Text(tag),
|
||||
groupValue: '${accountsStore.defaultUsername}'
|
||||
'@${accountsStore.defaultInstanceUrl}',
|
||||
'@${accountsStore.defaultInstanceHost}',
|
||||
onChanged: (selected) {
|
||||
final userTag = selected.split('@');
|
||||
accountsStore.setDefaultAccount(
|
||||
|
@ -119,7 +119,7 @@ class UserProfileTab extends HookWidget {
|
|||
),
|
||||
body: UserProfile(
|
||||
userId: accountsStore.defaultToken.payload.id,
|
||||
instanceUrl: accountsStore.defaultInstanceUrl,
|
||||
instanceHost: accountsStore.defaultInstanceHost,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -99,12 +99,12 @@ class AccountsConfigPage extends HookWidget {
|
|||
final theme = Theme.of(context);
|
||||
final accountsStore = useAccountsStore();
|
||||
|
||||
removeInstanceDialog(String instanceUrl) async {
|
||||
removeInstanceDialog(String instanceHost) async {
|
||||
if (await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Remove instance?'),
|
||||
content: Text('Are you sure you want to remove $instanceUrl?'),
|
||||
content: Text('Are you sure you want to remove $instanceHost?'),
|
||||
actions: [
|
||||
FlatButton(
|
||||
child: Text('no'),
|
||||
|
@ -118,17 +118,17 @@ class AccountsConfigPage extends HookWidget {
|
|||
),
|
||||
) ??
|
||||
false) {
|
||||
accountsStore.removeInstance(instanceUrl);
|
||||
accountsStore.removeInstance(instanceHost);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> removeUserDialog(String instanceUrl, String username) async {
|
||||
Future<void> removeUserDialog(String instanceHost, String username) async {
|
||||
if (await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Remove user?'),
|
||||
content: Text(
|
||||
'Are you sure you want to remove $username@$instanceUrl?'),
|
||||
'Are you sure you want to remove $username@$instanceHost?'),
|
||||
actions: [
|
||||
FlatButton(
|
||||
child: Text('no'),
|
||||
|
@ -142,7 +142,7 @@ class AccountsConfigPage extends HookWidget {
|
|||
),
|
||||
) ??
|
||||
false) {
|
||||
accountsStore.removeAccount(instanceUrl, username);
|
||||
accountsStore.removeAccount(instanceHost, username);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ class AccountsConfigPage extends HookWidget {
|
|||
onTap: () => showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) =>
|
||||
AddAccountPage(instanceUrl: accountsStore.instances.last)),
|
||||
AddAccountPage(instanceHost: accountsStore.instances.last)),
|
||||
),
|
||||
SpeedDialChild(
|
||||
child: Icon(Icons.dns),
|
||||
|
@ -263,7 +263,7 @@ class AccountsConfigPage extends HookWidget {
|
|||
onTap: () {
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) => AddAccountPage(instanceUrl: entry.key));
|
||||
builder: (_) => AddAccountPage(instanceHost: entry.key));
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -8,20 +8,20 @@ import '../widgets/user_profile.dart';
|
|||
/// Page showing posts, comments, and general info about a user.
|
||||
class UserPage extends HookWidget {
|
||||
final int userId;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final Future<UserDetails> _userDetails;
|
||||
|
||||
UserPage({@required this.userId, @required this.instanceUrl})
|
||||
UserPage({@required this.userId, @required this.instanceHost})
|
||||
: assert(userId != null),
|
||||
assert(instanceUrl != null),
|
||||
_userDetails = LemmyApi(instanceUrl).v1.getUserDetails(
|
||||
assert(instanceHost != null),
|
||||
_userDetails = LemmyApi(instanceHost).v1.getUserDetails(
|
||||
userId: userId, savedOnly: true, sort: SortType.active);
|
||||
|
||||
UserPage.fromName({@required this.instanceUrl, @required String username})
|
||||
: assert(instanceUrl != null),
|
||||
UserPage.fromName({@required this.instanceHost, @required String username})
|
||||
: assert(instanceHost != null),
|
||||
assert(username != null),
|
||||
userId = null,
|
||||
_userDetails = LemmyApi(instanceUrl).v1.getUserDetails(
|
||||
_userDetails = LemmyApi(instanceHost).v1.getUserDetails(
|
||||
username: username, savedOnly: true, sort: SortType.active);
|
||||
|
||||
@override
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:cached_network_image/cached_network_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||
|
||||
import '../util/extensions/api.dart';
|
||||
import '../widgets/markdown_text.dart';
|
||||
|
||||
/// Infinite list of Users fetched by the given fetcher
|
||||
|
@ -42,7 +41,7 @@ class UsersListPage extends StatelessWidget {
|
|||
opacity: 0.5,
|
||||
child: MarkdownText(
|
||||
users[i].bio,
|
||||
instanceUrl: users[i].instanceUrl,
|
||||
instanceHost: users[i].instanceHost,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
|
|
|
@ -12,16 +12,16 @@ class AccountsStore extends ChangeNotifier {
|
|||
/// Map containing JWT tokens of specific users.
|
||||
/// If a token is in this map, the user is considered logged in
|
||||
/// for that account.
|
||||
/// `tokens['instanceUrl']['username']`
|
||||
/// `tokens['instanceHost']['username']`
|
||||
HashMap<String, HashMap<String, Jwt>> get tokens => _tokens;
|
||||
HashMap<String, HashMap<String, Jwt>> _tokens;
|
||||
|
||||
/// default account for a given instance
|
||||
/// map where keys are instanceUrls and values are usernames
|
||||
/// map where keys are instanceHosts and values are usernames
|
||||
HashMap<String, String> _defaultAccounts;
|
||||
|
||||
/// default account for the app
|
||||
/// It is in a form of `username@instanceUrl`
|
||||
/// It is in a form of `username@instanceHost`
|
||||
String _defaultAccount;
|
||||
|
||||
Future<void> load() async {
|
||||
|
@ -87,12 +87,12 @@ class AccountsStore extends ChangeNotifier {
|
|||
}
|
||||
|
||||
// set local defaults
|
||||
for (final instanceUrl in instances) {
|
||||
for (final instanceHost in instances) {
|
||||
// if this instance is not in defaults
|
||||
if (!_defaultAccounts.containsKey(instanceUrl)) {
|
||||
if (!_defaultAccounts.containsKey(instanceHost)) {
|
||||
// select first account in this instance, if any
|
||||
if (!isAnonymousFor(instanceUrl)) {
|
||||
setDefaultAccountFor(instanceUrl, tokens[instanceUrl].keys.first);
|
||||
if (!isAnonymousFor(instanceHost)) {
|
||||
setDefaultAccountFor(instanceHost, tokens[instanceHost].keys.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,10 +100,10 @@ class AccountsStore extends ChangeNotifier {
|
|||
// set global default
|
||||
if (_defaultAccount == null) {
|
||||
// select first account of first instance
|
||||
for (final instanceUrl in instances) {
|
||||
for (final instanceHost in instances) {
|
||||
// select first account in this instance, if any
|
||||
if (!isAnonymousFor(instanceUrl)) {
|
||||
setDefaultAccount(instanceUrl, tokens[instanceUrl].keys.first);
|
||||
if (!isAnonymousFor(instanceHost)) {
|
||||
setDefaultAccount(instanceHost, tokens[instanceHost].keys.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ class AccountsStore extends ChangeNotifier {
|
|||
return _defaultAccount.split('@')[0];
|
||||
}
|
||||
|
||||
String get defaultInstanceUrl {
|
||||
String get defaultInstanceHost {
|
||||
if (_defaultAccount == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -125,12 +125,12 @@ class AccountsStore extends ChangeNotifier {
|
|||
return _defaultAccount.split('@')[1];
|
||||
}
|
||||
|
||||
String defaultUsernameFor(String instanceUrl) {
|
||||
if (isAnonymousFor(instanceUrl)) {
|
||||
String defaultUsernameFor(String instanceHost) {
|
||||
if (isAnonymousFor(instanceHost)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return _defaultAccounts[instanceUrl];
|
||||
return _defaultAccounts[instanceHost];
|
||||
}
|
||||
|
||||
Jwt get defaultToken {
|
||||
|
@ -142,25 +142,25 @@ class AccountsStore extends ChangeNotifier {
|
|||
return tokens[userTag[1]][userTag[0]];
|
||||
}
|
||||
|
||||
Jwt defaultTokenFor(String instanceUrl) {
|
||||
if (isAnonymousFor(instanceUrl)) {
|
||||
Jwt defaultTokenFor(String instanceHost) {
|
||||
if (isAnonymousFor(instanceHost)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return tokens[instanceUrl][_defaultAccounts[instanceUrl]];
|
||||
return tokens[instanceHost][_defaultAccounts[instanceHost]];
|
||||
}
|
||||
|
||||
/// sets globally default account
|
||||
void setDefaultAccount(String instanceUrl, String username) {
|
||||
_defaultAccount = '$username@$instanceUrl';
|
||||
void setDefaultAccount(String instanceHost, String username) {
|
||||
_defaultAccount = '$username@$instanceHost';
|
||||
|
||||
notifyListeners();
|
||||
save();
|
||||
}
|
||||
|
||||
/// sets default account for given instance
|
||||
void setDefaultAccountFor(String instanceUrl, String username) {
|
||||
_defaultAccounts[instanceUrl] = username;
|
||||
void setDefaultAccountFor(String instanceHost, String username) {
|
||||
_defaultAccounts[instanceHost] = username;
|
||||
|
||||
notifyListeners();
|
||||
save();
|
||||
|
@ -168,12 +168,12 @@ class AccountsStore extends ChangeNotifier {
|
|||
|
||||
/// An instance is considered anonymous if it was not
|
||||
/// added or there are no accounts assigned to it.
|
||||
bool isAnonymousFor(String instanceUrl) {
|
||||
if (!instances.contains(instanceUrl)) {
|
||||
bool isAnonymousFor(String instanceHost) {
|
||||
if (!instances.contains(instanceHost)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return tokens[instanceUrl].isEmpty;
|
||||
return tokens[instanceHost].isEmpty;
|
||||
}
|
||||
|
||||
/// `true` if no added instance has an account assigned to it
|
||||
|
@ -190,15 +190,15 @@ class AccountsStore extends ChangeNotifier {
|
|||
/// if it's the first account for an instance the account is
|
||||
/// set as default for that instance
|
||||
Future<void> addAccount(
|
||||
String instanceUrl,
|
||||
String instanceHost,
|
||||
String usernameOrEmail,
|
||||
String password,
|
||||
) async {
|
||||
if (!instances.contains(instanceUrl)) {
|
||||
if (!instances.contains(instanceHost)) {
|
||||
throw Exception('No such instance was added');
|
||||
}
|
||||
|
||||
final lemmy = LemmyApi(instanceUrl).v1;
|
||||
final lemmy = LemmyApi(instanceHost).v1;
|
||||
|
||||
final token = await lemmy.login(
|
||||
usernameOrEmail: usernameOrEmail,
|
||||
|
@ -207,7 +207,7 @@ class AccountsStore extends ChangeNotifier {
|
|||
final userData =
|
||||
await lemmy.getSite(auth: token.raw).then((value) => value.myUser);
|
||||
|
||||
tokens[instanceUrl][userData.name] = token;
|
||||
tokens[instanceHost][userData.name] = token;
|
||||
|
||||
_assignDefaultAccounts();
|
||||
notifyListeners();
|
||||
|
@ -218,23 +218,23 @@ class AccountsStore extends ChangeNotifier {
|
|||
/// Additionally makes a test `GET /site` request to check if the instance exists.
|
||||
/// Check is skipped when [assumeValid] is `true`
|
||||
Future<void> addInstance(
|
||||
String instanceUrl, {
|
||||
String instanceHost, {
|
||||
bool assumeValid = false,
|
||||
}) async {
|
||||
if (instances.contains(instanceUrl)) {
|
||||
if (instances.contains(instanceHost)) {
|
||||
throw Exception('This instance has already been added');
|
||||
}
|
||||
|
||||
if (!assumeValid) {
|
||||
try {
|
||||
await LemmyApi(instanceUrl).v1.getSite();
|
||||
await LemmyApi(instanceHost).v1.getSite();
|
||||
// ignore: avoid_catches_without_on_clauses
|
||||
} catch (_) {
|
||||
throw Exception('This instance seems to not exist');
|
||||
}
|
||||
}
|
||||
|
||||
tokens[instanceUrl] = HashMap();
|
||||
tokens[instanceHost] = HashMap();
|
||||
|
||||
_assignDefaultAccounts();
|
||||
notifyListeners();
|
||||
|
@ -242,16 +242,16 @@ class AccountsStore extends ChangeNotifier {
|
|||
}
|
||||
|
||||
/// This also removes all accounts assigned to this instance
|
||||
void removeInstance(String instanceUrl) {
|
||||
tokens.remove(instanceUrl);
|
||||
void removeInstance(String instanceHost) {
|
||||
tokens.remove(instanceHost);
|
||||
|
||||
_assignDefaultAccounts();
|
||||
notifyListeners();
|
||||
save();
|
||||
}
|
||||
|
||||
void removeAccount(String instanceUrl, String username) {
|
||||
tokens[instanceUrl].remove(username);
|
||||
void removeAccount(String instanceHost, String username) {
|
||||
tokens[instanceHost].remove(username);
|
||||
|
||||
_assignDefaultAccounts();
|
||||
notifyListeners();
|
||||
|
|
|
@ -15,7 +15,7 @@ import 'util/goto.dart';
|
|||
Future<void> linkLauncher({
|
||||
@required BuildContext context,
|
||||
@required String url,
|
||||
@required String instanceUrl,
|
||||
@required String instanceHost,
|
||||
}) async {
|
||||
push(Widget Function() builder) {
|
||||
goTo(context, (c) => builder());
|
||||
|
@ -28,14 +28,14 @@ Future<void> linkLauncher({
|
|||
|
||||
// CHECK IF LINK TO USER
|
||||
if (url.startsWith('/u/')) {
|
||||
return push(
|
||||
() => UserPage.fromName(instanceUrl: instanceUrl, username: chonks[2]));
|
||||
return push(() =>
|
||||
UserPage.fromName(instanceHost: instanceHost, username: chonks[2]));
|
||||
}
|
||||
|
||||
// CHECK IF LINK TO COMMUNITY
|
||||
if (url.startsWith('/c/')) {
|
||||
return push(() => CommunityPage.fromName(
|
||||
communityName: chonks[2], instanceUrl: instanceUrl));
|
||||
communityName: chonks[2], instanceHost: instanceHost));
|
||||
}
|
||||
|
||||
// CHECK IF REDIRECTS TO A PAGE ON ONE OF ADDED INSTANCES
|
||||
|
@ -48,7 +48,7 @@ Future<void> linkLauncher({
|
|||
|
||||
if (matchedInstance != null && instances.any((e) => e == match.group(1))) {
|
||||
if (rest.isEmpty || rest == '/') {
|
||||
return push(() => InstancePage(instanceUrl: matchedInstance));
|
||||
return push(() => InstancePage(instanceHost: matchedInstance));
|
||||
}
|
||||
final split = rest.split('/');
|
||||
switch (split[1]) {
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||
|
||||
import '../cleanup_url.dart';
|
||||
|
||||
// Extensions to lemmy api objects which give a [.instanceUrl] getter
|
||||
// allowing for a convenient way of knowing from which instance did this
|
||||
// object come from
|
||||
|
||||
// TODO: change it to something more robust? regex?
|
||||
|
||||
extension GetInstanceCommunityView on CommunityView {
|
||||
String get instanceUrl => _extract(actorId);
|
||||
}
|
||||
|
||||
extension GetInstanceUserView on UserView {
|
||||
String get instanceUrl => _extract(actorId);
|
||||
}
|
||||
|
||||
extension GetInstanceCommunityModeratorView on CommunityModeratorView {
|
||||
String get instanceUrl => _extract(userActorId);
|
||||
}
|
||||
|
||||
extension GetInstancePostView on PostView {
|
||||
String get instanceUrl => _extract(apId);
|
||||
}
|
||||
|
||||
extension GetInstanceUser on User {
|
||||
String get instanceUrl => _extract(actorId);
|
||||
}
|
||||
|
||||
extension GetInstanceCommentView on CommentView {
|
||||
String get instanceUrl => _extract(apId);
|
||||
}
|
||||
|
||||
String _extract(String s) => cleanUpUrl(s.split('/')[2]);
|
|
@ -25,41 +25,42 @@ Future<dynamic> goToReplace(
|
|||
builder: builder,
|
||||
));
|
||||
|
||||
void goToInstance(BuildContext context, String instanceUrl) =>
|
||||
goTo(context, (context) => InstancePage(instanceUrl: instanceUrl));
|
||||
void goToInstance(BuildContext context, String instanceHost) =>
|
||||
goTo(context, (context) => InstancePage(instanceHost: instanceHost));
|
||||
|
||||
// ignore: camel_case_types
|
||||
abstract class goToCommunity {
|
||||
/// Navigates to `CommunityPage`
|
||||
static void byId(BuildContext context, String instanceUrl, int communityId) =>
|
||||
static void byId(
|
||||
BuildContext context, String instanceHost, int communityId) =>
|
||||
goTo(
|
||||
context,
|
||||
(context) => CommunityPage.fromId(
|
||||
instanceUrl: instanceUrl, communityId: communityId),
|
||||
instanceHost: instanceHost, communityId: communityId),
|
||||
);
|
||||
|
||||
static void byName(
|
||||
BuildContext context, String instanceUrl, String communityName) =>
|
||||
BuildContext context, String instanceHost, String communityName) =>
|
||||
goTo(
|
||||
context,
|
||||
(context) => CommunityPage.fromName(
|
||||
instanceUrl: instanceUrl, communityName: communityName),
|
||||
instanceHost: instanceHost, communityName: communityName),
|
||||
);
|
||||
}
|
||||
|
||||
// ignore: camel_case_types
|
||||
abstract class goToUser {
|
||||
static void byId(BuildContext context, String instanceUrl, int userId) =>
|
||||
static void byId(BuildContext context, String instanceHost, int userId) =>
|
||||
goTo(context,
|
||||
(context) => UserPage(instanceUrl: instanceUrl, userId: userId));
|
||||
(context) => UserPage(instanceHost: instanceHost, userId: userId));
|
||||
|
||||
static void byName(
|
||||
BuildContext context, String instanceUrl, String userName) =>
|
||||
BuildContext context, String instanceHost, String userName) =>
|
||||
throw UnimplementedError('need to create UserProfile constructor first');
|
||||
}
|
||||
|
||||
void goToPost(BuildContext context, String instanceUrl, int postId) => goTo(
|
||||
context, (context) => FullPostPage(instanceUrl: instanceUrl, id: postId));
|
||||
void goToPost(BuildContext context, String instanceHost, int postId) => goTo(
|
||||
context, (context) => FullPostPage(instanceHost: instanceHost, id: postId));
|
||||
|
||||
void goToMedia(BuildContext context, String url) => Navigator.push(
|
||||
context,
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
String pathToPictrs(String instanceUrl, String imgId) =>
|
||||
'https://$instanceUrl/pictrs/image/$imgId';
|
||||
String pathToPictrs(String instanceHost, String imgId) =>
|
||||
'https://$instanceHost/pictrs/image/$imgId';
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'package:url_launcher/url_launcher.dart' as ul;
|
|||
import '../comment_tree.dart';
|
||||
import '../hooks/delayed_loading.dart';
|
||||
import '../hooks/logged_in_action.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/goto.dart';
|
||||
import '../util/intl.dart';
|
||||
import '../util/text_color.dart';
|
||||
|
@ -75,7 +74,7 @@ class Comment extends HookWidget {
|
|||
final isDeleted = useState(commentTree.comment.deleted);
|
||||
final delayedVoting = useDelayedLoading();
|
||||
final delayedDeletion = useDelayedLoading();
|
||||
final loggedInAction = useLoggedInAction(commentTree.comment.instanceUrl);
|
||||
final loggedInAction = useLoggedInAction(commentTree.comment.instanceHost);
|
||||
final newReplies = useState(const <CommentTree>[]);
|
||||
|
||||
final comment = commentTree.comment;
|
||||
|
@ -237,7 +236,7 @@ class Comment extends HookWidget {
|
|||
: Text(commentTree.comment.content)
|
||||
: MarkdownText(
|
||||
commentTree.comment.content,
|
||||
instanceUrl: commentTree.comment.instanceUrl,
|
||||
instanceHost: commentTree.comment.instanceHost,
|
||||
selectable: selectable.value,
|
||||
));
|
||||
}
|
||||
|
@ -305,7 +304,7 @@ class Comment extends HookWidget {
|
|||
padding: const EdgeInsets.only(right: 5),
|
||||
child: InkWell(
|
||||
onTap: () => goToUser.byId(
|
||||
context, comment.instanceUrl, comment.creatorId),
|
||||
context, comment.instanceHost, comment.creatorId),
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: comment.creatorAvatar,
|
||||
height: 20,
|
||||
|
@ -329,7 +328,7 @@ class Comment extends HookWidget {
|
|||
color: Theme.of(context).accentColor,
|
||||
)),
|
||||
onTap: () => goToUser.byId(
|
||||
context, comment.instanceUrl, comment.creatorId),
|
||||
context, comment.instanceHost, comment.creatorId),
|
||||
),
|
||||
if (isOP) _CommentTag('OP', Theme.of(context).accentColor),
|
||||
if (comment.banned) _CommentTag('BANNED', Colors.red),
|
||||
|
@ -394,12 +393,12 @@ class _SaveComment extends HookWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loggedInAction = useLoggedInAction(comment.instanceUrl);
|
||||
final loggedInAction = useLoggedInAction(comment.instanceHost);
|
||||
final isSaved = useState(comment.saved ?? false);
|
||||
final delayed = useDelayedLoading(const Duration(milliseconds: 500));
|
||||
|
||||
handleSave(Jwt token) async {
|
||||
final api = LemmyApi(comment.instanceUrl).v1;
|
||||
final api = LemmyApi(comment.instanceHost).v1;
|
||||
|
||||
delayed.start();
|
||||
try {
|
||||
|
|
|
@ -8,12 +8,13 @@ import 'fullscreenable_image.dart';
|
|||
|
||||
/// A Markdown renderer with link/image handling
|
||||
class MarkdownText extends StatelessWidget {
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final String text;
|
||||
final bool selectable;
|
||||
|
||||
MarkdownText(this.text, {@required this.instanceUrl, this.selectable = false})
|
||||
: assert(instanceUrl != null);
|
||||
MarkdownText(this.text,
|
||||
{@required this.instanceHost, this.selectable = false})
|
||||
: assert(instanceHost != null);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => MarkdownBody(
|
||||
|
@ -21,7 +22,7 @@ class MarkdownText extends StatelessWidget {
|
|||
data: text,
|
||||
extensionSet: md.ExtensionSet.gitHubWeb,
|
||||
onTapLink: (href) {
|
||||
linkLauncher(context: context, url: href, instanceUrl: instanceUrl)
|
||||
linkLauncher(context: context, url: href, instanceHost: instanceHost)
|
||||
.catchError((e) => Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
|
|
|
@ -13,7 +13,6 @@ import '../hooks/delayed_loading.dart';
|
|||
import '../hooks/logged_in_action.dart';
|
||||
import '../pages/full_post.dart';
|
||||
import '../url_launcher.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/goto.dart';
|
||||
import '../util/more_icon.dart';
|
||||
import 'bottom_modal.dart';
|
||||
|
@ -49,10 +48,10 @@ MediaType whatType(String url) {
|
|||
/// A post overview card
|
||||
class Post extends HookWidget {
|
||||
final PostView post;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final bool fullPost;
|
||||
|
||||
Post(this.post, {this.fullPost = false}) : instanceUrl = post.instanceUrl;
|
||||
Post(this.post, {this.fullPost = false}) : instanceHost = post.instanceHost;
|
||||
|
||||
// == ACTIONS ==
|
||||
|
||||
|
@ -103,8 +102,8 @@ class Post extends HookWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
void _openLink() =>
|
||||
linkLauncher(context: context, url: post.url, instanceUrl: instanceUrl);
|
||||
void _openLink() => linkLauncher(
|
||||
context: context, url: post.url, instanceHost: instanceHost);
|
||||
|
||||
final urlDomain = () {
|
||||
if (whatType(post.url) == MediaType.none) return null;
|
||||
|
@ -127,7 +126,7 @@ class Post extends HookWidget {
|
|||
padding: const EdgeInsets.only(right: 10),
|
||||
child: InkWell(
|
||||
onTap: () => goToCommunity.byId(
|
||||
context, instanceUrl, post.communityId),
|
||||
context, instanceHost, post.communityId),
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: 40,
|
||||
|
@ -168,16 +167,16 @@ class Post extends HookWidget {
|
|||
style: TextStyle(fontWeight: FontWeight.w600),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => goToCommunity.byId(
|
||||
context, instanceUrl, post.communityId)),
|
||||
context, instanceHost, post.communityId)),
|
||||
TextSpan(
|
||||
text: '@',
|
||||
style: TextStyle(fontWeight: FontWeight.w300)),
|
||||
TextSpan(
|
||||
text: instanceUrl,
|
||||
text: instanceHost,
|
||||
style: TextStyle(fontWeight: FontWeight.w600),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap =
|
||||
() => goToInstance(context, instanceUrl)),
|
||||
() => goToInstance(context, instanceHost)),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
@ -199,7 +198,7 @@ class Post extends HookWidget {
|
|||
style: TextStyle(fontWeight: FontWeight.w600),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () => goToUser.byId(
|
||||
context, post.instanceUrl, post.creatorId),
|
||||
context, post.instanceHost, post.creatorId),
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
|
@ -377,10 +376,7 @@ class Post extends HookWidget {
|
|||
child: InkWell(
|
||||
onTap: fullPost
|
||||
? null
|
||||
: () => goTo(
|
||||
context,
|
||||
(context) =>
|
||||
FullPostPage.fromPostView(post)), //, instanceUrl, post.id),
|
||||
: () => goTo(context, (context) => FullPostPage.fromPostView(post)),
|
||||
child: Column(
|
||||
children: [
|
||||
info(),
|
||||
|
@ -394,7 +390,7 @@ class Post extends HookWidget {
|
|||
// TODO: trim content
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: MarkdownText(post.body, instanceUrl: instanceUrl)),
|
||||
child: MarkdownText(post.body, instanceHost: instanceHost)),
|
||||
actions(),
|
||||
],
|
||||
),
|
||||
|
@ -416,10 +412,10 @@ class _Voting extends HookWidget {
|
|||
final theme = Theme.of(context);
|
||||
final myVote = useState(post.myVote ?? VoteType.none);
|
||||
final loading = useDelayedLoading(Duration(milliseconds: 500));
|
||||
final loggedInAction = useLoggedInAction(post.instanceUrl);
|
||||
final loggedInAction = useLoggedInAction(post.instanceHost);
|
||||
|
||||
vote(VoteType vote, Jwt token) async {
|
||||
final api = LemmyApi(post.instanceUrl).v1;
|
||||
final api = LemmyApi(post.instanceHost).v1;
|
||||
|
||||
loading.start();
|
||||
try {
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:lemmy_api_client/lemmy_api_client.dart';
|
|||
|
||||
import '../hooks/delayed_loading.dart';
|
||||
import '../hooks/logged_in_action.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
|
||||
// TODO: sync this button between post and fullpost. the same with voting
|
||||
|
||||
|
@ -18,10 +17,10 @@ class SavePostButton extends HookWidget {
|
|||
final isSaved = useState(post.saved ?? false);
|
||||
final savedIcon = isSaved.value ? Icons.bookmark : Icons.bookmark_border;
|
||||
final loading = useDelayedLoading(Duration(milliseconds: 500));
|
||||
final loggedInAction = useLoggedInAction(post.instanceUrl);
|
||||
final loggedInAction = useLoggedInAction(post.instanceHost);
|
||||
|
||||
savePost(Jwt token) async {
|
||||
final api = LemmyApi(post.instanceUrl).v1;
|
||||
final api = LemmyApi(post.instanceHost).v1;
|
||||
|
||||
loading.start();
|
||||
try {
|
||||
|
|
|
@ -6,7 +6,6 @@ import 'package:lemmy_api_client/lemmy_api_client.dart';
|
|||
import 'package:timeago/timeago.dart' as timeago;
|
||||
|
||||
import '../hooks/stores.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import '../util/goto.dart';
|
||||
import '../util/intl.dart';
|
||||
import '../util/text_color.dart';
|
||||
|
@ -18,15 +17,15 @@ import 'sortable_infinite_list.dart';
|
|||
/// Shared widget of UserPage and ProfileTab
|
||||
class UserProfile extends HookWidget {
|
||||
final Future<UserDetails> _userDetails;
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
|
||||
UserProfile({@required int userId, @required this.instanceUrl})
|
||||
: _userDetails = LemmyApi(instanceUrl).v1.getUserDetails(
|
||||
UserProfile({@required int userId, @required this.instanceHost})
|
||||
: _userDetails = LemmyApi(instanceHost).v1.getUserDetails(
|
||||
userId: userId, savedOnly: false, sort: SortType.active);
|
||||
|
||||
UserProfile.fromUserDetails(UserDetails userDetails)
|
||||
: _userDetails = Future.value(userDetails),
|
||||
instanceUrl = userDetails.user.instanceUrl;
|
||||
instanceHost = userDetails.user.instanceHost;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -78,7 +77,7 @@ class UserProfile extends HookWidget {
|
|||
// TODO: first batch is already fetched on render
|
||||
// TODO: comment and post come from the same endpoint, could be shared
|
||||
InfinitePostList(
|
||||
fetcher: (page, batchSize, sort) => LemmyApi(instanceUrl)
|
||||
fetcher: (page, batchSize, sort) => LemmyApi(instanceHost)
|
||||
.v1
|
||||
.getUserDetails(
|
||||
userId: userView.id,
|
||||
|
@ -90,7 +89,7 @@ class UserProfile extends HookWidget {
|
|||
.then((val) => val.posts),
|
||||
),
|
||||
InfiniteCommentList(
|
||||
fetcher: (page, batchSize, sort) => LemmyApi(instanceUrl)
|
||||
fetcher: (page, batchSize, sort) => LemmyApi(instanceHost)
|
||||
.v1
|
||||
.getUserDetails(
|
||||
userId: userView.id,
|
||||
|
@ -222,9 +221,9 @@ class _UserOverview extends HookWidget {
|
|||
style: theme.textTheme.caption,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () => goToInstance(context, userView.instanceUrl),
|
||||
onTap: () => goToInstance(context, userView.instanceHost),
|
||||
child: Text(
|
||||
'${userView.instanceUrl}',
|
||||
'${userView.instanceHost}',
|
||||
style: theme.textTheme.caption,
|
||||
),
|
||||
)
|
||||
|
@ -324,12 +323,12 @@ class _AboutTab extends HookWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final instanceUrl = userDetails.user.instanceUrl;
|
||||
final instanceHost = userDetails.user.instanceHost;
|
||||
|
||||
final accStore = useAccountsStore();
|
||||
|
||||
final isOwnedAccount = accStore.loggedInInstances.contains(instanceUrl) &&
|
||||
accStore.tokens[instanceUrl].containsKey(userDetails.user.name);
|
||||
final isOwnedAccount = accStore.loggedInInstances.contains(instanceHost) &&
|
||||
accStore.tokens[instanceHost].containsKey(userDetails.user.name);
|
||||
|
||||
const wallPadding = EdgeInsets.symmetric(horizontal: 15);
|
||||
|
||||
|
@ -341,7 +340,7 @@ class _AboutTab extends HookWidget {
|
|||
|
||||
communityTile(String name, String icon, int id) => ListTile(
|
||||
dense: true,
|
||||
onTap: () => goToCommunity.byId(context, instanceUrl, id),
|
||||
onTap: () => goToCommunity.byId(context, instanceHost, id),
|
||||
title: Text('!$name'),
|
||||
leading: icon != null
|
||||
? CachedNetworkImage(
|
||||
|
@ -379,8 +378,8 @@ class _AboutTab extends HookWidget {
|
|||
if (userDetails.user.bio != null) ...[
|
||||
Padding(
|
||||
padding: wallPadding,
|
||||
child:
|
||||
MarkdownText(userDetails.user.bio, instanceUrl: instanceUrl)),
|
||||
child: MarkdownText(userDetails.user.bio,
|
||||
instanceHost: instanceHost)),
|
||||
divider,
|
||||
],
|
||||
if (userDetails.moderates.isNotEmpty) ...[
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:lemmy_api_client/lemmy_api_client.dart';
|
|||
|
||||
import '../hooks/delayed_loading.dart';
|
||||
import '../hooks/stores.dart';
|
||||
import '../util/extensions/api.dart';
|
||||
import 'markdown_text.dart';
|
||||
|
||||
/// Modal for writing a comment to a given post/comment (aka reply)
|
||||
|
@ -14,14 +13,14 @@ class WriteComment extends HookWidget {
|
|||
final PostView post;
|
||||
final CommentView comment;
|
||||
|
||||
final String instanceUrl;
|
||||
final String instanceHost;
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
|
||||
|
||||
WriteComment.toPost(this.post)
|
||||
: instanceUrl = post.instanceUrl,
|
||||
: instanceHost = post.instanceHost,
|
||||
comment = null;
|
||||
WriteComment.toComment(this.comment)
|
||||
: instanceUrl = comment.instanceUrl,
|
||||
: instanceHost = comment.instanceHost,
|
||||
post = null;
|
||||
|
||||
@override
|
||||
|
@ -34,7 +33,7 @@ class WriteComment extends HookWidget {
|
|||
final preview = () {
|
||||
final body = MarkdownText(
|
||||
comment?.content ?? post.body ?? '',
|
||||
instanceUrl: instanceUrl,
|
||||
instanceHost: instanceHost,
|
||||
);
|
||||
|
||||
if (post != null) {
|
||||
|
@ -54,9 +53,9 @@ class WriteComment extends HookWidget {
|
|||
}();
|
||||
|
||||
handleSubmit() async {
|
||||
final api = LemmyApi(instanceUrl).v1;
|
||||
final api = LemmyApi(instanceHost).v1;
|
||||
|
||||
final token = accStore.defaultTokenFor(instanceUrl);
|
||||
final token = accStore.defaultTokenFor(instanceHost);
|
||||
|
||||
delayed.start();
|
||||
try {
|
||||
|
@ -115,7 +114,7 @@ class WriteComment extends HookWidget {
|
|||
padding: const EdgeInsets.all(16),
|
||||
child: MarkdownText(
|
||||
controller.text,
|
||||
instanceUrl: instanceUrl,
|
||||
instanceHost: instanceHost,
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -260,7 +260,7 @@ packages:
|
|||
name: lemmy_api_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.0"
|
||||
version: "0.8.2"
|
||||
markdown:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -43,7 +43,7 @@ dependencies:
|
|||
# utils
|
||||
timeago: ^2.0.27
|
||||
fuzzy: <1.0.0
|
||||
lemmy_api_client: ^0.8.0
|
||||
lemmy_api_client: ^0.8.2
|
||||
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
|
Loading…
Reference in New Issue