Skip to content
Merged
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
12 changes: 12 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,21 @@ on:
- cron: '0 3 * * 1'

jobs:
codeql-disabled:
name: CodeQL Disabled
runs-on: ubuntu-latest
if: ${{ github.event.repository.private && vars.ENABLE_PRIVATE_CODEQL != 'true' }}

steps:
- name: Explain why CodeQL is skipped
run: |
echo "Skipping CodeQL because this repository is private and GitHub Advanced Security is not enabled."
echo "Enable GitHub Advanced Security, then set the ENABLE_PRIVATE_CODEQL repository variable to true."

analyze:
name: Analyze
runs-on: ubuntu-latest
if: ${{ github.event.repository.private == false || vars.ENABLE_PRIVATE_CODEQL == 'true' }}

permissions:
actions: read
Expand Down
18 changes: 18 additions & 0 deletions lib/core/models/chat_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ class ChatTab {
final bool hasActivity;
final bool isEncrypted;

ChatTab copyWith({
String? id,
String? name,
ChatTabType? type,
String? networkId,
bool? hasActivity,
bool? isEncrypted,
}) {
return ChatTab(
id: id ?? this.id,
name: name ?? this.name,
type: type ?? this.type,
networkId: networkId ?? this.networkId,
hasActivity: hasActivity ?? this.hasActivity,
isEncrypted: isEncrypted ?? this.isEncrypted,
);
}

Map<String, Object?> toJson() {
return {
'id': id,
Expand Down
31 changes: 31 additions & 0 deletions lib/core/models/network_config.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
enum SaslMechanism {
plain,
scramSha256,
}

class NetworkConfig {
const NetworkConfig({
required this.id,
required this.name,
required this.host,
required this.port,
required this.nickname,
this.altNickname,
this.username = 'androidircx',
this.realName = 'AndroidIRCX',
this.useTls = true,
this.password,
this.saslAccount,
this.saslPassword,
this.saslMechanism = SaslMechanism.plain,
this.autoConnect = false,
});

Expand All @@ -17,10 +26,14 @@ class NetworkConfig {
final String host;
final int port;
final String nickname;
final String? altNickname;
final String username;
final String realName;
final bool useTls;
final String? password;
final String? saslAccount;
final String? saslPassword;
final SaslMechanism saslMechanism;
final bool autoConnect;

NetworkConfig copyWith({
Expand All @@ -29,10 +42,14 @@ class NetworkConfig {
String? host,
int? port,
String? nickname,
String? altNickname,
String? username,
String? realName,
bool? useTls,
String? password,
String? saslAccount,
String? saslPassword,
SaslMechanism? saslMechanism,
bool? autoConnect,
}) {
return NetworkConfig(
Expand All @@ -41,10 +58,14 @@ class NetworkConfig {
host: host ?? this.host,
port: port ?? this.port,
nickname: nickname ?? this.nickname,
altNickname: altNickname ?? this.altNickname,
username: username ?? this.username,
realName: realName ?? this.realName,
useTls: useTls ?? this.useTls,
password: password ?? this.password,
saslAccount: saslAccount ?? this.saslAccount,
saslPassword: saslPassword ?? this.saslPassword,
saslMechanism: saslMechanism ?? this.saslMechanism,
autoConnect: autoConnect ?? this.autoConnect,
);
}
Expand All @@ -56,10 +77,14 @@ class NetworkConfig {
'host': host,
'port': port,
'nickname': nickname,
'altNickname': altNickname,
'username': username,
'realName': realName,
'useTls': useTls,
'password': password,
'saslAccount': saslAccount,
'saslPassword': saslPassword,
'saslMechanism': saslMechanism.name,
'autoConnect': autoConnect,
};
}
Expand All @@ -71,10 +96,16 @@ class NetworkConfig {
host: json['host']! as String,
port: (json['port']! as num).toInt(),
nickname: json['nickname']! as String,
altNickname: json['altNickname'] as String?,
username: (json['username'] as String?) ?? 'androidircx',
realName: (json['realName'] as String?) ?? 'AndroidIRCX',
useTls: (json['useTls'] as bool?) ?? true,
password: json['password'] as String?,
saslAccount: json['saslAccount'] as String?,
saslPassword: json['saslPassword'] as String?,
saslMechanism: json['saslMechanism'] == null
? SaslMechanism.plain
: SaslMechanism.values.byName(json['saslMechanism']! as String),
autoConnect: (json['autoConnect'] as bool?) ?? false,
);
}
Expand Down
1 change: 1 addition & 0 deletions lib/core/storage/in_memory_network_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class InMemoryNetworkRepository implements NetworkRepository {
host: 'irc.dbase.in.rs',
port: 6697,
nickname: 'AndroidIRCX',
altNickname: 'AndroidIRCX_',
useTls: true,
),
];
Expand Down
1 change: 1 addition & 0 deletions lib/core/storage/shared_prefs_network_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class SharedPrefsNetworkRepository implements NetworkRepository {
host: 'irc.dbase.in.rs',
port: 6697,
nickname: 'AndroidIRCX',
altNickname: 'AndroidIRCX_',
useTls: true,
),
];
Expand Down
39 changes: 37 additions & 2 deletions lib/features/bootstrap/presentation/bootstrap_screen.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:androidircx/core/storage/shared_prefs_network_repository.dart';
import 'package:androidircx/features/chat/application/session_registry.dart';
import 'package:androidircx/features/connections/application/network_list_controller.dart';
import 'package:androidircx/features/connections/presentation/network_list_screen.dart';
import 'package:flutter/material.dart';
Expand All @@ -12,23 +13,57 @@ class BootstrapScreen extends StatefulWidget {

class _BootstrapScreenState extends State<BootstrapScreen> {
late final NetworkListController _controller;
late final SessionRegistry _sessionRegistry;
bool _bootstrapComplete = false;

@override
void initState() {
super.initState();
_sessionRegistry = SessionRegistry();
_controller = NetworkListController(
repository: SharedPrefsNetworkRepository(),
)..load();
);
_bootstrap();
}

Future<void> _bootstrap() async {
await _controller.load();
for (final network in _controller.networks.where((item) => item.autoConnect)) {
final session = _sessionRegistry.obtainSession(network);
await session.start();
}

if (!mounted) {
return;
}

setState(() {
_bootstrapComplete = true;
});
}

@override
void dispose() {
_controller.dispose();
_sessionRegistry.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return NetworkListScreen(controller: _controller);
if (!_bootstrapComplete && _controller.isLoading) {
return const Scaffold(
body: SafeArea(
child: Center(
child: CircularProgressIndicator(),
),
),
);
}

return NetworkListScreen(
controller: _controller,
sessionRegistry: _sessionRegistry,
);
}
}
Loading
Loading