diff --git a/src/assets/images/members/others/sasakikotoko_2020-10-14.jpg b/src/assets/images/members/others/sasakikotoko_2020-10-14.jpg new file mode 100644 index 00000000000..2d35bafd1b8 Binary files /dev/null and b/src/assets/images/members/others/sasakikotoko_2020-10-14.jpg differ diff --git a/src/client/hooks/useDarkModeMediaQuery.ts b/src/client/hooks/useDarkModeMediaQuery.ts index 6bd7bd68230..0bb84a23f2b 100644 --- a/src/client/hooks/useDarkModeMediaQuery.ts +++ b/src/client/hooks/useDarkModeMediaQuery.ts @@ -1,7 +1,9 @@ import * as React from 'react'; import { Context } from 'client/store/app/context'; -export const useDarkModeMediaQuery = () => { +type DarkModeQueryEventHandler = (event: MediaQueryListEvent) => void; + +export function useDarkModeMediaQuery() { const { themeMode, setThemeKey } = React.useContext(Context); React.useEffect(() => { @@ -9,14 +11,10 @@ export const useDarkModeMediaQuery = () => { '(prefers-color-scheme: dark)' ); - // Change theme when system settings have been changed - const handleDarkModeQueryChange = (event: MediaQueryListEvent) => { - if (event.matches) { - setThemeKey('dark'); - } else { - setThemeKey('light'); - } - }; + const handleDarkModeQueryChange = createDarkModeQueryChangeHandler({ + onMatch: () => setThemeKey('dark'), + onUnMatch: () => setThemeKey('light'), + }); // Auto change theme based on system settings if (themeMode === 'auto') { @@ -30,25 +28,54 @@ export const useDarkModeMediaQuery = () => { } } - if (typeof darkModeMediaQuery.addEventListener === 'function') { - darkModeMediaQuery.addEventListener( - 'change', - handleDarkModeQueryChange - ); - } else { - darkModeMediaQuery.addListener(handleDarkModeQueryChange); - } + subscribeDarkModeMediaQueryEventListeners( + darkModeMediaQuery, + handleDarkModeQueryChange + ); } return () => { - if (typeof darkModeMediaQuery.addEventListener === 'function') { - darkModeMediaQuery.removeEventListener( - 'change', - handleDarkModeQueryChange - ); - } else { - darkModeMediaQuery.removeListener(handleDarkModeQueryChange); - } + clearUpDarkModeMediaQueryEventListeners( + darkModeMediaQuery, + handleDarkModeQueryChange + ); }; }, [themeMode, setThemeKey]); -}; +} + +function createDarkModeQueryChangeHandler(params: { + onMatch(): void; + onUnMatch(): void; +}): DarkModeQueryEventHandler { + function handleDarkModeQueryChange(event: MediaQueryListEvent) { + if (event.matches) { + params.onMatch(); + } else { + params.onUnMatch(); + } + } + + return handleDarkModeQueryChange; +} + +function subscribeDarkModeMediaQueryEventListeners( + darkModeMediaQuery: MediaQueryList, + onDarkModeQueryChange: DarkModeQueryEventHandler +) { + if (typeof darkModeMediaQuery.addEventListener === 'function') { + darkModeMediaQuery.addEventListener('change', onDarkModeQueryChange); + } else { + darkModeMediaQuery.addListener(onDarkModeQueryChange); + } +} + +function clearUpDarkModeMediaQueryEventListeners( + darkModeMediaQuery: MediaQueryList, + onDarkModeQueryChange: DarkModeQueryEventHandler +) { + if (typeof darkModeMediaQuery.addEventListener === 'function') { + darkModeMediaQuery.removeEventListener('change', onDarkModeQueryChange); + } else { + darkModeMediaQuery.removeListener(onDarkModeQueryChange); + } +} diff --git a/src/client/hooks/useLocalStorageForContenxt.ts b/src/client/hooks/useLocalStorageForContext.ts similarity index 100% rename from src/client/hooks/useLocalStorageForContenxt.ts rename to src/client/hooks/useLocalStorageForContext.ts diff --git a/src/client/store/app/context.tsx b/src/client/store/app/context.tsx index e4f398cc2e2..278337ecdb5 100644 --- a/src/client/store/app/context.tsx +++ b/src/client/store/app/context.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { getInitialState, reducer } from 'client/store/app/reducer'; +import { getInitialState, reducer, State } from 'client/store/app/reducer'; import { ThemeMode } from 'client/types/themeMode'; import { ThemeKey } from 'client/styles/colors'; import { @@ -8,10 +8,7 @@ import { } from 'client/utils/constants'; import { Language } from 'client/types/language'; -type Context = { - themeMode: ThemeMode; - themeKey: ThemeKey; - language: Language; +type Context = State & { setThemeKey(themeKey: ThemeKey): void; setTheme(themeMode: ThemeMode): void; setLanguage(language: Language): void; diff --git a/src/client/store/app/reducer.ts b/src/client/store/app/reducer.ts index 9f878346e15..417dabd7bad 100644 --- a/src/client/store/app/reducer.ts +++ b/src/client/store/app/reducer.ts @@ -2,7 +2,7 @@ import { ThemeKey } from 'client/styles/colors'; import { Language } from 'client/types/language'; import { ThemeMode } from 'client/types/themeMode'; -type State = { +export type State = { themeMode: ThemeMode; themeKey: ThemeKey; language: Language; diff --git a/src/client/store/theme/context.tsx b/src/client/store/theme/context.tsx index af2f2cfd3f9..34fb71e9bea 100644 --- a/src/client/store/theme/context.tsx +++ b/src/client/store/theme/context.tsx @@ -5,7 +5,7 @@ import { ThemeProvider as EmotionThemeProvider } from 'emotion-theming'; import { themes } from 'client/styles/tokens'; import { useDarkModeMediaQuery } from 'client/hooks/useDarkModeMediaQuery'; import { useAppContext } from 'client/hooks/useAppContext'; -import { useLocalStorageForContext } from 'client/hooks/useLocalStorageForContenxt'; +import { useLocalStorageForContext } from 'client/hooks/useLocalStorageForContext'; export const ThemeProvider: React.FC = props => { const { themeKey } = useAppContext(); diff --git a/src/data/members.json b/src/data/members.json index 3dd83a0d9a6..8b94f510f58 100644 --- a/src/data/members.json +++ b/src/data/members.json @@ -12378,7 +12378,8 @@ "members/singles/20/sasakikotoko.jpg", "members/singles/22/sasakikotoko.jpg", "members/singles/24/sasakikotoko.jpg", - "members/singles/25/sasakikotoko.jpg" + "members/singles/25/sasakikotoko.jpg", + "members/others/sasakikotoko_2020-10-14.jpg" ], "singles": [ { @@ -12524,6 +12525,10 @@ { "title": "Instagram", "url": "https://www.instagram.com/sasaki_kotoko828/" + }, + { + "title": "Twitter", + "url": "https://twitter.com/ssk_ktk828" } ], "photoAlbums": [], diff --git a/src/server/actors/Members/raw/editor/secondGen.ts b/src/server/actors/Members/raw/editor/secondGen.ts index 7c6e5f04dac..f46b67253c8 100644 --- a/src/server/actors/Members/raw/editor/secondGen.ts +++ b/src/server/actors/Members/raw/editor/secondGen.ts @@ -114,6 +114,10 @@ export const SECOND_GEN_MEMBERS: MemberRaw[] = [ title: SocialMedia.Instagram, url: 'https://www.instagram.com/sasaki_kotoko828/', }, + { + title: SocialMedia.Twitter, + url: 'https://twitter.com/ssk_ktk828', + }, ], graduatedDate: '2020-03-31', }),