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

feat: preserve hashtags in post form #464

Merged
merged 5 commits into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
19 changes: 19 additions & 0 deletions lib/extension/notes_create_request_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,23 @@ extension NotesCreateRequestExtension on NotesCreateRequest {
)
: null,
);

NotesCreateRequest addHashtags(List<String>? hashtags) {
if (hashtags case final hashtags? when hashtags.isNotEmpty) {
if (text case final text? when text.isNotEmpty) {
if (text.split('\n').last.trim().isEmpty) {
return copyWith(
text: '$text${hashtags.map((tag) => '#$tag').join(' ')}',
);
} else {
return copyWith(
text: '$text ${hashtags.map((tag) => '#$tag').join(' ')}',
);
}
} else {
return copyWith(text: hashtags.map((tag) => '#$tag').join(' '));
}
}
return this;
}
}
2 changes: 2 additions & 0 deletions lib/model/account_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class AccountSettings with _$AccountSettings {

// PostForm
@Default([]) List<String> hashtags,
@Default(false) bool postFormUseHashtags,
@Default([]) List<String> postFormHashtags,
}) = _AccountSettings;

factory AccountSettings.fromJson(Map<String, Object?> json) =>
Expand Down
76 changes: 64 additions & 12 deletions lib/model/account_settings.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ mixin _$AccountSettings {
List<String> get recentlyUsedUsers =>
throw _privateConstructorUsedError; // PostForm
List<String> get hashtags => throw _privateConstructorUsedError;
bool get postFormUseHashtags => throw _privateConstructorUsedError;
List<String> get postFormHashtags => throw _privateConstructorUsedError;

/// Serializes this AccountSettings to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
Expand Down Expand Up @@ -92,7 +94,9 @@ abstract class $AccountSettingsCopyWith<$Res> {
List<MuteWord> hardMutedWords,
List<String> mutedEmojis,
List<String> recentlyUsedUsers,
List<String> hashtags});
List<String> hashtags,
bool postFormUseHashtags,
List<String> postFormHashtags});
}

/// @nodoc
Expand Down Expand Up @@ -134,6 +138,8 @@ class _$AccountSettingsCopyWithImpl<$Res, $Val extends AccountSettings>
Object? mutedEmojis = null,
Object? recentlyUsedUsers = null,
Object? hashtags = null,
Object? postFormUseHashtags = null,
Object? postFormHashtags = null,
}) {
return _then(_value.copyWith(
keepCw: null == keepCw
Expand Down Expand Up @@ -232,6 +238,14 @@ class _$AccountSettingsCopyWithImpl<$Res, $Val extends AccountSettings>
? _value.hashtags
: hashtags // ignore: cast_nullable_to_non_nullable
as List<String>,
postFormUseHashtags: null == postFormUseHashtags
? _value.postFormUseHashtags
: postFormUseHashtags // ignore: cast_nullable_to_non_nullable
as bool,
postFormHashtags: null == postFormHashtags
? _value.postFormHashtags
: postFormHashtags // ignore: cast_nullable_to_non_nullable
as List<String>,
) as $Val);
}
}
Expand Down Expand Up @@ -268,7 +282,9 @@ abstract class _$$AccountSettingsImplCopyWith<$Res>
List<MuteWord> hardMutedWords,
List<String> mutedEmojis,
List<String> recentlyUsedUsers,
List<String> hashtags});
List<String> hashtags,
bool postFormUseHashtags,
List<String> postFormHashtags});
}

/// @nodoc
Expand Down Expand Up @@ -308,6 +324,8 @@ class __$$AccountSettingsImplCopyWithImpl<$Res>
Object? mutedEmojis = null,
Object? recentlyUsedUsers = null,
Object? hashtags = null,
Object? postFormUseHashtags = null,
Object? postFormHashtags = null,
}) {
return _then(_$AccountSettingsImpl(
keepCw: null == keepCw
Expand Down Expand Up @@ -406,6 +424,14 @@ class __$$AccountSettingsImplCopyWithImpl<$Res>
? _value._hashtags
: hashtags // ignore: cast_nullable_to_non_nullable
as List<String>,
postFormUseHashtags: null == postFormUseHashtags
? _value.postFormUseHashtags
: postFormUseHashtags // ignore: cast_nullable_to_non_nullable
as bool,
postFormHashtags: null == postFormHashtags
? _value._postFormHashtags
: postFormHashtags // ignore: cast_nullable_to_non_nullable
as List<String>,
));
}
}
Expand Down Expand Up @@ -437,15 +463,18 @@ class _$AccountSettingsImpl implements _AccountSettings {
final List<MuteWord> hardMutedWords = const [],
final List<String> mutedEmojis = const [],
final List<String> recentlyUsedUsers = const [],
final List<String> hashtags = const []})
final List<String> hashtags = const [],
this.postFormUseHashtags = false,
final List<String> postFormHashtags = const []})
: _pinnedEmojisForReaction = pinnedEmojisForReaction,
_pinnedEmojis = pinnedEmojis,
_recentlyUsedEmojis = recentlyUsedEmojis,
_mutedWords = mutedWords,
_hardMutedWords = hardMutedWords,
_mutedEmojis = mutedEmojis,
_recentlyUsedUsers = recentlyUsedUsers,
_hashtags = hashtags;
_hashtags = hashtags,
_postFormHashtags = postFormHashtags;

