diff --git a/src/App.tsx b/src/App.tsx
index 3063c3533b..151fbbabd0 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -27,12 +27,12 @@ import { UpdateContextProvider } from "./pages/settings/update/UpdateContext";
import GlobalStyles from "./GlobalStyles";
import GalleryProvider from "./features/gallery/GalleryProvider";
import ConfigProvider from "./services/app";
+import { getDeviceMode } from "./features/settings/settingsSlice";
setupIonicReact({
rippleEffect: false,
- mode: "ios",
- swipeBackEnabled: isInstalled(),
- hardwareBackButton: true,
+ mode: getDeviceMode(),
+ swipeBackEnabled: isInstalled() && getDeviceMode() === "ios",
});
export default function App() {
diff --git a/src/TabbedRoutes.tsx b/src/TabbedRoutes.tsx
index 1d9136ff88..0d6f9a4c55 100644
--- a/src/TabbedRoutes.tsx
+++ b/src/TabbedRoutes.tsx
@@ -57,6 +57,7 @@ import BlocksSettingsPage from "./pages/settings/BlocksSettingsPage";
import { getDefaultServer } from "./services/app";
import GeneralPage from "./pages/settings/GeneralPage";
import HidingSettingsPage from "./pages/settings/HidingSettingsPage";
+import DeviceModeSettingsPage from "./pages/settings/DeviceModeSettingsPage";
const Interceptor = styled.div`
position: absolute;
@@ -335,6 +336,9 @@ export default function TabbedRoutes() {
+
+
+
diff --git a/src/features/settings/appearance/system/DarkMode.tsx b/src/features/settings/appearance/system/DarkMode.tsx
index 6c35ee8ca3..033e0d1376 100644
--- a/src/features/settings/appearance/system/DarkMode.tsx
+++ b/src/features/settings/appearance/system/DarkMode.tsx
@@ -1,8 +1,7 @@
-import { IonLabel, IonList, IonToggle } from "@ionic/react";
+import { IonLabel, IonToggle } from "@ionic/react";
import { InsetIonItem } from "../../../../pages/profile/ProfileFeedItemsPage";
import { useAppDispatch, useAppSelector } from "../../../../store";
import { setUseSystemDarkMode } from "../../settingsSlice";
-import UserDarkMode from "./UserDarkMode";
export default function DarkMode() {
const dispatch = useAppDispatch();
@@ -11,20 +10,12 @@ export default function DarkMode() {
);
return (
- <>
-
-
- Use System Light/Dark Mode
-
- dispatch(setUseSystemDarkMode(e.detail.checked))
- }
- />
-
-
-
- {!usingSystemDarkMode && }
- >
+
+ Use System Light/Dark Mode
+ dispatch(setUseSystemDarkMode(e.detail.checked))}
+ />
+
);
}
diff --git a/src/features/settings/appearance/system/DeviceMode.tsx b/src/features/settings/appearance/system/DeviceMode.tsx
new file mode 100644
index 0000000000..63db833560
--- /dev/null
+++ b/src/features/settings/appearance/system/DeviceMode.tsx
@@ -0,0 +1,30 @@
+import { Mode } from "@ionic/core";
+import { useAppSelector } from "../../../../store";
+import { InsetIonItem } from "../../../user/Profile";
+import { IonLabel } from "@ionic/react";
+
+export default function DeviceMode() {
+ const deviceMode = useAppSelector(
+ (state) => state.settings.appearance.deviceMode
+ );
+
+ return (
+ <>
+
+ Device Mode
+
+ {getDeviceModeLabel(deviceMode)}
+
+
+ >
+ );
+}
+
+export function getDeviceModeLabel(mode: Mode): string {
+ switch (mode) {
+ case "ios":
+ return "Apple";
+ case "md":
+ return "Android (beta)";
+ }
+}
diff --git a/src/features/settings/appearance/system/SelectDeviceMode.tsx b/src/features/settings/appearance/system/SelectDeviceMode.tsx
new file mode 100644
index 0000000000..6139005967
--- /dev/null
+++ b/src/features/settings/appearance/system/SelectDeviceMode.tsx
@@ -0,0 +1,49 @@
+import { IonLabel, IonList, IonRadio, IonRadioGroup } from "@ionic/react";
+import { InsetIonItem } from "../../../user/Profile";
+import { getDeviceModeLabel } from "./DeviceMode";
+import { useAppDispatch, useAppSelector } from "../../../../store";
+import { useState } from "react";
+import { setDeviceMode } from "../../settingsSlice";
+
+const MODES = ["ios", "md"] as const;
+
+export default function SelectDeviceMode() {
+ const dispatch = useAppDispatch();
+ const deviceMode = useAppSelector(
+ (state) => state.settings.appearance.deviceMode
+ );
+ const [selectedDeviceMode, setSelectedDeviceMode] = useState(deviceMode);
+
+ function apply() {
+ dispatch(setDeviceMode(selectedDeviceMode));
+ location.reload();
+ }
+ return (
+ <>
+ setSelectedDeviceMode(e.detail.value)}
+ >
+
+ {MODES.map((mode) => (
+ setSelectedDeviceMode(mode)}
+ >
+ {getDeviceModeLabel(mode)}
+
+
+ ))}
+
+
+
+ {selectedDeviceMode !== deviceMode && (
+
+
+ Tap to apply changes and reload app
+
+
+ )}
+ >
+ );
+}
diff --git a/src/features/settings/appearance/system/System.tsx b/src/features/settings/appearance/system/System.tsx
index eca7afc0a0..03aada0b90 100644
--- a/src/features/settings/appearance/system/System.tsx
+++ b/src/features/settings/appearance/system/System.tsx
@@ -1,14 +1,26 @@
-import { IonLabel } from "@ionic/react";
+import { IonLabel, IonList } from "@ionic/react";
import DarkMode from "./DarkMode";
import { ListHeader } from "../TextSize";
+import DeviceMode from "./DeviceMode";
+import { useAppSelector } from "../../../../store";
+import UserDarkMode from "./UserDarkMode";
export default function System() {
+ const { usingSystemDarkMode } = useAppSelector(
+ (state) => state.settings.appearance.dark
+ );
+
return (
<>
System
-
+
+
+
+
+
+ {!usingSystemDarkMode && }
>
);
}
diff --git a/src/features/settings/settingsSlice.tsx b/src/features/settings/settingsSlice.tsx
index 73afedb000..43641f88fd 100644
--- a/src/features/settings/settingsSlice.tsx
+++ b/src/features/settings/settingsSlice.tsx
@@ -21,6 +21,7 @@ import {
OCommentDefaultSort,
} from "../../services/db";
import { get, set } from "./storage";
+import { Mode } from "@ionic/core";
export {
type CommentThreadCollapse,
@@ -50,6 +51,7 @@ interface SettingsState {
usingSystemDarkMode: boolean;
userDarkMode: boolean;
};
+ deviceMode: Mode;
};
general: {
comments: {
@@ -72,6 +74,7 @@ const LOCALSTORAGE_KEYS = {
USE_SYSTEM: "appearance--dark-use-system",
USER_MODE: "appearance--dark-user-mode",
},
+ DEVICE_MODE: "appearance--device-mode",
} as const;
const initialState: SettingsState = {
@@ -93,6 +96,7 @@ const initialState: SettingsState = {
usingSystemDarkMode: true,
userDarkMode: false,
},
+ deviceMode: "ios",
},
general: {
comments: {
@@ -118,6 +122,7 @@ const stateWithLocalstorageItems: SettingsState = merge(initialState, {
usingSystemDarkMode: get(LOCALSTORAGE_KEYS.DARK.USE_SYSTEM),
userDarkMode: get(LOCALSTORAGE_KEYS.DARK.USER_MODE),
},
+ deviceMode: get(LOCALSTORAGE_KEYS.DEVICE_MODE),
},
});
@@ -194,6 +199,11 @@ export const appearanceSlice = createSlice({
set(LOCALSTORAGE_KEYS.DARK.USE_SYSTEM, action.payload);
},
+ setDeviceMode(state, action: PayloadAction) {
+ state.appearance.deviceMode = action.payload;
+
+ set(LOCALSTORAGE_KEYS.DEVICE_MODE, action.payload);
+ },
setDefaultCommentSort(state, action: PayloadAction) {
state.general.comments.sort = action.payload;
@@ -331,6 +341,7 @@ export const {
setShowVotingButtons,
setUserDarkMode,
setUseSystemDarkMode,
+ setDeviceMode,
setDefaultCommentSort,
settingsReady,
setDisableMarkingPostsRead,
@@ -338,3 +349,8 @@ export const {
} = appearanceSlice.actions;
export default appearanceSlice.reducer;
+
+export function getDeviceMode(): Mode {
+ // md mode is beta, so default ios for all devices
+ return get(LOCALSTORAGE_KEYS.DEVICE_MODE) ?? "ios";
+}
diff --git a/src/pages/settings/DeviceModeSettingsPage.tsx b/src/pages/settings/DeviceModeSettingsPage.tsx
new file mode 100644
index 0000000000..1f3f9fe4b7
--- /dev/null
+++ b/src/pages/settings/DeviceModeSettingsPage.tsx
@@ -0,0 +1,32 @@
+import {
+ IonBackButton,
+ IonButtons,
+ IonHeader,
+ IonPage,
+ IonTitle,
+ IonToolbar,
+} from "@ionic/react";
+import AppContent from "../../features/shared/AppContent";
+import SelectDeviceMode from "../../features/settings/appearance/system/SelectDeviceMode";
+
+export default function DeviceModeSettingsPage() {
+ return (
+
+
+
+
+
+
+
+ Device Mode
+
+
+
+
+
+
+ );
+}
diff --git a/src/theme/variables.ts b/src/theme/variables.ts
index 8b11ad5d75..49bb467007 100644
--- a/src/theme/variables.ts
+++ b/src/theme/variables.ts
@@ -252,7 +252,7 @@ export const darkVariables = css`
// Material Design Dark Theme
.md body {
- --ion-background-color: #121212;
+ --ion-background-color: black;
--ion-background-color-rgb: 18, 18, 18;
--ion-text-color: #ffffff;
@@ -260,7 +260,7 @@ export const darkVariables = css`
--ion-border-color: #222222;
- --ion-color-step-50: #1e1e1e;
+ --ion-color-step-50: #121212;
--ion-color-step-100: #2a2a2a;
--ion-color-step-150: #363636;
--ion-color-step-200: #414141;
@@ -280,13 +280,16 @@ export const darkVariables = css`
--ion-color-step-900: #e7e7e7;
--ion-color-step-950: #f3f3f3;
- --ion-item-background: #1e1e1e;
+ --ion-item-background: black;
--ion-toolbar-background: #1f1f1f;
--ion-tab-bar-background: #1f1f1f;
- --ion-card-background: #1e1e1e;
+ --ion-card-background: black;
+
+ --ion-toolbar-background: #121212;
+ --ion-tab-bar-background: #121212;
}
@media (max-width: 767px) {