Finish KeyToken operations

This commit is contained in:
2025-04-18 18:56:17 +02:00
parent 1f0f280286
commit 78c895547e
23 changed files with 1089 additions and 211 deletions

View File

@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
enum BadgeMode { error, warn, info }
class BadgeDisplay extends StatelessWidget {
final String text;
final BadgeMode mode;
final IconData? icon;
const BadgeDisplay({
Key? key,
required this.text,
required this.mode,
required this.icon,
}) : super(key: key);
@override
Widget build(BuildContext context) {
var col = Colors.grey;
var colFG = Colors.black;
if (mode == BadgeMode.error) col = Colors.red;
if (mode == BadgeMode.warn) col = Colors.orange;
if (mode == BadgeMode.info) col = Colors.blue;
if (mode == BadgeMode.error) colFG = Colors.red[900]!;
if (mode == BadgeMode.warn) colFG = Colors.black;
if (mode == BadgeMode.info) colFG = Colors.black;
return Container(
padding: const EdgeInsets.fromLTRB(8, 2, 8, 2),
decoration: BoxDecoration(
color: col[100],
border: Border.all(color: col[300]!),
borderRadius: BorderRadius.circular(4.0),
),
child: Row(
children: [
if (icon != null) Icon(icon!, color: colFG, size: 16.0),
Expanded(
child: Text(
text,
textAlign: TextAlign.center,
style: TextStyle(color: colFG, fontSize: 14.0),
),
),
],
),
);
}
}

View File