factory _$AccountSettingsImpl.fromJson(Map<String, dynamic> json) =>
_$$AccountSettingsImplFromJson(json);
Expand Down Expand Up @@ -580,9 +609,22 @@ class _$AccountSettingsImpl implements _AccountSettings {
return EqualUnmodifiableListView(_hashtags);
}

@override
@JsonKey()
final bool postFormUseHashtags;
final List<String> _postFormHashtags;
@override
@JsonKey()
List<String> get postFormHashtags {
if (_postFormHashtags is EqualUnmodifiableListView)
return _postFormHashtags;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_postFormHashtags);
}

@override
String toString() {
return 'AccountSettings(keepCw: $keepCw, rememberNoteVisibility: $rememberNoteVisibility, defaultNoteVisibility: $defaultNoteVisibility, defaultNoteLocalOnly: $defaultNoteLocalOnly, rememberRenoteVisibility: $rememberRenoteVisibility, defaultRenoteVisibility: $defaultRenoteVisibility, defaultRenoteLocalOnly: $defaultRenoteLocalOnly, reactionAcceptance: $reactionAcceptance, visibility: $visibility, localOnly: $localOnly, renoteVisibility: $renoteVisibility, renoteLocalOnly: $renoteLocalOnly, pinnedEmojisForReaction: $pinnedEmojisForReaction, pinnedEmojis: $pinnedEmojis, recentlyUsedEmojis: $recentlyUsedEmojis, defaultReaction: $defaultReaction, uploadFolder: $uploadFolder, keepOriginalUploading: $keepOriginalUploading, keepOriginalFilename: $keepOriginalFilename, mutedWords: $mutedWords, hardMutedWords: $hardMutedWords, mutedEmojis: $mutedEmojis, recentlyUsedUsers: $recentlyUsedUsers, hashtags: $hashtags)';
return 'AccountSettings(keepCw: $keepCw, rememberNoteVisibility: $rememberNoteVisibility, defaultNoteVisibility: $defaultNoteVisibility, defaultNoteLocalOnly: $defaultNoteLocalOnly, rememberRenoteVisibility: $rememberRenoteVisibility, defaultRenoteVisibility: $defaultRenoteVisibility, defaultRenoteLocalOnly: $defaultRenoteLocalOnly, reactionAcceptance: $reactionAcceptance, visibility: $visibility, localOnly: $localOnly, renoteVisibility: $renoteVisibility, renoteLocalOnly: $renoteLocalOnly, pinnedEmojisForReaction: $pinnedEmojisForReaction, pinnedEmojis: $pinnedEmojis, recentlyUsedEmojis: $recentlyUsedEmojis, defaultReaction: $defaultReaction, uploadFolder: $uploadFolder, keepOriginalUploading: $keepOriginalUploading, keepOriginalFilename: $keepOriginalFilename, mutedWords: $mutedWords, hardMutedWords: $hardMutedWords, mutedEmojis: $mutedEmojis, recentlyUsedUsers: $recentlyUsedUsers, hashtags: $hashtags, postFormUseHashtags: $postFormUseHashtags, postFormHashtags: $postFormHashtags)';
}

