Skip to content

Commit

Permalink
Merge pull request #18 from arikama/show-hide-surah
Browse files Browse the repository at this point in the history
UI changes
  • Loading branch information
cglotr authored Sep 17, 2022
2 parents ce5fea1 + 4126548 commit eaea61d
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 24 deletions.
4 changes: 2 additions & 2 deletions __tests__/pages/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ describe('IndexPage', () => {
const result = await getStaticProps({}) as unknown as { props: Props }
render(<IndexPage surahInfos={result.props.surahInfos} />)

expect(await screen.findByText('1')).toBeInTheDocument()
expect(((await screen.findAllByText('1')).length)).not.toEqual(0)
expect(await screen.findByText('The Opening')).toBeInTheDocument()
expect(await screen.findByText('ٱلْفَاتِحَة')).toBeInTheDocument()

expect(await screen.findByText('114')).toBeInTheDocument()
expect(((await screen.findAllByText('114')).length)).not.toEqual(0)
expect(await screen.findByText('Mankind')).toBeInTheDocument()
expect(await screen.findByText('ٱلنَّاس')).toBeInTheDocument()
})
Expand Down
15 changes: 15 additions & 0 deletions src/components/show_hide_button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Button } from "./button"

export const ShowHideButton = (props: {
what: string
isHiding: boolean
onClick: () => void
}) => {
return (
<Button
onClick={props.onClick}
>
{props.isHiding ? "show" : "hide"}&nbsp;{props.what}
</Button>
)
}
7 changes: 5 additions & 2 deletions src/constants/storage.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export const USER_LOCAL_STORAGE_KEY = "userlocalstoragekey"
export const BOOKMARK_SETTINGS_STORAGE_KEY = "bookmarksettingsstoragekey"
export const STORAGE = {
USER_LOCAL_STORAGE_KEY: "userlocalstoragekey",
BOOKMARK_SETTINGS_STORAGE_KEY: "bookmarksettingsstoragekey",
SURAH_SETTINGS_STORAGE_KEY: "surahsettingsstoragekey"
}
9 changes: 5 additions & 4 deletions src/hooks/use_bookmark_settings.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useEffect, useState } from "react"

import { BOOKMARK_SETTINGS_STORAGE_KEY } from "../constants/storage"
import { BookmarkSettings } from "../types/bookmark_settings"
import { STORAGE } from "../constants/storage"

import type { BookmarkSettings } from "../types/bookmark_settings"