@@ -17,13 +17,12 @@ class FilterModalChannel extends StatefulWidget {
class _FilterModalChannelState extends State<FilterModalChannel> {
Set<String> _selectedEntries = {};
late ImmediateFuture<List<Channel>>? _futureChannels;
ImmediateFuture<List<Channel>> _futureChannels = ImmediateFuture.ofPending();
@override
void initState() {
super.initState();
_futureChannels = null;
_futureChannels = ImmediateFuture.ofFuture(() async {
final userAcc = Provider.of<AppAuth>(context, listen: false);
if (!userAcc.isAuth()) throw new Exception('not logged in');
@@ -51,45 +50,39 @@ class _FilterModalChannelState extends State<FilterModalChannel> {
content: Container(
width: 9000,
height: 9000,
child: () {
if (_futureChannels == null) {
return Center(child: CircularProgressIndicator());
}
return FutureBuilder(
future: _futureChannels!.future,
builder: ((context, snapshot) {
if (_futureChannels?.value != null) {
return _buildList(context, _futureChannels!.value!);
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) {
return ErrorDisplay(errorMessage: '${snapshot.error}');
} else if (snapshot.connectionState == ConnectionState.done) {
return _buildList(context, snapshot.data!);
} else {
return Center(child: CircularProgressIndicator());
}
}),
);
}(),
child: FutureBuilder(
future: _futureChannels.future,
builder: ((context, snapshot) {
if (_futureChannels.value != null) {
return _buildList(context, _futureChannels.value!);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) {
return ErrorDisplay(errorMessage: '${snapshot.error}');
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return _buildList(context, snapshot.data!);
} else {
return ErrorDisplay(errorMessage: 'Invalid future state');
}
}),
),
),
actions: <Widget>[
TextButton(
style: TextButton.styleFrom(textStyle: Theme.of(context).textTheme.labelLarge),
child: const Text('Apply'),
onPressed: () {
onOkay();
},
onPressed: _onOkay,
),
],
);
}
void onOkay() {
void _onOkay() {
Navi.popDialog(context);
final chiplets = _selectedEntries
.map((e) => MessageFilterChiplet(
label: _futureChannels?.get()?.map((e) => e as Channel?).firstWhere((p) => p?.channelID == e, orElse: () => null)?.displayName ?? '???',
label: _futureChannels.get()?.map((e) => e as Channel?).firstWhere((p) => p?.channelID == e, orElse: () => null)?.displayName ?? '???',
value: e,
type: MessageFilterChipletType.channel,
))

View File

@@ -17,13 +17,12 @@ class FilterModalKeytoken extends StatefulWidget {
class _FilterModalKeytokenState extends State<FilterModalKeytoken> {
Set<String> _selectedEntries = {};
late ImmediateFuture<List<KeyToken>>? _futureKeyTokens;
ImmediateFuture<List<KeyToken>> _futureKeyTokens = ImmediateFuture.ofPending();
@override
void initState() {
super.initState();
_futureKeyTokens = null;
_futureKeyTokens = ImmediateFuture.ofFuture(() async {
final userAcc = Provider.of<AppAuth>(context, listen: false);
if (!userAcc.isAuth()) throw new Exception('not logged in');
@@ -51,26 +50,22 @@ class _FilterModalKeytokenState extends State<FilterModalKeytoken> {
content: Container(
width: 9000,
height: 9000,
child: () {
if (_futureKeyTokens == null) {
return Center(child: CircularProgressIndicator());
}
return FutureBuilder(
future: _futureKeyTokens!.future,
builder: ((context, snapshot) {
if (_futureKeyTokens?.value != null) {
return _buildList(context, _futureKeyTokens!.value!);
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) {
return ErrorDisplay(errorMessage: '${snapshot.error}');
} else if (snapshot.connectionState == ConnectionState.done) {
return _buildList(context, snapshot.data!);
} else {
return Center(child: CircularProgressIndicator());
}
}),
);
}(),
child: FutureBuilder(
future: _futureKeyTokens.future,
builder: ((context, snapshot) {
if (_futureKeyTokens.value != null) {
return _buildList(context, _futureKeyTokens.value!);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) {
return ErrorDisplay(errorMessage: '${snapshot.error}');
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return _buildList(context, snapshot.data!);
} else {
return ErrorDisplay(errorMessage: 'Invalid future state');
}
}),
),
),
actions: <Widget>[
TextButton(
@@ -89,7 +84,7 @@ class _FilterModalKeytokenState extends State<FilterModalKeytoken> {
final chiplets = _selectedEntries
.map((e) => MessageFilterChiplet(
label: _futureKeyTokens?.get()?.map((e) => e as KeyToken?).firstWhere((p) => p?.keytokenID == e, orElse: () => null)?.name ?? '???',
label: _futureKeyTokens.get()?.map((e) => e as KeyToken?).firstWhere((p) => p?.keytokenID == e, orElse: () => null)?.name ?? '???',
value: e,
type: MessageFilterChipletType.sender,
))

View File

@@ -15,13 +15,12 @@ class FilterModalSendername extends StatefulWidget {
class _FilterModalSendernameState extends State<FilterModalSendername> {
Set<String> _selectedEntries = {};
late ImmediateFuture<List<String>>? _futureSenders;
ImmediateFuture<List<String>> _futureSenders = ImmediateFuture.ofPending();
@override
void initState() {
super.initState();
_futureSenders = null;
_futureSenders = ImmediateFuture.ofFuture(() async {
final userAcc = Provider.of<AppAuth>(context, listen: false);
if (!userAcc.isAuth()) throw new Exception('not logged in');
@@ -49,26 +48,22 @@ class _FilterModalSendernameState extends State<FilterModalSendername> {
content: Container(
width: 9000,
height: 9000,
child: () {
if (_futureSenders == null) {
return Center(child: CircularProgressIndicator());
}
return FutureBuilder(
future: _futureSenders!.future,
builder: ((context, snapshot) {
if (_futureSenders?.value != null) {
return _buildList(context, _futureSenders!.value!);
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) {
return ErrorDisplay(errorMessage: '${snapshot.error}');
} else if (snapshot.connectionState == ConnectionState.done) {
return _buildList(context, snapshot.data!);
} else {
return Center(child: CircularProgressIndicator());
}
}),
);
}(),
child: FutureBuilder(
future: _futureSenders.future,
builder: ((context, snapshot) {
if (_futureSenders.value != null) {
return _buildList(context, _futureSenders.value!);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasError) {
return ErrorDisplay(errorMessage: '${snapshot.error}');
} else if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return _buildList(context, snapshot.data!);
} else {
return ErrorDisplay(errorMessage: 'Invalid future state');
}
}),
),
),
actions: <Widget>[
TextButton(