Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add appearance page, add font size adjust #54

Merged
merged 2 commits into from
Jun 29, 2023
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
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { AppContextProvider } from "./features/auth/AppContext";
import Router from "./Router";
import BeforeInstallPromptProvider from "./BeforeInstallPromptProvider";
import { UpdateContextProvider } from "./pages/settings/update/UpdateContext";
import GlobalStyles from "./GlobalStyles";

setupIonicReact({
rippleEffect: false,
Expand All @@ -39,6 +40,7 @@ export default function App() {
return (
<AppContextProvider>
<Provider store={store}>
<GlobalStyles />
<BeforeInstallPromptProvider>
<UpdateContextProvider>
<Router>
Expand Down
30 changes: 30 additions & 0 deletions src/GlobalStyles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Global, css } from "@emotion/react";
import { useAppSelector } from "./store";

export default function GlobalStyles() {
const { fontSizeMultiplier, useSystemFontSize } = useAppSelector(
(state) => state.appearance.font
);

const baseFontStyles = useSystemFontSize
? css`
font: -apple-system-body;
`
: css`
font-size: ${fontSizeMultiplier}rem;
`;

return (
<Global
styles={css`
html {
${baseFontStyles}

ion-content ion-item {
font-size: 1rem;
}
}
`}
/>
);
}
4 changes: 4 additions & 0 deletions src/TabbedRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import UpdateAppPage from "./pages/settings/UpdateAppPage";
import useShouldInstall from "./features/pwa/useShouldInstall";
import { UpdateContext } from "./pages/settings/update/UpdateContext";
import { LEMMY_SERVERS } from "./helpers/lemmy";
import AppearancePage from "./pages/settings/AppearancePage";

const Interceptor = styled.div`
position: absolute;
Expand Down Expand Up @@ -314,6 +315,9 @@ export default function TabbedRoutes() {
<Route exact path="/settings/update">
<UpdateAppPage />
</Route>
<Route exact path="/settings/appearance">
<AppearancePage />
</Route>
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton
Expand Down
16 changes: 8 additions & 8 deletions src/features/post/detail/PostDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const CenteredSpinner = styled(IonSpinner)`
`;

const Container = styled.div`
margin: 0 0 1rem;
margin: 0 0 16px;
width: 100%;
`;

Expand All @@ -71,7 +71,7 @@ const LightboxImg = styled(Img)`
`;

const StyledMarkdown = styled(Markdown)`
margin: 1rem 0;
margin: 16px 0;

img {
display: block;
Expand All @@ -83,11 +83,11 @@ const StyledMarkdown = styled(Markdown)`
`;

const StyledEmbed = styled(Embed)`
margin: 1rem 0;
margin: 16px 0;
`;

const PostDeets = styled.div`
margin: 0 1rem;
margin: 0 16px;
font-size: 0.9em;

h1,
Expand All @@ -102,12 +102,12 @@ const PostDeets = styled.div`

const Title = styled.div`
font-size: 1.3em;
padding: 1rem 0 0;
margin-bottom: 1rem;
padding: 16px 0 0;
margin-bottom: 16px;
`;

const By = styled.div`
margin-bottom: 0.3rem;
margin-bottom: 5px;
color: var(--ion-color-medium);

white-space: nowrap;
Expand All @@ -117,7 +117,7 @@ const By = styled.div`

export const AnnouncementIcon = styled(IonIcon)`
font-size: 1.1rem;
margin-right: 0.3rem;
margin-right: 5px;
vertical-align: middle;
color: var(--ion-color-success);
`;
Expand Down
2 changes: 2 additions & 0 deletions src/features/post/inFeed/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ const LeftDetails = styled.div`
display: flex;
flex-direction: column;
gap: 0.5rem;

min-width: 0;
`;

const RightDetails = styled.div`
Expand Down
85 changes: 85 additions & 0 deletions src/features/settings/appearance/TextSize.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import styled from "@emotion/styled";
import { css } from "@emotion/react";
import { IonLabel, IonList, IonRange, IonToggle } from "@ionic/react";
import { InsetIonItem } from "../../../pages/profile/ProfileFeedItemsPage";
import { useAppDispatch, useAppSelector } from "../../../store";
import { setFontSizeMultiplier, setUseSystemFontSize } from "./appearanceSlice";

const ListHeader = styled.div`
font-size: 0.8em;
margin: 32px 0 -8px 32px;
text-transform: uppercase;
color: var(--ion-color-medium);
`;

const Range = styled(IonRange)`
--bar-background: var(--ion-color-medium);

::part(tick) {
background: var(--ion-color-medium);
}
`;

const A = styled.div<{ small?: boolean }>`
font-size: 1.3em;
padding: 0 0.5rem;
font-weight: 500;

${({ small }) =>
small &&
css`
font-size: 0.8em;
`}
`;

const HelperText = styled.div`
margin: 0 32px;
font-size: 0.9em;
color: var(--ion-color-medium);
`;

export default function TextSize() {
const dispatch = useAppDispatch();
const { fontSizeMultiplier, useSystemFontSize } = useAppSelector(
(state) => state.appearance.font
);

return (
<>
<ListHeader>
<IonLabel>Text size</IonLabel>
</ListHeader>
<IonList inset>
<InsetIonItem>
<IonLabel>Use System Text Size</IonLabel>
<IonToggle
checked={useSystemFontSize}
onIonChange={(e) =>
dispatch(setUseSystemFontSize(e.detail.checked))
}
/>
</InsetIonItem>
<InsetIonItem>
<Range
disabled={useSystemFontSize}
ticks
snaps
min={0.8}
max={1.6}
step={0.1}
value={fontSizeMultiplier}
onIonInput={(e) => {
dispatch(setFontSizeMultiplier(e.detail.value as number));
}}
>
<A slot="start" small>
A
</A>
<A slot="end">A</A>
</Range>
</InsetIonItem>
</IonList>
<HelperText>Default is two ticks from the left.</HelperText>
</>
);
}
55 changes: 55 additions & 0 deletions src/features/settings/appearance/appearanceSlice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
import { get, set } from "../storage";
import { merge } from "lodash";

const STORAGE_KEYS = {
FONT: {
FONT_SIZE_MULTIPLIER: "appearance--font-size-multiplier",
USE_SYSTEM: "appearance--font-use-system",
},
} as const;

interface AppearanceState {
font: {
fontSizeMultiplier: number;
useSystemFontSize: boolean;
};
}

const initialState: AppearanceState = {
font: {
fontSizeMultiplier: 1,
useSystemFontSize: false,
},
};

const stateFromStorage: AppearanceState = merge(initialState, {
font: {
fontSizeMultiplier: get(STORAGE_KEYS.FONT.FONT_SIZE_MULTIPLIER),
useSystemFontSize: get(STORAGE_KEYS.FONT.USE_SYSTEM),
},
});

export const appearanceSlice = createSlice({
name: "appearance",
initialState: stateFromStorage,
reducers: {
setFontSizeMultiplier(state, action: PayloadAction<number>) {
state.font.fontSizeMultiplier = action.payload;

set(STORAGE_KEYS.FONT.FONT_SIZE_MULTIPLIER, action.payload);
},
setUseSystemFontSize(state, action: PayloadAction<boolean>) {
state.font.useSystemFontSize = action.payload;

set(STORAGE_KEYS.FONT.USE_SYSTEM, action.payload);
},

resetAppearance: () => initialState,
},
});

export const { setFontSizeMultiplier, setUseSystemFontSize } =
appearanceSlice.actions;

export default appearanceSlice.reducer;
10 changes: 10 additions & 0 deletions src/features/settings/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function get(key: string): any {
const data = localStorage.getItem(key);
if (!data) return;
return JSON.parse(data);
}

export function set(key: string, value: unknown) {
localStorage.setItem(key, JSON.stringify(value));
}
2 changes: 1 addition & 1 deletion src/features/user/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const InsetIonItem = styled(IonItem)`
`;

export const SettingLabel = styled(IonLabel)`
margin-left: 1rem;
margin-left: 16px;
`;

interface ProfileProps {
Expand Down
6 changes: 0 additions & 6 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,3 @@ ion-modal.small {
ion-modal.small ion-header ion-toolbar:first-of-type {
padding-top: 0px;
}

/* TODO: Native font scaling */
/* (Need a configurable option first) */
/* body ion-content ion-item {
font: -apple-system-body;
} */
2 changes: 1 addition & 1 deletion src/pages/profile/ProfileFeedItemsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const InsetIonItem = styled(IonItem)`
`;

export const SettingLabel = styled(IonLabel)`
margin-left: 1rem;
margin-left: 16px;
`;

interface ProfileFeedItemsPageProps {
Expand Down
29 changes: 29 additions & 0 deletions src/pages/settings/AppearancePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
IonBackButton,
IonButtons,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
} from "@ionic/react";
import AppContent from "../../features/shared/AppContent";
import TextSize from "../../features/settings/appearance/TextSize";

export default function AppearancePage() {
return (
<IonPage className="grey-bg">
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton defaultHref="/settings" text="Settings" />
</IonButtons>

<IonTitle>Appearance</IonTitle>
</IonToolbar>
</IonHeader>
<AppContent scrollY>
<TextSize />
</AppContent>
</IonPage>
);
}
Loading