export function useBookmarkSettings() {
const [bookmarkSettings, setBookmarkSettings] = useState<BookmarkSettings>({
Expand All @@ -11,7 +12,7 @@ export function useBookmarkSettings() {

useEffect(() => {
if (typeof window !== "undefined") {
const blob = window.localStorage.getItem(BOOKMARK_SETTINGS_STORAGE_KEY)
const blob = window.localStorage.getItem(STORAGE.BOOKMARK_SETTINGS_STORAGE_KEY)
if (blob) {
const parsed = JSON.parse(blob) as BookmarkSettings
if (parsed) {
Expand All @@ -24,7 +25,7 @@ export function useBookmarkSettings() {
const updateBookmarkSettings = (update: BookmarkSettings) => {
if (typeof window !== "undefined") {
const blob = JSON.stringify(update)
window.localStorage.setItem(BOOKMARK_SETTINGS_STORAGE_KEY, blob)
window.localStorage.setItem(STORAGE.BOOKMARK_SETTINGS_STORAGE_KEY, blob)
}
setBookmarkSettings(update)
}
Expand Down
30 changes: 30 additions & 0 deletions src/hooks/use_persistent_state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useEffect, useState } from "react"

export function usePersistentState<T>(storageKey: string, initialState: T): [T, (newState: T) => boolean] {
const [state, setState] = useState<T>(initialState)

useEffect(() => {
if (typeof window !== "undefined") {
const blob = window.localStorage.getItem(storageKey)
if (blob) {
const parsed = JSON.parse(blob) as T
if (parsed) {
setState(parsed)
}
}
}
}, [storageKey])

const update = (newState: T) => {
setState(newState)
if (typeof window !== "undefined") {
const blob = JSON.stringify(newState)
window.localStorage.setItem(storageKey, blob)
return true
} else {
return false
}
}

return [state, update]
}
6 changes: 3 additions & 3 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import "../styles/globals.css"
import { AppNav } from "../components/app_nav"
import { GoogleAuthApiImpl } from "../apis/google_auth_api_impl"
import { KoranApiImpl } from "../apis/koran_api_impl"
import { USER_LOCAL_STORAGE_KEY } from "../constants/storage"
import { STORAGE } from "../constants/storage"
import { UserApiImpl } from "../apis/user_api_impl"
import { triggerGtmPageview } from "../utils/trigger_gtm_pageview"

Expand Down Expand Up @@ -51,7 +51,7 @@ function MyApp({ Component, pageProps }: AppProps) {

useEffect(() => {
if (typeof window !== "undefined") {
const userBlob = window.localStorage.getItem(USER_LOCAL_STORAGE_KEY)
const userBlob = window.localStorage.getItem(STORAGE.USER_LOCAL_STORAGE_KEY)
if (userBlob) {
if (!user.token) {
setUser(JSON.parse(userBlob) as User)
Expand Down Expand Up @@ -86,7 +86,7 @@ function MyApp({ Component, pageProps }: AppProps) {
user: user,
updateUser: (user: User) => {
if (typeof window !== "undefined" && user) {
window.localStorage.setItem(USER_LOCAL_STORAGE_KEY, JSON.stringify(user))
window.localStorage.setItem(STORAGE.USER_LOCAL_STORAGE_KEY, JSON.stringify(user))
}
setUser(user)
},
Expand Down
36 changes: 35 additions & 1 deletion src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ const IndexPage: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (pro
const href = `/surahs/${surahInfo.surahId}`

return (
<div key={surahInfo.surahId.toString()}>
<div
id={surahInfo.surahId.toString()}
key={surahInfo.surahId.toString()}
>
<div
style={{
display: 'flex',
Expand All @@ -33,6 +36,7 @@ const IndexPage: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (pro
&nbsp;&nbsp;&nbsp;&nbsp;
<Button
onClick={() => {
router.push(`/#${surahInfo.surahId.toString()}`)
router.push(href)
}}
>
Expand All @@ -50,8 +54,38 @@ const IndexPage: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (pro
</div>
)
})

const renderShortcuts = () => {
const shortcuts = [25, 50, 75, 100, 114]
const buttons = shortcuts.map((surahId => {
const href = `/#${surahId}`
return (
<u
key={href}
onClick={() => {
router.push(href)
}}
>
{surahId}
</u>
)
}))
return (
<div
style={{
display: "flex",
justifyContent: "space-between",
fontSize: "0.9em"
}}
>
{buttons}
</div>
)
}

return (
<>
{renderShortcuts()}
{SurahInfos}
</>
)
Expand Down
151 changes: 139 additions & 12 deletions src/pages/surahs/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,85 @@ import {
import { Button } from './../../components/button'
import { GetStaticProps } from 'next'
import { KoranApiImpl } from './../../apis/koran_api_impl'
import { STORAGE } from '../../constants/storage'
import { ShowHideButton } from '../../components/show_hide_button'
import { usePersistentState } from '../../hooks/use_persistent_state'

import type { KoranApi } from './../../apis/koran_api'
import type { Surah } from './../../types/surah'
import type { SurahSettings } from '../../types/surah_settings'

export default function SurahPage(props: { surah: Surah }) {
const router = useRouter()
const [surahSettings, updateSurahSettings] = usePersistentState<SurahSettings>(
STORAGE.SURAH_SETTINGS_STORAGE_KEY,
{
hideVerse: false,
hideTranslation: false
},
)

const renderShowHideVerse = () => {
return (
<ShowHideButton
what="verse"
isHiding={surahSettings.hideVerse}
onClick={() => {
updateSurahSettings({
...surahSettings,
hideVerse: !surahSettings.hideVerse
})
}}
/>
)
}

const renderShowHideTranslation = () => {
return (
<ShowHideButton
what="translation"
isHiding={surahSettings.hideTranslation}
onClick={() => {
updateSurahSettings({
...surahSettings,
hideTranslation: !surahSettings.hideTranslation
})
}}
/>
)
}

const renderVerse = (verseText: string) => {
if (surahSettings.hideVerse) {
return <>&nbsp;</>
}
return (
<div
style={{
fontFamily: QURAN_FONT_FAMILY,
fontSize: QURAN_FONT_SIZE,
textAlign: 'right'
}}
>
{verseText}
</div>
)
}

const renderTranslation = (verseTranslation: string) => {
if (surahSettings.hideTranslation) {
return <>&nbsp;</>
}
return (
<div
style={{
fontSize: TRANSLATION_FONT_SIZE
}}
>
{verseTranslation}
</div>
)
}

const Verses = props.surah.verses.map((verse) => {
return (
Expand All @@ -42,32 +115,86 @@ export default function SurahPage(props: { surah: Surah }) {
back
</Button>
</div>
<div
style={{
fontFamily: QURAN_FONT_FAMILY,
fontSize: QURAN_FONT_SIZE,
textAlign: 'right'
{renderVerse(verse.text)}
{renderTranslation(verse.translation)}
<br />
<br />
</div>
)
})

const renderShortcuts = () => {
const surahSz = props.surah.verses.length
const set = new Set<number>([
Math.round(surahSz * 0.25),
Math.round(surahSz * 0.5),
Math.round(surahSz * 0.75),
Math.round(surahSz * 1.0),
])
const shortcuts = Array.from(set).sort((a, b) => {
if (a === b) {
return 0
}
if (a < b) {
return -1
} else {
return 1
}
})
const buttons = shortcuts.map((verseId => {
const href = `/surahs/${props.surah.surahId}/#${verseId}`
return (
<u
key={href}
onClick={() => {
router.push(href)
}}
>
{verse.text}
</div>
{verseId}
</u>
)
}))
return (
<div
style={{
fontSize: "0.9em"
}}
>
<div
style={{
fontSize: TRANSLATION_FONT_SIZE
display: "flex",
justifyContent: "space-between"
}}
>
{verse.translation}
{buttons}
</div>
<br />
<br />
&nbsp;
</div>
)
})
}

return (
<>
<Head>
<title>{props.surah.englishName}</title>
</Head>
{renderShortcuts()}
<div
style={{
fontSize: "0.9em",
}}
>
<div
style={{
display: "flex",
justifyContent: "flex-end"
}}
>
{renderShowHideVerse()}
{renderShowHideTranslation()}
</div>
&nbsp;
</div>
{Verses}
</>
)
Expand Down
4 changes: 4 additions & 0 deletions src/types/surah_settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type SurahSettings = {
hideVerse: boolean
hideTranslation: boolean
}

0 comments on commit eaea61d

Please sign in to comment.