@override
Expand All @@ -597,11 +639,9 @@ class _$AccountSettingsImpl implements _AccountSettings {
other.defaultNoteVisibility == defaultNoteVisibility) &&
(identical(other.defaultNoteLocalOnly, defaultNoteLocalOnly) ||
other.defaultNoteLocalOnly == defaultNoteLocalOnly) &&
(identical(
other.rememberRenoteVisibility, rememberRenoteVisibility) ||
(identical(other.rememberRenoteVisibility, rememberRenoteVisibility) ||
other.rememberRenoteVisibility == rememberRenoteVisibility) &&
(identical(
other.defaultRenoteVisibility, defaultRenoteVisibility) ||
(identical(other.defaultRenoteVisibility, defaultRenoteVisibility) ||
other.defaultRenoteVisibility == defaultRenoteVisibility) &&
(identical(other.defaultRenoteLocalOnly, defaultRenoteLocalOnly) ||
other.defaultRenoteLocalOnly == defaultRenoteLocalOnly) &&
Expand Down Expand Up @@ -637,7 +677,11 @@ class _$AccountSettingsImpl implements _AccountSettings {
.equals(other._mutedEmojis, _mutedEmojis) &&
const DeepCollectionEquality()
.equals(other._recentlyUsedUsers, _recentlyUsedUsers) &&
const DeepCollectionEquality().equals(other._hashtags, _hashtags));
const DeepCollectionEquality().equals(other._hashtags, _hashtags) &&
(identical(other.postFormUseHashtags, postFormUseHashtags) ||
other.postFormUseHashtags == postFormUseHashtags) &&
const DeepCollectionEquality()
.equals(other._postFormHashtags, _postFormHashtags));
}

@JsonKey(includeFromJson: false, includeToJson: false)
Expand Down Expand Up @@ -667,7 +711,9 @@ class _$AccountSettingsImpl implements _AccountSettings {
const DeepCollectionEquality().hash(_hardMutedWords),
const DeepCollectionEquality().hash(_mutedEmojis),
const DeepCollectionEquality().hash(_recentlyUsedUsers),
const DeepCollectionEquality().hash(_hashtags)
const DeepCollectionEquality().hash(_hashtags),
postFormUseHashtags,
const DeepCollectionEquality().hash(_postFormHashtags)
]);

/// Create a copy of AccountSettings
Expand Down Expand Up @@ -712,7 +758,9 @@ abstract class _AccountSettings implements AccountSettings {
final List<MuteWord> hardMutedWords,
final List<String> mutedEmojis,
final List<String> recentlyUsedUsers,
final List<String> hashtags}) = _$AccountSettingsImpl;
final List<String> hashtags,
final bool postFormUseHashtags,
final List<String> postFormHashtags}) = _$AccountSettingsImpl;

factory _AccountSettings.fromJson(Map<String, dynamic> json) =
_$AccountSettingsImpl.fromJson;
Expand Down Expand Up @@ -766,6 +814,10 @@ abstract class _AccountSettings implements AccountSettings {
List<String> get recentlyUsedUsers; // PostForm
@override
List<String> get hashtags;
@override
bool get postFormUseHashtags;
@override
List<String> get postFormHashtags;

/// Create a copy of AccountSettings
/// with the given fields replaced by the non-null parameter values.
Expand Down
7 changes: 7 additions & 0 deletions lib/model/account_settings.g.dart

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

10 changes: 10 additions & 0 deletions lib/provider/account_settings_notifier_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,14 @@ class AccountSettingsNotifier extends _$AccountSettingsNotifier {
state = state.copyWith(hashtags: hashtags);
await _save();
}

Future<void> setPostFormUseHashtags(bool postFormUseHashtags) async {
state = state.copyWith(postFormUseHashtags: postFormUseHashtags);
await _save();
}

Future<void> setPostFormHashtags(List<String> postFormHashtags) async {
state = state.copyWith(postFormHashtags: postFormHashtags);
await _save();
}
}
2 changes: 1 addition & 1 deletion lib/provider/account_settings_notifier_provider.g.dart

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

44 changes: 44 additions & 0 deletions lib/provider/post_form_hashtags_notifier_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:collection/collection.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../model/account.dart';
import 'account_settings_notifier_provider.dart';

part 'post_form_hashtags_notifier_provider.g.dart';

@Riverpod(keepAlive: true)
class PostFormHashtagsNotifier extends _$PostFormHashtagsNotifier {
@override
List<String> build(Account account) {
return ref.watch(
accountSettingsNotifierProvider(account)
.select((settings) => settings.postFormHashtags),
);
}

// ignore: use_setters_to_change_properties
void updateHashtags(List<String> hashtags) {
state = hashtags;
}

void updateFromString(String text) {
updateHashtags(
text
.split(RegExp(r'\s'))
.map((tag) => tag.trim())
.map((tag) => tag.startsWith('#') ? tag.substring(1) : tag)
.where((tag) => tag.isNotEmpty)
.toList(),
);
}

Future<void> save() async {
if (!state.equals(
ref.read(accountSettingsNotifierProvider(account)).postFormHashtags,
)) {
await ref
.read(accountSettingsNotifierProvider(account).notifier)
.setPostFormHashtags(state);
}
}
}
Loading
Loading