Add message limit slider (#45)

This commit is contained in:
tommyxchow 2021-11-23 04:15:13 -05:00
parent 7dc5b114fb
commit 3944d54841
5 changed files with 50 additions and 9 deletions

View file

@ -26,6 +26,17 @@ class Settings extends StatelessWidget {
value: settingsStore.videoEnabled,
onChanged: (newValue) => settingsStore.videoEnabled = newValue,
),
ListTile(
title: const Text('Chat Message Limit'),
subtitle: Slider(
value: settingsStore.messageLimit,
onChanged: (newValue) => settingsStore.messageLimit = newValue,
min: 0,
max: 1000,
divisions: 10,
label: settingsStore.messageLimit == 1000 ? 'Unlimited' : '${settingsStore.messageLimit}',
),
)
],
);
},

View file

@ -7,21 +7,26 @@ part 'settings_store.g.dart';
class SettingsStore = _SettingsStoreBase with _$SettingsStore;
abstract class _SettingsStoreBase with Store {
@observable
bool videoEnabled = true;
@observable
double messageLimit = 200;
Future<void> init() async {
// Retrieve the instance that will allow us to store and persist settings.
final prefs = await SharedPreferences.getInstance();
// Initialize settings from stored preferences if any.
videoEnabled = prefs.getBool('video_enabled') ?? videoEnabled;
messageLimit = prefs.getDouble('message_limit') ?? messageLimit;
// Set up autorun to store setting anytime they're changed.
// The ReactionDisposer will not be needed since settings will always exist.
autorun((_) {
debugPrint('video changed');
debugPrint('settings changed');
prefs.setBool('video_enabled', videoEnabled);
prefs.setDouble('message_limit', messageLimit);
});
}
@observable
bool videoEnabled = true;
}

View file

@ -24,10 +24,26 @@ mixin _$SettingsStore on _SettingsStoreBase, Store {
});
}
final _$messageLimitAtom = Atom(name: '_SettingsStoreBase.messageLimit');
@override
double get messageLimit {
_$messageLimitAtom.reportRead();
return super.messageLimit;
}
@override
set messageLimit(double value) {
_$messageLimitAtom.reportWrite(value, super.messageLimit, () {
super.messageLimit = value;
});
}
@override
String toString() {
return '''
videoEnabled: ${videoEnabled}
videoEnabled: ${videoEnabled},
messageLimit: ${messageLimit}
''';
}
}

View file

@ -7,6 +7,7 @@ import 'package:frosty/api/irc_api.dart';
import 'package:frosty/api/seventv_api.dart';
import 'package:frosty/api/twitch_api.dart';
import 'package:frosty/core/auth/auth_store.dart';
import 'package:frosty/core/settings/settings_store.dart';
import 'package:frosty/models/irc.dart';
import 'package:mobx/mobx.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
@ -38,6 +39,9 @@ abstract class _ChatStoreBase with Store {
/// The provided auth store to determine login status, get the token, and use the headers for requests.
final AuthStore auth;
/// The provided setting store to account for any user-defined behaviors.
final SettingsStore settings;
/// The logged-in user's appearance in chat.
String? _userState;
@ -52,7 +56,11 @@ abstract class _ChatStoreBase with Store {
@readonly
var _roomState = const ROOMSTATE();
_ChatStoreBase({required this.auth, required this.channelName}) {
_ChatStoreBase({
required this.auth,
required this.settings,
required this.channelName,
}) {
// Listen for new messages and forward them to the handler.
_channel.stream.listen(
(data) => _handleIRCData(data.toString()),
@ -170,9 +178,9 @@ abstract class _ChatStoreBase with Store {
@action
void _deleteAndScrollToEnd() {
if (_autoScroll) {
// If there are over 200 messages, remove at least 20.
if (messages.length > 200) {
messages.removeRange(0, messages.length - 180);
// If there are more messages than the limit, remove around 10% of them from the oldest.
if (messages.length > settings.messageLimit && settings.messageLimit != 1000) {
messages.removeRange(0, (messages.length - settings.messageLimit * 0.1).ceil());
}
// After the end of the frame, scroll to the bottom of the chat.

View file

@ -68,6 +68,7 @@ class VideoChat extends StatelessWidget {
child: Chat(
chatStore: ChatStore(
auth: context.read<AuthStore>(),
settings: context.read<SettingsStore>(),
channelName: userLogin,
),
),