Skip to content

Commit 80b3608

Browse files
authored
Merge pull request #2 from AndroidIRCx/develop
Add IRC auth, command, and stability improvements
2 parents d9a6716 + c1870c8 commit 80b3608

26 files changed

+2194
-52
lines changed

.github/workflows/codeql.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,21 @@ on:
99
- cron: '0 3 * * 1'
1010

1111
jobs:
12+
codeql-disabled:
13+
name: CodeQL Disabled
14+
runs-on: ubuntu-latest
15+
if: ${{ github.event.repository.private && vars.ENABLE_PRIVATE_CODEQL != 'true' }}
16+
17+
steps:
18+
- name: Explain why CodeQL is skipped
19+
run: |
20+
echo "Skipping CodeQL because this repository is private and GitHub Advanced Security is not enabled."
21+
echo "Enable GitHub Advanced Security, then set the ENABLE_PRIVATE_CODEQL repository variable to true."
22+
1223
analyze:
1324
name: Analyze
1425
runs-on: ubuntu-latest
26+
if: ${{ github.event.repository.private == false || vars.ENABLE_PRIVATE_CODEQL == 'true' }}
1527

1628
permissions:
1729
actions: read

lib/core/models/chat_tab.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@ class ChatTab {
1717
final bool hasActivity;
1818
final bool isEncrypted;
1919

20+
ChatTab copyWith({
21+
String? id,
22+
String? name,
23+
ChatTabType? type,
24+
String? networkId,
25+
bool? hasActivity,
26+
bool? isEncrypted,
27+
}) {
28+
return ChatTab(
29+
id: id ?? this.id,
30+
name: name ?? this.name,
31+
type: type ?? this.type,
32+
networkId: networkId ?? this.networkId,
33+
hasActivity: hasActivity ?? this.hasActivity,
34+
isEncrypted: isEncrypted ?? this.isEncrypted,
35+
);
36+
}
37+
2038
Map<String, Object?> toJson() {
2139
return {
2240
'id': id,

lib/core/models/network_config.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1+
enum SaslMechanism {
2+
plain,
3+
scramSha256,
4+
}
5+
16
class NetworkConfig {
27
const NetworkConfig({
38
required this.id,
49
required this.name,
510
required this.host,
611
required this.port,
712
required this.nickname,
13+
this.altNickname,
814
this.username = 'androidircx',
915
this.realName = 'AndroidIRCX',
1016
this.useTls = true,
1117
this.password,
18+
this.saslAccount,
19+
this.saslPassword,
20+
this.saslMechanism = SaslMechanism.plain,
1221
this.autoConnect = false,
1322
});
1423

@@ -17,10 +26,14 @@ class NetworkConfig {
1726
final String host;
1827
final int port;
1928
final String nickname;
29+
final String? altNickname;
2030
final String username;
2131
final String realName;
2232
final bool useTls;
2333
final String? password;
34+
final String? saslAccount;
35+
final String? saslPassword;
36+
final SaslMechanism saslMechanism;
2437
final bool autoConnect;
2538

2639
NetworkConfig copyWith({
@@ -29,10 +42,14 @@ class NetworkConfig {
2942
String? host,
3043
int? port,
3144
String? nickname,
45+
String? altNickname,
3246
String? username,
3347
String? realName,
3448
bool? useTls,
3549
String? password,
50+
String? saslAccount,
51+
String? saslPassword,
52+
SaslMechanism? saslMechanism,
3653
bool? autoConnect,
3754
}) {
3855
return NetworkConfig(
@@ -41,10 +58,14 @@ class NetworkConfig {
4158
host: host ?? this.host,
4259
port: port ?? this.port,
4360
nickname: nickname ?? this.nickname,
61+
altNickname: altNickname ?? this.altNickname,
4462
username: username ?? this.username,
4563
realName: realName ?? this.realName,
4664
useTls: useTls ?? this.useTls,
4765
password: password ?? this.password,
66+
saslAccount: saslAccount ?? this.saslAccount,
67+
saslPassword: saslPassword ?? this.saslPassword,
68+
saslMechanism: saslMechanism ?? this.saslMechanism,
4869
autoConnect: autoConnect ?? this.autoConnect,
4970
);
5071
}
@@ -56,10 +77,14 @@ class NetworkConfig {
5677
'host': host,
5778
'port': port,
5879
'nickname': nickname,
80+
'altNickname': altNickname,
5981
'username': username,
6082
'realName': realName,
6183
'useTls': useTls,
6284
'password': password,
85+
'saslAccount': saslAccount,
86+
'saslPassword': saslPassword,
87+
'saslMechanism': saslMechanism.name,
6388
'autoConnect': autoConnect,
6489
};
6590
}
@@ -71,10 +96,16 @@ class NetworkConfig {
7196
host: json['host']! as String,
7297
port: (json['port']! as num).toInt(),
7398
nickname: json['nickname']! as String,
99+
altNickname: json['altNickname'] as String?,
74100
username: (json['username'] as String?) ?? 'androidircx',
75101
realName: (json['realName'] as String?) ?? 'AndroidIRCX',
76102
useTls: (json['useTls'] as bool?) ?? true,
77103
password: json['password'] as String?,
104+
saslAccount: json['saslAccount'] as String?,
105+
saslPassword: json['saslPassword'] as String?,
106+
saslMechanism: json['saslMechanism'] == null
107+
? SaslMechanism.plain
108+
: SaslMechanism.values.byName(json['saslMechanism']! as String),
78109
autoConnect: (json['autoConnect'] as bool?) ?? false,
79110
);
80111
}

lib/core/storage/in_memory_network_repository.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class InMemoryNetworkRepository implements NetworkRepository {
1515
host: 'irc.dbase.in.rs',
1616
port: 6697,
1717
nickname: 'AndroidIRCX',
18+
altNickname: 'AndroidIRCX_',
1819
useTls: true,
1920
),
2021
];

lib/core/storage/shared_prefs_network_repository.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class SharedPrefsNetworkRepository implements NetworkRepository {
5555
host: 'irc.dbase.in.rs',
5656
port: 6697,
5757
nickname: 'AndroidIRCX',
58+
altNickname: 'AndroidIRCX_',
5859
useTls: true,
5960
),
6061
];

lib/features/bootstrap/presentation/bootstrap_screen.dart

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:androidircx/core/storage/shared_prefs_network_repository.dart';
2+
import 'package:androidircx/features/chat/application/session_registry.dart';
23
import 'package:androidircx/features/connections/application/network_list_controller.dart';
34
import 'package:androidircx/features/connections/presentation/network_list_screen.dart';
45
import 'package:flutter/material.dart';
@@ -12,23 +13,57 @@ class BootstrapScreen extends StatefulWidget {
1213

1314
class _BootstrapScreenState extends State<BootstrapScreen> {
1415
late final NetworkListController _controller;
16+
late final SessionRegistry _sessionRegistry;
17+
bool _bootstrapComplete = false;
1518

1619
@override
1720
void initState() {
1821
super.initState();
22+
_sessionRegistry = SessionRegistry();
1923
_controller = NetworkListController(
2024
repository: SharedPrefsNetworkRepository(),
21-
)..load();
25+
);
26+
_bootstrap();
27+
}
28+
29+
Future<void> _bootstrap() async {
30+
await _controller.load();
31+
for (final network in _controller.networks.where((item) => item.autoConnect)) {
32+
final session = _sessionRegistry.obtainSession(network);
33+
await session.start();
34+
}
35+
36+
if (!mounted) {
37+
return;
38+
}
39+
40+
setState(() {
41+
_bootstrapComplete = true;
42+
});
2243
}
2344

2445
@override
2546
void dispose() {
2647
_controller.dispose();
48+
_sessionRegistry.dispose();
2749
super.dispose();
2850
}
2951

3052
@override
3153
Widget build(BuildContext context) {
32-
return NetworkListScreen(controller: _controller);
54+
if (!_bootstrapComplete && _controller.isLoading) {
55+
return const Scaffold(
56+
body: SafeArea(
57+
child: Center(
58+
child: CircularProgressIndicator(),
59+
),
60+
),
61+
);
62+
}
63+
64+
return NetworkListScreen(
65+
controller: _controller,
66+
sessionRegistry: _sessionRegistry,
67+
);
3368
}
3469
}

0 commit comments

Comments
 (0)