chore: show visibility toggle loading, standardize level calculation (#2631)
This commit is contained in:
parent
20a14969e7
commit
b6053230c5
2 changed files with 104 additions and 48 deletions
|
|
@ -36,6 +36,10 @@ class ConstructListModel {
|
|||
/// A list of unique grammar lemmas
|
||||
List<String> grammarLemmasList = [];
|
||||
|
||||
/// [D] is the "compression factor". It determines how quickly
|
||||
/// or slowly the level grows relative to XP
|
||||
final double D = 1500;
|
||||
|
||||
List<ConstructIdentifier> unlockedLemmas(
|
||||
ConstructTypeEnum type, {
|
||||
int threshold = 0,
|
||||
|
|
@ -187,9 +191,6 @@ class ConstructListModel {
|
|||
}
|
||||
|
||||
int calculateLevelWithXp(int totalXP) {
|
||||
// [D] is the "compression factor". It determines how quickly
|
||||
/// or slowly the level grows relative to XP
|
||||
const double D = 1500;
|
||||
final doubleScore = (1 + sqrt((1 + (8.0 * totalXP / D)) / 2.0));
|
||||
if (!doubleScore.isNaN && doubleScore.isFinite) {
|
||||
return doubleScore.floor();
|
||||
|
|
@ -207,9 +208,6 @@ class ConstructListModel {
|
|||
}
|
||||
|
||||
int calculateXpWithLevel(int level) {
|
||||
// [D] is the same "compression factor" as in calculateLevelWithXp.
|
||||
const double D = 2500.0;
|
||||
|
||||
// If level <= 1, XP should be 0 or negative by this math.
|
||||
// In practice, you might clamp it to 0:
|
||||
if (level <= 1) {
|
||||
|
|
|
|||
|
|
@ -5,34 +5,69 @@ import 'package:matrix/matrix.dart' as matrix;
|
|||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class VisibilityToggle extends StatelessWidget {
|
||||
final Room? room;
|
||||
class VisibilityToggle extends StatefulWidget {
|
||||
final Room room;
|
||||
final Color? iconColor;
|
||||
final Future<void> Function(matrix.Visibility) setVisibility;
|
||||
final Future<void> Function(JoinRules) setJoinRules;
|
||||
final bool spaceMode;
|
||||
final matrix.Visibility visibility;
|
||||
final JoinRules joinRules;
|
||||
|
||||
final bool showSearchToggle;
|
||||
|
||||
const VisibilityToggle({
|
||||
required this.setVisibility,
|
||||
required this.setJoinRules,
|
||||
this.room,
|
||||
required this.room,
|
||||
this.iconColor,
|
||||
this.spaceMode = false,
|
||||
this.visibility = matrix.Visibility.private,
|
||||
this.joinRules = JoinRules.knock,
|
||||
this.showSearchToggle = true,
|
||||
super.key,
|
||||
});
|
||||
|
||||
bool get _isPublic => room != null
|
||||
? room!.joinRules == matrix.JoinRules.public
|
||||
: joinRules == matrix.JoinRules.public;
|
||||
@override
|
||||
State<VisibilityToggle> createState() => VisibilityToggleState();
|
||||
}
|
||||
|
||||
class VisibilityToggleState extends State<VisibilityToggle> {
|
||||
Room get room => widget.room;
|
||||
|
||||
bool get _isPublic => room.joinRules == matrix.JoinRules.public;
|
||||
|
||||
matrix.Visibility? _visibility;
|
||||
bool _loading = true;
|
||||
String? _error;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_getVisibility();
|
||||
}
|
||||
|
||||
Future<void> _getVisibility() async {
|
||||
try {
|
||||
final resp = await Matrix.of(context).client.getRoomVisibilityOnDirectory(
|
||||
room.id,
|
||||
);
|
||||
_visibility = resp ?? matrix.Visibility.private;
|
||||
} catch (e) {
|
||||
_error = e.toString();
|
||||
} finally {
|
||||
setState(() {
|
||||
_loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setVisibility(matrix.Visibility visibility) async {
|
||||
try {
|
||||
await widget.setVisibility(visibility);
|
||||
_visibility = visibility;
|
||||
} catch (e) {
|
||||
_error = e.toString();
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -50,40 +85,63 @@ class VisibilityToggle extends StatelessWidget {
|
|||
),
|
||||
secondary: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: iconColor,
|
||||
foregroundColor: widget.iconColor,
|
||||
child: const Icon(Icons.key_outlined),
|
||||
),
|
||||
value: !_isPublic,
|
||||
onChanged: (value) =>
|
||||
setJoinRules(value ? JoinRules.knock : JoinRules.public),
|
||||
widget.setJoinRules(value ? JoinRules.knock : JoinRules.public),
|
||||
),
|
||||
FutureBuilder(
|
||||
future: room != null
|
||||
? Matrix.of(context).client.getRoomVisibilityOnDirectory(room!.id)
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).canFindInSearch,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: widget.iconColor,
|
||||
child: const Icon(Icons.search_outlined),
|
||||
),
|
||||
onTap: _visibility != null
|
||||
? () => showFutureLoadingDialog(
|
||||
future: () async {
|
||||
_setVisibility(
|
||||
_visibility == matrix.Visibility.public
|
||||
? matrix.Visibility.private
|
||||
: matrix.Visibility.public,
|
||||
);
|
||||
},
|
||||
context: context,
|
||||
)
|
||||
: null,
|
||||
builder: (context, snapshot) {
|
||||
return SwitchListTile.adaptive(
|
||||
activeColor: AppConfig.activeToggleColor,
|
||||
title: Text(
|
||||
L10n.of(context).canFindInSearch,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
trailing: _loading || _error != null
|
||||
? SizedBox(
|
||||
height: 24.0,
|
||||
width: 24.0,
|
||||
child: _error != null
|
||||
? Icon(
|
||||
Icons.error,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
)
|
||||
: const CircularProgressIndicator.adaptive(),
|
||||
)
|
||||
: Switch.adaptive(
|
||||
activeColor: AppConfig.activeToggleColor,
|
||||
value: _visibility == matrix.Visibility.public,
|
||||
onChanged: (value) => showFutureLoadingDialog(
|
||||
future: () async {
|
||||
_setVisibility(
|
||||
value
|
||||
? matrix.Visibility.public
|
||||
: matrix.Visibility.private,
|
||||
);
|
||||
},
|
||||
context: context,
|
||||
),
|
||||
),
|
||||
),
|
||||
secondary: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: iconColor,
|
||||
child: const Icon(Icons.search_outlined),
|
||||
),
|
||||
value: room != null
|
||||
? snapshot.data == matrix.Visibility.public
|
||||
: visibility == matrix.Visibility.public,
|
||||
onChanged: (value) => setVisibility(
|
||||
value ? matrix.Visibility.public : matrix.Visibility.private,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue