Skip to content

Commit 3a9888b

Browse files
committed
Add option to follow current system theme & fix windows installer
1 parent 6d39d75 commit 3a9888b

File tree

7 files changed

+132
-30
lines changed

7 files changed

+132
-30
lines changed

SETUP.md

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ cd OpenlibProject
2828
### 2. Clone the Repository
2929
Use Git to clone the project into your newly created directory:
3030
```bash
31-
git clone https://github.com/dstark5/Openlib.git
31+
git clone https://github.com/warreth/OpenlibExtended.git
3232
```
3333

3434
### 3. Navigate to the Project Folder
35-
After cloning, move into the **Openlib** folder:
35+
After cloning, move into the **OpenlibExtended** folder:
3636
```bash
37-
cd Openlib
37+
cd OpenlibExtended
3838
```
3939

4040
### 4. Open the Project in Android Studio or VS Code
@@ -70,6 +70,28 @@ To run the app:
7070

7171
---
7272

73+
## Linux Setup
74+
75+
### Requirements
76+
To build and run on Linux, you need to install **WebKitGTK 4.1**. This is required for the internal browser window used for CAPTCHA verification and downloads.
77+
78+
**Arch Linux / CachyOS:**
79+
```bash
80+
sudo pacman -S webkit2gtk-4.1
81+
```
82+
83+
**Ubuntu / Debian:**
84+
```bash
85+
sudo apt install libwebkit2gtk-4.1-dev
86+
```
87+
88+
**Fedora:**
89+
```bash
90+
sudo dnf install webkit2gtk4.1-devel
91+
```
92+
93+
---
94+
7395
## Additional Resources and Troubleshooting
7496
If you encounter any issues, refer to the official [Flutter documentation](https://docs.flutter.dev/) for comprehensive troubleshooting and setup tips.
7597

lib/main.dart

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import 'package:openlib/services/download_notification.dart';
3030
import 'package:openlib/services/instance_manager.dart';
3131
import 'package:openlib/state/state.dart'
3232
show
33+
ThemeModeNotifier,
3334
selectedIndexProvider,
3435
themeModeProvider,
3536
fontSizeScaleProvider,
@@ -64,8 +65,7 @@ void main(List<String> args) async {
6465

6566
await DownloadManager().initialize();
6667

67-
bool isDarkMode =
68-
await dataBase.getPreference('darkMode') == 0 ? false : true;
68+
ThemeMode startThemeMode = await ThemeModeNotifier.getInitialTheme();
6969

7070
double fontSizeScale = 1.0;
7171
try {
@@ -139,17 +139,15 @@ void main(List<String> args) async {
139139

140140
if (Platform.isAndroid) {
141141
// Android-specific setup for system UI overlay colors
142-
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
143-
systemNavigationBarColor:
144-
isDarkMode ? Colors.black : Colors.grey.shade200));
142+
ThemeModeNotifier.updateSystemUi(startThemeMode);
145143
await moveFilesToAndroidInternalStorage();
146144
}
147145

148146
runApp(
149147
ProviderScope(
150148
overrides: [
151-
themeModeProvider.overrideWith(
152-
(ref) => isDarkMode ? ThemeMode.dark : ThemeMode.light),
149+
themeModeProvider
150+
.overrideWith((ref) => ThemeModeNotifier(startThemeMode)),
153151
fontSizeScaleProvider.overrideWith((ref) => fontSizeScale),
154152
openPdfWithExternalAppProvider
155153
.overrideWith((ref) => openPdfwithExternalapp),

lib/services/database.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class MyLibraryDb {
140140
await getBookStorageDefaultDirectory;
141141
await db.execute(
142142
"INSERT OR IGNORE INTO preferences (name, value) VALUES ('darkMode', 0)");
143+
await db.execute(
144+
"INSERT OR IGNORE INTO preferences (name, value) VALUES ('themeMode', 'system')");
143145
await db.execute(
144146
"INSERT OR IGNORE INTO preferences (name, value) VALUES ('openPdfwithExternalApp', 0)");
145147
await db.execute(

lib/state/state.dart

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// Dart imports:
22
import 'dart:math';
3+
import 'dart:io';
4+
import 'dart:ui' as ui;
35

46
// Flutter imports:
57
import 'package:flutter/material.dart';
8+
import 'package:flutter/services.dart';
69

710
// Package imports:
811
import 'package:dio/dio.dart';
@@ -161,9 +164,65 @@ class FileName {
161164
// UI AND SIMPLE STATE PROVIDERS
162165
// ====================================================================
163166

167+
class ThemeModeNotifier extends StateNotifier<ThemeMode> {
168+
ThemeModeNotifier(super.state);
169+
170+
Future<void> setTheme(ThemeMode mode) async {
171+
state = mode;
172+
173+
// Save to DB
174+
String pref = 'system';
175+
if (mode == ThemeMode.light) pref = 'light';
176+
if (mode == ThemeMode.dark) pref = 'dark';
177+
await MyLibraryDb.instance.savePreference('themeMode', pref);
178+
179+
updateSystemUi(mode);
180+
}
181+
182+
static void updateSystemUi(ThemeMode mode) {
183+
if (Platform.isAndroid) {
184+
bool isDark = mode == ThemeMode.dark;
185+
if (mode == ThemeMode.system) {
186+
isDark = ui.PlatformDispatcher.instance.platformBrightness ==
187+
Brightness.dark;
188+
}
189+
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
190+
systemNavigationBarColor:
191+
isDark ? Colors.black : Colors.grey.shade200));
192+
}
193+
}
194+
195+
static Future<ThemeMode> getInitialTheme() async {
196+
try {
197+
MyLibraryDb dataBase = MyLibraryDb.instance;
198+
// Check for new theme mode preference
199+
var themePref =
200+
await dataBase.getPreference('themeMode').catchError((e) => null);
201+
if (themePref != null && themePref is String) {
202+
if (themePref == 'light') return ThemeMode.light;
203+
if (themePref == 'dark') return ThemeMode.dark;
204+
return ThemeMode.system;
205+
} else {
206+
// Fallback to legacy darkMode preference
207+
var legacyDark =
208+
await dataBase.getPreference('darkMode').catchError((e) => null);
209+
if (legacyDark != null) {
210+
return (legacyDark == 0) ? ThemeMode.light : ThemeMode.dark;
211+
}
212+
}
213+
} catch (e) {
214+
// Ignore
215+
}
216+
return ThemeMode.system;
217+
}
218+
}
219+
164220
final selectedIndexProvider = StateProvider<int>((ref) => 0);
165221
final homePageSelectedIndexProvider = StateProvider<int>((ref) => 0);
166-
final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.light);
222+
final themeModeProvider =
223+
StateNotifierProvider<ThemeModeNotifier, ThemeMode>((ref) {
224+
return ThemeModeNotifier(ThemeMode.light);
225+
});
167226
final fontSizeScaleProvider = StateProvider<double>((ref) => 1.0);
168227

169228
// Search Filter States

lib/ui/onboarding/onboarding_page.dart

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -457,18 +457,19 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
457457
icon: Icons.light_mode,
458458
selected: mode == ThemeMode.light,
459459
onTap: () {
460-
ref.read(themeModeProvider.notifier).state =
461-
ThemeMode.light;
462-
MyLibraryDb.instance.savePreference('darkMode', 0);
460+
ref
461+
.read(themeModeProvider.notifier)
462+
.setTheme(ThemeMode.light);
463463
}),
464464
const SizedBox(width: 20),
465465
_ThemeCard(
466466
title: "Dark",
467467
icon: Icons.dark_mode,
468468
selected: mode == ThemeMode.dark,
469469
onTap: () {
470-
ref.read(themeModeProvider.notifier).state = ThemeMode.dark;
471-
MyLibraryDb.instance.savePreference('darkMode', 1);
470+
ref
471+
.read(themeModeProvider.notifier)
472+
.setTheme(ThemeMode.dark);
472473
}),
473474
],
474475
),

lib/ui/settings_page.dart

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,34 @@ class SettingsPage extends ConsumerWidget {
163163
const _AutoRankInstancesWidget(),
164164
const SizedBox(height: 20),
165165
_buildSectionHeader(context, "Appearance"),
166-
_buildSwitchTile(
166+
_buildSettingCard(
167167
context,
168-
title: "Dark Mode",
169-
value: themeMode == ThemeMode.dark,
170-
onChanged: (val) {
171-
ref.read(themeModeProvider.notifier).state =
172-
val ? ThemeMode.dark : ThemeMode.light;
173-
dataBase.savePreference('darkMode', val);
174-
if (Platform.isAndroid) {
175-
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
176-
systemNavigationBarColor:
177-
val ? Colors.black : Colors.grey.shade200));
178-
}
179-
},
168+
title: "Theme",
169+
child: Padding(
170+
padding:
171+
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
172+
child: DropdownButtonFormField<ThemeMode>(
173+
value: themeMode,
174+
decoration: const InputDecoration(
175+
border: InputBorder.none,
176+
contentPadding: EdgeInsets.zero,
177+
),
178+
items: const [
179+
DropdownMenuItem(
180+
value: ThemeMode.system,
181+
child: Text("Follow the System")),
182+
DropdownMenuItem(
183+
value: ThemeMode.light, child: Text("Light theme")),
184+
DropdownMenuItem(
185+
value: ThemeMode.dark, child: Text("Dark theme")),
186+
],
187+
onChanged: (ThemeMode? val) {
188+
if (val != null) {
189+
ref.read(themeModeProvider.notifier).setTheme(val);
190+
}
191+
},
192+
),
193+
),
180194
),
181195
_buildSettingCard(
182196
context,

linux/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(runner LANGUAGES CXX)
44

55
# The name of the executable created for the application. Change this to change
66
# the on-disk name of your application.
7-
set(BINARY_NAME "OpenlibExtended")
7+
set(BINARY_NAME "OpenLibExtended")
88
# The unique GTK application identifier for this application. See:
99
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
1010
set(APPLICATION_ID "dev.wath.openlibextended")
@@ -100,6 +100,12 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
100100
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
101101
endif()
102102

103+
# If the install prefix is /usr/local, it's likely the default from a previous run
104+
# or system setting, but we want to install to the local bundle directory.
105+
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr/local")
106+
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
107+
endif()
108+
103109
# Start with a clean build bundle directory every time.
104110
install(CODE "
105111
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")

0 commit comments

Comments
 (0)