kopia lustrzana https://gitlab.com/mysocialportal/relatica
Merge branch 'reshare-post-fix' into 'main'
Reshare post fix See merge request mysocialportal/relatica!35codemagic-setup
commit
c59b427133
|
@ -14,6 +14,7 @@
|
||||||
to make the zooming in of images more predictable.
|
to make the zooming in of images more predictable.
|
||||||
* Fixes
|
* Fixes
|
||||||
* Seemingly disappearing contacts on Contacts screen have been corrected.
|
* Seemingly disappearing contacts on Contacts screen have been corrected.
|
||||||
|
* Workaround for a regresssion in Friendica 2023.04 for reshared posts
|
||||||
* New Features
|
* New Features
|
||||||
* Responsive design for allowing the image and video attachments to scale up for larger videos
|
* Responsive design for allowing the image and video attachments to scale up for larger videos
|
||||||
but limit timeline/list width on very large screens.
|
but limit timeline/list width on very large screens.
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:relatica/models/exec_error.dart';
|
import 'package:relatica/models/exec_error.dart';
|
||||||
|
import 'package:relatica/services/auth_service.dart';
|
||||||
import 'package:result_monad/result_monad.dart';
|
import 'package:result_monad/result_monad.dart';
|
||||||
|
|
||||||
import '../../globals.dart';
|
import '../../globals.dart';
|
||||||
|
@ -111,7 +112,21 @@ class _InteractionsBarControlState extends State<InteractionsBarControl> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addComment() async {
|
Future<void> addComment() async {
|
||||||
context.push('/comment/new?parent_id=${widget.entry.id}');
|
final needingReshareIdFix = getIt<FriendicaVersionChecker>()
|
||||||
|
.canUseFeature(RelaticaFeatures.reshareIdFix);
|
||||||
|
final myId = getIt<AccountsService>().currentProfile.userId;
|
||||||
|
|
||||||
|
if (needingReshareIdFix &&
|
||||||
|
widget.entry.reshareOriginalPostId.isNotEmpty &&
|
||||||
|
widget.entry.reshareAuthorId != myId) {
|
||||||
|
await showConfirmDialog(context,
|
||||||
|
'Unable to comment on reshared posts with your current version of Friendica server.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
context.push('/comment/new?parent_id=${widget.entry.id}');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> unResharePost() async {
|
Future<void> unResharePost() async {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import 'friendica_version.dart';
|
||||||
|
|
||||||
|
final FriendicaVersionRequirement unknownRequirement =
|
||||||
|
FriendicaVersionRequirement(unknown);
|
||||||
|
|
||||||
|
class FriendicaVersionRequirement {
|
||||||
|
final FriendicaVersion minimumVersion;
|
||||||
|
final FriendicaVersion? maxVersion;
|
||||||
|
|
||||||
|
const FriendicaVersionRequirement(this.minimumVersion, {this.maxVersion});
|
||||||
|
|
||||||
|
bool versionMeetsRequirement(FriendicaVersion version) {
|
||||||
|
if (version < minimumVersion) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxVersion == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return version <= maxVersion!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
if (maxVersion == null) {
|
||||||
|
return 'requires at least Friendica $minimumVersion';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'works only on Friendica $minimumVersion to $maxVersion';
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,8 @@ class TimelineEntry {
|
||||||
|
|
||||||
final String parentAuthorId;
|
final String parentAuthorId;
|
||||||
|
|
||||||
|
final String reshareOriginalPostId;
|
||||||
|
|
||||||
final String reshareAuthor;
|
final String reshareAuthor;
|
||||||
|
|
||||||
final String reshareAuthorId;
|
final String reshareAuthorId;
|
||||||
|
@ -61,6 +63,7 @@ class TimelineEntry {
|
||||||
TimelineEntry(
|
TimelineEntry(
|
||||||
{this.id = '',
|
{this.id = '',
|
||||||
this.parentId = '',
|
this.parentId = '',
|
||||||
|
this.reshareOriginalPostId = '',
|
||||||
this.creationTimestamp = 0,
|
this.creationTimestamp = 0,
|
||||||
this.backdatedTimestamp = 0,
|
this.backdatedTimestamp = 0,
|
||||||
this.modificationTimestamp = 0,
|
this.modificationTimestamp = 0,
|
||||||
|
@ -91,6 +94,7 @@ class TimelineEntry {
|
||||||
backdatedTimestamp = DateTime.now().millisecondsSinceEpoch,
|
backdatedTimestamp = DateTime.now().millisecondsSinceEpoch,
|
||||||
modificationTimestamp = DateTime.now().millisecondsSinceEpoch,
|
modificationTimestamp = DateTime.now().millisecondsSinceEpoch,
|
||||||
id = randomId(),
|
id = randomId(),
|
||||||
|
reshareOriginalPostId = '',
|
||||||
youReshared = DateTime.now().second ~/ 2 == 0 ? true : false,
|
youReshared = DateTime.now().second ~/ 2 == 0 ? true : false,
|
||||||
visibility = DateTime.now().second ~/ 2 == 0
|
visibility = DateTime.now().second ~/ 2 == 0
|
||||||
? Visibility.public()
|
? Visibility.public()
|
||||||
|
@ -122,6 +126,7 @@ class TimelineEntry {
|
||||||
bool? isReshare,
|
bool? isReshare,
|
||||||
Visibility? visibility,
|
Visibility? visibility,
|
||||||
String? id,
|
String? id,
|
||||||
|
String? reshareOriginalPostId,
|
||||||
String? parentId,
|
String? parentId,
|
||||||
String? externalLink,
|
String? externalLink,
|
||||||
String? body,
|
String? body,
|
||||||
|
@ -148,6 +153,8 @@ class TimelineEntry {
|
||||||
modificationTimestamp:
|
modificationTimestamp:
|
||||||
modificationTimestamp ?? this.modificationTimestamp,
|
modificationTimestamp ?? this.modificationTimestamp,
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
|
reshareOriginalPostId:
|
||||||
|
reshareOriginalPostId ?? this.reshareOriginalPostId,
|
||||||
youReshared: isReshare ?? this.youReshared,
|
youReshared: isReshare ?? this.youReshared,
|
||||||
visibility: visibility ?? this.visibility,
|
visibility: visibility ?? this.visibility,
|
||||||
parentId: parentId ?? this.parentId,
|
parentId: parentId ?? this.parentId,
|
||||||
|
@ -187,6 +194,7 @@ class TimelineEntry {
|
||||||
other is TimelineEntry &&
|
other is TimelineEntry &&
|
||||||
runtimeType == other.runtimeType &&
|
runtimeType == other.runtimeType &&
|
||||||
id == other.id &&
|
id == other.id &&
|
||||||
|
reshareOriginalPostId == other.reshareOriginalPostId &&
|
||||||
parentId == other.parentId &&
|
parentId == other.parentId &&
|
||||||
parentAuthor == other.parentAuthor &&
|
parentAuthor == other.parentAuthor &&
|
||||||
parentAuthorId == other.parentAuthorId &&
|
parentAuthorId == other.parentAuthorId &&
|
||||||
|
@ -214,6 +222,7 @@ class TimelineEntry {
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
id.hashCode ^
|
id.hashCode ^
|
||||||
|
reshareOriginalPostId.hashCode ^
|
||||||
parentId.hashCode ^
|
parentId.hashCode ^
|
||||||
parentAuthor.hashCode ^
|
parentAuthor.hashCode ^
|
||||||
parentAuthorId.hashCode ^
|
parentAuthorId.hashCode ^
|
||||||
|
|
|
@ -76,15 +76,18 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
|
||||||
|
|
||||||
late final String reshareAuthor;
|
late final String reshareAuthor;
|
||||||
late final String reshareAuthorId;
|
late final String reshareAuthorId;
|
||||||
|
late final String reshareOriginalPostId;
|
||||||
if (json['reblog'] != null) {
|
if (json['reblog'] != null) {
|
||||||
final rebloggedUser =
|
final rebloggedUser =
|
||||||
ConnectionMastodonExtensions.fromJson(json['reblog']['account']);
|
ConnectionMastodonExtensions.fromJson(json['reblog']['account']);
|
||||||
connectionManager?.upsertConnection(rebloggedUser);
|
connectionManager?.upsertConnection(rebloggedUser);
|
||||||
reshareAuthor = rebloggedUser.name;
|
reshareAuthor = rebloggedUser.name;
|
||||||
reshareAuthorId = rebloggedUser.id;
|
reshareAuthorId = rebloggedUser.id;
|
||||||
|
reshareOriginalPostId = json['reblog']['id'] ?? id;
|
||||||
} else {
|
} else {
|
||||||
reshareAuthorId = '';
|
reshareAuthorId = '';
|
||||||
reshareAuthor = '';
|
reshareAuthor = '';
|
||||||
|
reshareOriginalPostId = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<dynamic>? tags = json['tags'];
|
final List<dynamic>? tags = json['tags'];
|
||||||
|
@ -106,6 +109,7 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
|
||||||
youReshared: youReshared,
|
youReshared: youReshared,
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
id: id,
|
id: id,
|
||||||
|
reshareOriginalPostId: reshareOriginalPostId,
|
||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
parentAuthorId: parentAuthorId,
|
parentAuthorId: parentAuthorId,
|
||||||
reshareAuthor: reshareAuthor,
|
reshareAuthor: reshareAuthor,
|
||||||
|
|
|
@ -19,6 +19,7 @@ class ConnectionsManager extends ChangeNotifier {
|
||||||
static final _logger = Logger('$ConnectionsManager');
|
static final _logger = Logger('$ConnectionsManager');
|
||||||
late final IConnectionsRepo conRepo;
|
late final IConnectionsRepo conRepo;
|
||||||
late final IGroupsRepo groupsRepo;
|
late final IGroupsRepo groupsRepo;
|
||||||
|
var groupsNotInitialized = true;
|
||||||
|
|
||||||
ConnectionsManager(this.conRepo, this.groupsRepo);
|
ConnectionsManager(this.conRepo, this.groupsRepo);
|
||||||
|
|
||||||
|
@ -200,7 +201,8 @@ class ConnectionsManager extends ChangeNotifier {
|
||||||
|
|
||||||
List<GroupData> getMyGroups() {
|
List<GroupData> getMyGroups() {
|
||||||
final myGroups = groupsRepo.getMyGroups();
|
final myGroups = groupsRepo.getMyGroups();
|
||||||
if (myGroups.isEmpty) {
|
if (groupsNotInitialized) {
|
||||||
|
groupsNotInitialized = true;
|
||||||
_updateMyGroups(true);
|
_updateMyGroups(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import '../models/media_attachment_uploads/new_entry_media_items.dart';
|
||||||
import '../models/timeline_entry.dart';
|
import '../models/timeline_entry.dart';
|
||||||
import '../models/visibility.dart';
|
import '../models/visibility.dart';
|
||||||
import 'auth_service.dart';
|
import 'auth_service.dart';
|
||||||
|
import 'feature_version_checker.dart';
|
||||||
import 'media_upload_attachment_helper.dart';
|
import 'media_upload_attachment_helper.dart';
|
||||||
|
|
||||||
class EntryManagerService extends ChangeNotifier {
|
class EntryManagerService extends ChangeNotifier {
|
||||||
|
@ -44,8 +45,9 @@ class EntryManagerService extends ChangeNotifier {
|
||||||
|
|
||||||
Result<EntryTreeItem, ExecError> getPostTreeEntryBy(String id) {
|
Result<EntryTreeItem, ExecError> getPostTreeEntryBy(String id) {
|
||||||
_logger.finest('Getting post: $id');
|
_logger.finest('Getting post: $id');
|
||||||
|
final idForCall = mapInteractionId(id);
|
||||||
final currentId = getIt<AccountsService>().currentProfile.userId;
|
final currentId = getIt<AccountsService>().currentProfile.userId;
|
||||||
final postNode = _getPostRootNode(id);
|
final postNode = _getPostRootNode(idForCall);
|
||||||
if (postNode == null) {
|
if (postNode == null) {
|
||||||
return Result.error(ExecError(
|
return Result.error(ExecError(
|
||||||
type: ErrorType.notFound,
|
type: ErrorType.notFound,
|
||||||
|
@ -179,6 +181,7 @@ class EntryManagerService extends ChangeNotifier {
|
||||||
required Visibility newMediaItemVisibility,
|
required Visibility newMediaItemVisibility,
|
||||||
}) async {
|
}) async {
|
||||||
_logger.finest('Editing post: $text');
|
_logger.finest('Editing post: $text');
|
||||||
|
final idForCall = mapInteractionId(id);
|
||||||
final mediaIds = existingMediaItems
|
final mediaIds = existingMediaItems
|
||||||
.map((m) => m.scales.isEmpty ? m.id : m.scales.first.id)
|
.map((m) => m.scales.isEmpty ? m.id : m.scales.first.id)
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -225,7 +228,10 @@ class EntryManagerService extends ChangeNotifier {
|
||||||
|
|
||||||
final result = await StatusesClient(getIt<AccountsService>().currentProfile)
|
final result = await StatusesClient(getIt<AccountsService>().currentProfile)
|
||||||
.editStatus(
|
.editStatus(
|
||||||
id: id, text: text, spoilerText: spoilerText, mediaIds: mediaIds)
|
id: idForCall,
|
||||||
|
text: text,
|
||||||
|
spoilerText: spoilerText,
|
||||||
|
mediaIds: mediaIds)
|
||||||
.andThenSuccessAsync((item) async {
|
.andThenSuccessAsync((item) async {
|
||||||
await processNewItems(
|
await processNewItems(
|
||||||
[item], getIt<AccountsService>().currentProfile.username, null);
|
[item], getIt<AccountsService>().currentProfile.username, null);
|
||||||
|
@ -394,13 +400,29 @@ class EntryManagerService extends ChangeNotifier {
|
||||||
return updatedPosts;
|
return updatedPosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String mapInteractionId(String id) {
|
||||||
|
return getEntryById(id).transform((e) {
|
||||||
|
if (e.reshareOriginalPostId.isEmpty) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
final fvc = getIt<FriendicaVersionChecker>();
|
||||||
|
if (fvc.canUseFeature(RelaticaFeatures.reshareIdFix)) {
|
||||||
|
return e.reshareOriginalPostId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}).getValueOrElse(() => id);
|
||||||
|
}
|
||||||
|
|
||||||
FutureResult<EntryTreeItem, ExecError> refreshStatusChain(String id) async {
|
FutureResult<EntryTreeItem, ExecError> refreshStatusChain(String id) async {
|
||||||
_logger.finest('Refreshing post: $id');
|
_logger.finest('Refreshing post: $id');
|
||||||
final client = StatusesClient(getIt<AccountsService>().currentProfile);
|
final client = StatusesClient(getIt<AccountsService>().currentProfile);
|
||||||
|
final idForCall = mapInteractionId(id);
|
||||||
final result = await client
|
final result = await client
|
||||||
.getPostOrComment(id, fullContext: false)
|
.getPostOrComment(idForCall, fullContext: false)
|
||||||
.andThenAsync((rootItems) async => await client
|
.andThenAsync((rootItems) async => await client
|
||||||
.getPostOrComment(id, fullContext: true)
|
.getPostOrComment(idForCall, fullContext: true)
|
||||||
.andThenSuccessAsync(
|
.andThenSuccessAsync(
|
||||||
(contextItems) async => [...rootItems, ...contextItems]))
|
(contextItems) async => [...rootItems, ...contextItems]))
|
||||||
.andThenSuccessAsync((items) async {
|
.andThenSuccessAsync((items) async {
|
||||||
|
@ -424,8 +446,9 @@ class EntryManagerService extends ChangeNotifier {
|
||||||
FutureResult<EntryTreeItem, ExecError> resharePost(String id) async {
|
FutureResult<EntryTreeItem, ExecError> resharePost(String id) async {
|
||||||
_logger.finest('Resharing post: $id');
|
_logger.finest('Resharing post: $id');
|
||||||
final client = StatusesClient(getIt<AccountsService>().currentProfile);
|
final client = StatusesClient(getIt<AccountsService>().currentProfile);
|
||||||
|
final idForCall = mapInteractionId(id);
|
||||||
final result =
|
final result =
|
||||||
await client.resharePost(id).andThenSuccessAsync((item) async {
|
await client.resharePost(idForCall).andThenSuccessAsync((item) async {
|
||||||
await processNewItems([item], client.profile.username, null);
|
await processNewItems([item], client.profile.username, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -446,8 +469,9 @@ class EntryManagerService extends ChangeNotifier {
|
||||||
FutureResult<bool, ExecError> unResharePost(String id) async {
|
FutureResult<bool, ExecError> unResharePost(String id) async {
|
||||||
_logger.finest('Unresharing post: $id');
|
_logger.finest('Unresharing post: $id');
|
||||||
final client = StatusesClient(getIt<AccountsService>().currentProfile);
|
final client = StatusesClient(getIt<AccountsService>().currentProfile);
|
||||||
|
final idForCall = mapInteractionId(id);
|
||||||
final result =
|
final result =
|
||||||
await client.unResharePost(id).andThenSuccessAsync((item) async {
|
await client.unResharePost(idForCall).andThenSuccessAsync((item) async {
|
||||||
await processNewItems([item], client.profile.username, null);
|
await processNewItems([item], client.profile.username, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -463,20 +487,29 @@ class EntryManagerService extends ChangeNotifier {
|
||||||
|
|
||||||
FutureResult<EntryTreeItem, ExecError> toggleFavorited(
|
FutureResult<EntryTreeItem, ExecError> toggleFavorited(
|
||||||
String id, bool newStatus) async {
|
String id, bool newStatus) async {
|
||||||
final client = InteractionsClient(getIt<AccountsService>().currentProfile);
|
final profile = getIt<AccountsService>().currentProfile;
|
||||||
final result = await client.changeFavoriteStatus(id, newStatus);
|
final interactionClient = InteractionsClient(profile);
|
||||||
|
final postsClient = StatusesClient(profile);
|
||||||
|
final idForCall = mapInteractionId(id);
|
||||||
|
final result =
|
||||||
|
await interactionClient.changeFavoriteStatus(idForCall, newStatus);
|
||||||
if (result.isFailure) {
|
if (result.isFailure) {
|
||||||
return result.errorCast();
|
return result.errorCast();
|
||||||
}
|
}
|
||||||
|
|
||||||
final update = result.value;
|
final updateResult =
|
||||||
|
await postsClient.getPostOrComment(id, fullContext: false);
|
||||||
|
if (updateResult.isFailure) {
|
||||||
|
return updateResult.errorCast();
|
||||||
|
}
|
||||||
|
final update = updateResult.value.first;
|
||||||
_entries[update.id] = update;
|
_entries[update.id] = update;
|
||||||
final node = update.parentId.isEmpty
|
final node = update.parentId.isEmpty
|
||||||
? _postNodes[update.id]!
|
? _postNodes[update.id]!
|
||||||
: _postNodes[_parentPostIds[update.id]]!;
|
: _postNodes[_parentPostIds[update.id]]!;
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
return Result.ok(_nodeToTreeItem(node, client.profile.userId));
|
return Result.ok(_nodeToTreeItem(node, interactionClient.profile.userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
EntryTreeItem _nodeToTreeItem(_Node node, String currentId) {
|
EntryTreeItem _nodeToTreeItem(_Node node, String currentId) {
|
||||||
|
|
|
@ -6,11 +6,13 @@ import 'package:result_monad/result_monad.dart';
|
||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
import '../models/exec_error.dart';
|
import '../models/exec_error.dart';
|
||||||
import '../models/friendica_version.dart';
|
import '../models/friendica_version.dart';
|
||||||
|
import '../models/friendica_version_requirement.dart';
|
||||||
|
|
||||||
enum RelaticaFeatures {
|
enum RelaticaFeatures {
|
||||||
diasporaReshare('Resharing Diaspora Posts'),
|
diasporaReshare('Resharing Diaspora Posts'),
|
||||||
directMessageCreation('Direct message creation with OAuth login'),
|
directMessageCreation('Direct message creation with OAuth login'),
|
||||||
postSpoilerText('Spoiler Text on Posts'),
|
postSpoilerText('Spoiler Text on Posts'),
|
||||||
|
reshareIdFix('Reshare ID fix'),
|
||||||
statusEditing('Post/Comment Editing'),
|
statusEditing('Post/Comment Editing'),
|
||||||
usingActualFollowRequests(
|
usingActualFollowRequests(
|
||||||
'Using Follow Request System not Friend Request Notifications'),
|
'Using Follow Request System not Friend Request Notifications'),
|
||||||
|
@ -29,8 +31,8 @@ class FriendicaVersionChecker {
|
||||||
const FriendicaVersionChecker();
|
const FriendicaVersionChecker();
|
||||||
|
|
||||||
bool canUseFeature(RelaticaFeatures feature) {
|
bool canUseFeature(RelaticaFeatures feature) {
|
||||||
final neededVersion = featureVersionRequirement[feature];
|
final requirement = featureVersionRequirement[feature];
|
||||||
if (neededVersion == null) {
|
if (requirement == null) {
|
||||||
_logger.severe(
|
_logger.severe(
|
||||||
'Return false since no minimum version data in table for: $feature',
|
'Return false since no minimum version data in table for: $feature',
|
||||||
);
|
);
|
||||||
|
@ -39,7 +41,9 @@ class FriendicaVersionChecker {
|
||||||
|
|
||||||
return getIt<ActiveProfileSelector<InstanceInfo>>()
|
return getIt<ActiveProfileSelector<InstanceInfo>>()
|
||||||
.activeEntry
|
.activeEntry
|
||||||
.andThenSuccess((info) => info.friendicaVersion >= neededVersion)
|
.andThenSuccess(
|
||||||
|
(info) => requirement.versionMeetsRequirement(info.friendicaVersion),
|
||||||
|
)
|
||||||
.fold(
|
.fold(
|
||||||
onSuccess: (versionMet) => versionMet,
|
onSuccess: (versionMet) => versionMet,
|
||||||
onError: (error) {
|
onError: (error) {
|
||||||
|
@ -61,17 +65,26 @@ class FriendicaVersionChecker {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FriendicaVersion getVersionRequirement(RelaticaFeatures feature) =>
|
FriendicaVersionRequirement getVersionRequirement(RelaticaFeatures feature) =>
|
||||||
featureVersionRequirement[feature] ?? unknown;
|
featureVersionRequirement[feature] ?? unknownRequirement;
|
||||||
|
|
||||||
String versionErrorString(RelaticaFeatures feature) =>
|
String versionErrorString(RelaticaFeatures feature) =>
|
||||||
"${feature.label} requires at least Friendica ${getVersionRequirement(feature).toVersionString()}";
|
"${feature.label} ${getVersionRequirement(feature)}";
|
||||||
|
|
||||||
static final featureVersionRequirement = <RelaticaFeatures, FriendicaVersion>{
|
static final featureVersionRequirement =
|
||||||
RelaticaFeatures.diasporaReshare: v2023_04,
|
<RelaticaFeatures, FriendicaVersionRequirement>{
|
||||||
RelaticaFeatures.directMessageCreation: v2023_04,
|
RelaticaFeatures.diasporaReshare: FriendicaVersionRequirement(v2023_04),
|
||||||
RelaticaFeatures.postSpoilerText: v2023_04,
|
RelaticaFeatures.directMessageCreation: FriendicaVersionRequirement(
|
||||||
RelaticaFeatures.statusEditing: v2023_04,
|
v2023_04,
|
||||||
RelaticaFeatures.usingActualFollowRequests: v2023_04,
|
),
|
||||||
|
RelaticaFeatures.postSpoilerText: FriendicaVersionRequirement(v2023_04),
|
||||||
|
RelaticaFeatures.reshareIdFix: FriendicaVersionRequirement(
|
||||||
|
v2023_04,
|
||||||
|
maxVersion: v2023_04,
|
||||||
|
),
|
||||||
|
RelaticaFeatures.statusEditing: FriendicaVersionRequirement(v2023_04),
|
||||||
|
RelaticaFeatures.usingActualFollowRequests: FriendicaVersionRequirement(
|
||||||
|
v2023_04,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ import '../friendica_client/friendica_client.dart';
|
||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
import '../models/connection.dart';
|
import '../models/connection.dart';
|
||||||
import '../models/exec_error.dart';
|
import '../models/exec_error.dart';
|
||||||
|
import '../utils/active_profile_selector.dart';
|
||||||
import 'auth_service.dart';
|
import 'auth_service.dart';
|
||||||
|
import 'entry_manager_service.dart';
|
||||||
|
|
||||||
class InteractionsManager extends ChangeNotifier {
|
class InteractionsManager extends ChangeNotifier {
|
||||||
final _likesByStatusId = <String, List<Connection>>{};
|
final _likesByStatusId = <String, List<Connection>>{};
|
||||||
|
@ -31,9 +33,10 @@ class InteractionsManager extends ChangeNotifier {
|
||||||
|
|
||||||
FutureResult<List<Connection>, ExecError> updateLikesForStatus(
|
FutureResult<List<Connection>, ExecError> updateLikesForStatus(
|
||||||
String statusId) async {
|
String statusId) async {
|
||||||
|
final idForCall = _mapStatusId(statusId);
|
||||||
final likesResult =
|
final likesResult =
|
||||||
await InteractionsClient(getIt<AccountsService>().currentProfile)
|
await InteractionsClient(getIt<AccountsService>().currentProfile)
|
||||||
.getLikes(statusId);
|
.getLikes(idForCall);
|
||||||
if (likesResult.isSuccess) {
|
if (likesResult.isSuccess) {
|
||||||
_likesByStatusId[statusId] = likesResult.value;
|
_likesByStatusId[statusId] = likesResult.value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
@ -43,13 +46,21 @@ class InteractionsManager extends ChangeNotifier {
|
||||||
|
|
||||||
FutureResult<List<Connection>, ExecError> updateResharesForStatus(
|
FutureResult<List<Connection>, ExecError> updateResharesForStatus(
|
||||||
String statusId) async {
|
String statusId) async {
|
||||||
|
final idForCall = _mapStatusId(statusId);
|
||||||
final resharesResult =
|
final resharesResult =
|
||||||
await InteractionsClient(getIt<AccountsService>().currentProfile)
|
await InteractionsClient(getIt<AccountsService>().currentProfile)
|
||||||
.getReshares(statusId);
|
.getReshares(idForCall);
|
||||||
if (resharesResult.isSuccess) {
|
if (resharesResult.isSuccess) {
|
||||||
_resharesByStatusId[statusId] = resharesResult.value;
|
_resharesByStatusId[statusId] = resharesResult.value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
return resharesResult;
|
return resharesResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _mapStatusId(String statusId) {
|
||||||
|
return getIt<ActiveProfileSelector<EntryManagerService>>()
|
||||||
|
.activeEntry
|
||||||
|
.transform((m) => m.mapInteractionId(statusId))
|
||||||
|
.getValueOrElse(() => statusId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ class TimelineManager extends ChangeNotifier {
|
||||||
|
|
||||||
final IGroupsRepo groupsRepo;
|
final IGroupsRepo groupsRepo;
|
||||||
final EntryManagerService entryManagerService;
|
final EntryManagerService entryManagerService;
|
||||||
|
var groupsNotInitialized = true;
|
||||||
|
|
||||||
final cachedTimelines = <TimelineIdentifiers, Timeline>{};
|
final cachedTimelines = <TimelineIdentifiers, Timeline>{};
|
||||||
|
|
||||||
|
@ -41,8 +42,9 @@ class TimelineManager extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<List<GroupData>, ExecError> getGroups() {
|
Result<List<GroupData>, ExecError> getGroups() {
|
||||||
if (groupsRepo.getMyGroups().isEmpty) {
|
if (groupsNotInitialized) {
|
||||||
_refreshGroupData();
|
_refreshGroupData();
|
||||||
|
groupsNotInitialized = false;
|
||||||
return Result.ok([]);
|
return Result.ok([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue