Skip to content
This repository was archived by the owner on Dec 13, 2025. It is now read-only.
Draft
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
52 changes: 40 additions & 12 deletions lib/pages/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:weechat/relay/nicklist.dart';
import 'package:weechat/widgets/channel/user_list.dart';
import 'package:weechat/widgets/home/channel_list_item.dart';
import 'package:weechat/pages/log.dart';
import 'package:weechat/pages/log/event_logger.dart';
import 'package:weechat/pages/settings.dart';
import 'package:weechat/pages/settings/config.dart';
Expand Down Expand Up @@ -108,10 +109,8 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
return _suspend();
}
case AppLifecycleState.detached:
{
break;
}
case AppLifecycleState.inactive:
case AppLifecycleState.hidden:
{
break;
}
Expand Down Expand Up @@ -313,20 +312,25 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
_channelListDrawerChanged(_relayConnection!, isOpen);
}
},
endDrawer: _userListDrawer(context),
appBar: AppBar(
title: _title(),
actions: [
// show users button if connected
if (cs.connected)
Builder(
builder: (context) => IconButton(
icon: const Icon(Icons.group),
onPressed: () => _toggleUserList(context),
),
),
// settings button
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
Navigator.of(context).push(LogPage.route());
Navigator.of(context).push(SettingsPage.route());
},
icon: const Icon(Feather.info),
),
IconButton(
onPressed: () {
Navigator.of(context).push(SettingsPage.route());
},
icon: const Icon(Icons.settings)),
)
],
),

Expand Down Expand Up @@ -387,6 +391,30 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
});
}

Widget? _userListDrawer(BuildContext context) {
if (_relayBuffer != null) {
return Drawer(
child: UserListWidget(
nicklist: RelayBufferNicklist(
bufferId: _relayBuffer!.bufferPointer,
connection: _relayBuffer!.relayConnection,
),
),
);
} else {
return const Drawer();
}
}

void _toggleUserList(BuildContext context) {
final scaff = Scaffold.of(context);
if (scaff.isEndDrawerOpen) {
scaff.closeEndDrawer();
} else {
scaff.openEndDrawer();
}
}

Widget? _channelListDrawer(BuildContext context) {
final con = RelayConnection.of(context, listen: false);
if (!con.isConnected) return null;
Expand Down
9 changes: 9 additions & 0 deletions lib/pages/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:weechat/pages/log.dart';
import 'package:weechat/pages/settings/config.dart';

class SettingsPage extends StatefulWidget {
Expand All @@ -23,6 +24,14 @@ class _SettingsState extends State<SettingsPage> {
return Scaffold(
appBar: AppBar(
title: Text(loc.settingsTitle),
actions: [
IconButton(
onPressed: () {
Navigator.of(context).push(LogPage.route());
},
icon: const Icon(Feather.info),
),
],
),
body: ListView(
children: [
Expand Down
55 changes: 55 additions & 0 deletions lib/relay/nicklist.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:weechat/relay/connection.dart';
import 'package:weechat/relay/protocol/message_body.dart';

class NicklistData {
final String name;
final String color;
final String prefix;
final String prefix_color;

NicklistData({
required this.name,
required this.color,
required this.prefix,
required this.prefix_color,
});
}

class RelayBufferNicklist {
final RelayConnection connection;
final String bufferId;

RelayBufferNicklist({
required this.connection,
required this.bufferId,
});

Map<String, List<NicklistData>> get groups => Map.unmodifiable(_groups);
final Map<String, List<NicklistData>> _groups = {};

Future<List<NicklistData>?> load() async {
return await connection.command(
"nicklist $bufferId",
callback: (RelayMessageBody body) {
final lst = <NicklistData>[];
for (final hdata in body.objects()) {
for (final obj in hdata.objects) {
print(obj);
// sort objects into _groups
if (obj.values[0] == "\x01") {
continue;
} else {
lst.add(NicklistData(
name: obj.values[3],
color: obj.values[4],
prefix: obj.values[5],
prefix_color: obj.values[6],
));
}
}
}
return lst;
},
);
}
}
57 changes: 57 additions & 0 deletions lib/widgets/channel/user_list.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:weechat/relay/nicklist.dart';

class UserListWidget extends StatefulWidget {
final RelayBufferNicklist nicklist;

const UserListWidget({
required this.nicklist,
super.key,
});

@override
State<StatefulWidget> createState() {
return _State();
}
}

Future? _request;

class _State extends State<UserListWidget> {
RelayBufferNicklist get nicklist => widget.nicklist;

_State();

@override
Widget build(BuildContext context) {
// request nicklist from server
_request ??= nicklist.load();

return FutureBuilder(
future: _request,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return _loading();
} else if (snapshot.data == null) {
return _failed();
} else {
return _userList(context, snapshot.data!);
}
});
}

Widget _loading() => Container();
Widget _failed() => Container();

Widget _userList(BuildContext context, List<NicklistData> nicks) {
return ListView(
children: nicks.map((nick) => _userWidget(context, nick)).toList(),
);
}

Widget _userWidget(BuildContext context, NicklistData nick) {
return ListTile(
title: Text("${nick.prefix}${nick.name}"),
);
}
}
11 changes: 5 additions & 6 deletions lib/widgets/home/channel_list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,25 @@ class ChannelListItem extends StatelessWidget {
);

@override
Widget build(BuildContext context,
{
Widget build(
BuildContext context, {
RelayHotlistEntry? hotlist,
Future Function(BuildContext)? openBuffer,
}) {

final theme = Theme.of(context);

var titleColor = theme.disabledColor;
var captionColor = theme.colorScheme.onSurface.withAlpha(100);

switch (hotlist?.priority) {
case 0: // GUI_HOTLIST_LOW
titleColor = theme.colorScheme.inverseSurface.withAlpha(200);
titleColor = theme.colorScheme.onSurface.withAlpha(180);
break;
case 1: // GUI_HOTLIST_MESSAGE
titleColor = theme.colorScheme.secondary;
titleColor = theme.colorScheme.onSurface;
break;
case 2: // GUI_HOTLIST_PRIVATE
titleColor = theme.colorScheme.secondary;
titleColor = theme.colorScheme.onSurface;
break;
case 3: // GUI_HOTLIST_HIGHLIGHT
titleColor = theme.colorScheme.primary;
Expand Down
4 changes: 2 additions & 2 deletions macos/Flutter/ephemeral/Flutter-Generated.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ FLUTTER_ROOT=E:\dev\flutter
FLUTTER_APPLICATION_PATH=E:\dev\weechat
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=1.24.10
FLUTTER_BUILD_NUMBER=16
FLUTTER_BUILD_NAME=1.24.12
FLUTTER_BUILD_NUMBER=18
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
Expand Down
4 changes: 2 additions & 2 deletions macos/Flutter/ephemeral/flutter_export_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export "FLUTTER_ROOT=E:\dev\flutter"
export "FLUTTER_APPLICATION_PATH=E:\dev\weechat"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=1.24.10"
export "FLUTTER_BUILD_NUMBER=16"
export "FLUTTER_BUILD_NAME=1.24.12"
export "FLUTTER_BUILD_NUMBER=18"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
Expand Down