-
Notifications
You must be signed in to change notification settings - Fork 4
Community Audio #727
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
Merged
Merged
Community Audio #727
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
d778546
feat: added audio icon in testaments, started community audio page
BogdanLi d961ecf
feat: refactored community audio component till everything works fine
BogdanLi b51f6b2
feat: implemented verses component
BogdanLi f21a575
feat: started recorder component
BogdanLi e477517
feat: made recording, pausing, stoping and playing
BogdanLi b555a0a
feat: finished recorder
BogdanLi a209a15
feat: made font size adjustment
BogdanLi 2d704c4
feat: made simple teleprompter functionality
BogdanLi d3938a7
feat: minor refactor
BogdanLi 685dca3
feat: minor fixes
BogdanLi 6297539
Merge branch 'feature-bogdan-706' of https://github.com/BogdanLi/leve…
BogdanLi 6cc562e
Merge branch 'develop' of https://github.com/BogdanLi/level into feat…
BogdanLi 4df1b18
feat: fixed conflict
BogdanLi 8ec0fc0
feat: max speed 15
BogdanLi 634720b
feat: added filename
BogdanLi e8d0b55
feat: lint fix
BogdanLi c251096
feat: converted to mp3
BogdanLi 0bb9c6c
feat: minor fixes
BogdanLi 470bfba
feat: finished comments fixes
BogdanLi 8739e92
feat: removed lamejs
BogdanLi 2e259ed
Merge branch 'develop' of https://github.com/BogdanLi/level into feat…
BogdanLi 4554fe6
feat: fixed on comments, added lamejs
BogdanLi 392500d
feat: mp3 converter
BogdanLi 59c387e
feat: added recorder loading after recording stopped
BogdanLi 817ddf5
feat: fixed on comments
BogdanLi f3b99dd
feat: comments fix
BogdanLi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import AudioPause from 'public/icons/audioPause.svg' | ||
| import AudioPlay from 'public/icons/audioPlay.svg' | ||
| import Download from 'public/icons/download-audio.svg' | ||
| import Loading from 'public/icons/progress.svg' | ||
|
|
||
| export default function AudioPreview({ | ||
| audioUrl, | ||
| onPlay, | ||
| onPause, | ||
| isPlaying, | ||
| audioName, | ||
| loading, | ||
| }) { | ||
| return ( | ||
| <div | ||
| className={`flex items-center gap-2 rounded-full border border-th-text-primary p-2 ${ | ||
| !audioUrl || loading ? 'opacity-70' : '' | ||
| }`} | ||
| > | ||
| <p className="text-sm">{audioName || 'audio'}</p> | ||
| <a | ||
| href={audioUrl || ''} | ||
| className="disabled:fill-gray-400" | ||
| download={`${audioName || 'audio'}.mp3`} | ||
| > | ||
| {loading && !audioUrl ? ( | ||
| <Loading className="progress-custom-colors h-5 w-5 animate-spin stroke-th-secondary-100" /> | ||
| ) : ( | ||
| <Download /> | ||
| )} | ||
| </a> | ||
| <button | ||
| disabled={!audioUrl} | ||
| className="rounded-full bg-th-secondary-400 p-2 disabled:bg-th-text-primary" | ||
| onClick={isPlaying ? onPause : onPlay} | ||
| > | ||
| {loading ? ( | ||
| <Loading className="progress-custom-colors h-5 w-5 animate-spin stroke-th-secondary-100" /> | ||
| ) : isPlaying ? ( | ||
| <AudioPause className="h-5 w-5" /> | ||
| ) : ( | ||
| <AudioPlay className="h-5 w-5" /> | ||
| )} | ||
| </button> | ||
| </div> | ||
| ) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,210 @@ | ||
| import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react' | ||
|
|
||
| import { useRouter } from 'next/router' | ||
|
|
||
| import { Disclosure, Tab } from '@headlessui/react' | ||
| import { useTranslation } from 'next-i18next' | ||
|
|
||
| import ChecksIcon from 'components/Project/BookList/ChecksIcon' | ||
| import Card from 'components/Project/Card' | ||
|
|
||
| import { checkChapterVersesExist } from 'utils/helper' | ||
| import { useGetChaptersTranslate } from 'utils/hooks' | ||
|
|
||
| import Down from 'public/icons/arrow-down.svg' | ||
|
|
||
| function BookListReader({ books, setReference, reference, project, code }) { | ||
| const [currentBook, setCurrentBook] = useState(null) | ||
| const [createdOldTestamentBooks, createdNewTestamentBooks] = books | ||
| const { query, replace } = useRouter() | ||
| const { t } = useTranslation(['common', 'books']) | ||
| const refs = useRef([]) | ||
| const [chapters] = useGetChaptersTranslate({ code }) | ||
|
|
||
| const scrollRefs = useRef({}) | ||
| const handleClose = (index) => { | ||
| refs.current.map((closeFunction, refIndex) => { | ||
| if (refIndex !== index) { | ||
| closeFunction() | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| const handleScroll = (bookid) => { | ||
| if (scrollRefs?.current && Object.keys(scrollRefs?.current).length) { | ||
| verseRef(scrollRefs.current[bookid]) | ||
| } | ||
| } | ||
|
|
||
| const scrollTo = (currentBook, position) => { | ||
| let offset = 0 | ||
| const top = currentBook.offsetTop - 95 | ||
| switch (position) { | ||
| case 'center': | ||
| offset = currentBook.clientHeight / 2 - currentBook.parentNode.clientHeight / 2 | ||
| break | ||
| case 'top': | ||
| default: | ||
| break | ||
| } | ||
|
|
||
| currentBook.parentNode.scrollTo({ left: 0, top: top + offset, behavior: 'smooth' }) | ||
| } | ||
|
|
||
| const { tabs, defaultIndex } = useMemo(() => { | ||
| const index = [createdNewTestamentBooks, createdOldTestamentBooks]?.findIndex( | ||
| (list) => list?.find((el) => el.code === query.bookid) | ||
| ) | ||
|
|
||
| const tabs = | ||
| project?.type === 'obs' ? ['OpenBibleStories'] : ['NewTestament', 'OldTestament'] | ||
|
|
||
| const defaultIndex = index === -1 ? 0 : index | ||
|
|
||
| return { defaultIndex, tabs } | ||
| }, [createdNewTestamentBooks, createdOldTestamentBooks, query.bookid, project?.type]) | ||
|
|
||
| const verseRef = useCallback((node) => { | ||
| if (node !== null) { | ||
| setCurrentBook(node) | ||
| } | ||
| }, []) | ||
|
|
||
| useEffect(() => { | ||
| if (currentBook) { | ||
| scrollTo(currentBook, 'top') | ||
| } | ||
| }, [currentBook]) | ||
|
|
||
| useEffect(() => { | ||
| if (reference?.bookid) { | ||
| handleScroll(reference.bookid) | ||
| } | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, [reference?.bookid]) | ||
| return ( | ||
| <Card> | ||
| <div className="flex flex-col gap-7 bg-th-secondary-10"> | ||
| <Tab.Group defaultIndex={defaultIndex}> | ||
| <Tab.List className="-mt-6 flex w-full rounded-3xl border border-th-secondary-300 bg-th-secondary-10 p-1 shadow-md"> | ||
| {tabs.map((tab) => ( | ||
| <Tab as={Fragment} key={tab}> | ||
| {({ selected }) => ( | ||
| <div | ||
| className={`w-full cursor-pointer rounded-3xl p-2 text-center ${ | ||
| selected ? 'bg-th-primary-100 text-th-text-secondary-100' : '' | ||
| } `} | ||
| > | ||
| {t(tab)} | ||
| </div> | ||
| )} | ||
| </Tab> | ||
| ))} | ||
| </Tab.List> | ||
|
|
||
| <Tab.Panels className="text-sm font-bold"> | ||
| {[ | ||
| ...(createdNewTestamentBooks !== undefined | ||
| ? [createdNewTestamentBooks] | ||
| : []), | ||
| ...(createdOldTestamentBooks !== undefined | ||
| ? [createdOldTestamentBooks] | ||
| : []), | ||
| ].map((list, idx) => ( | ||
| <Tab.Panel key={idx} className="max-h-[70vh] overflow-y-scroll pr-4"> | ||
| {list?.map((book, index) => ( | ||
| <Disclosure | ||
| as={'div'} | ||
| key={book.code} | ||
| defaultOpen={query?.bookid === book.code} | ||
| ref={(ref) => (scrollRefs.current[book.code] = ref)} | ||
| > | ||
| {({ open, close }) => { | ||
| return ( | ||
| <> | ||
| <Disclosure.Button | ||
| ref={() => (refs.current[index] = close)} | ||
| onClick={() => { | ||
| handleClose(index) | ||
| replace( | ||
| { | ||
| query: { ...query, bookid: book.code }, | ||
| }, | ||
| undefined, | ||
| { shallow: true } | ||
| ) | ||
| }} | ||
| className={`flex w-full items-center justify-between py-2 hover:opacity-70 ${ | ||
| !open ? 'border-b border-th-secondary-300' : '' | ||
| }`} | ||
| > | ||
| <div className="flex items-center gap-4 text-base"> | ||
| <ChecksIcon levelCheck={book?.level_checks} /> | ||
| <div>{t('books:' + book.code)}</div> | ||
| </div> | ||
| <Down | ||
| className={`w-6 max-w-[1.5rem] ${ | ||
| open ? 'rotate-180 transform' : '' | ||
| }`} | ||
| /> | ||
| </Disclosure.Button> | ||
| <Disclosure.Panel> | ||
| <div className="flex w-full flex-wrap gap-4 border-b border-th-secondary-300 pb-5"> | ||
| {[...Array(Object.keys(book.chapters).length).keys()] | ||
| .map((el) => el + 1) | ||
| .map((index) => ( | ||
| <button | ||
| disabled={ | ||
| !checkChapterVersesExist( | ||
| book.code, | ||
| index, | ||
| chapters | ||
| ) && !reference?.checks | ||
| } | ||
| className={`flex h-10 w-10 items-center justify-center rounded-md ${ | ||
| checkChapterVersesExist( | ||
| book.code, | ||
| index, | ||
| chapters | ||
| ) || reference?.checks | ||
| ? 'cursor-pointer bg-th-primary-100' | ||
| : 'disabled cursor-default rounded-md bg-th-secondary-200 text-th-text-secondary-100' | ||
| } ${ | ||
| index === reference?.chapter | ||
| ? 'cursor-default rounded-md bg-th-primary-100 text-th-text-secondary-100' | ||
| : checkChapterVersesExist( | ||
| book.code, | ||
| index, | ||
| chapters | ||
| ) || reference?.checks | ||
| ? 'bg-th-secondary-200 hover:opacity-70' | ||
| : '' | ||
| }`} | ||
| key={index} | ||
| onClick={() => | ||
| setReference((prev) => ({ | ||
| ...prev, | ||
| chapter: index, | ||
| })) | ||
| } | ||
| > | ||
| {index} | ||
| </button> | ||
| ))} | ||
| </div> | ||
| </Disclosure.Panel> | ||
| </> | ||
| ) | ||
| }} | ||
| </Disclosure> | ||
| ))} | ||
| </Tab.Panel> | ||
| ))} | ||
| </Tab.Panels> | ||
| </Tab.Group> | ||
| </div> | ||
| </Card> | ||
| ) | ||
| } | ||
|
|
||
| export default BookListReader |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.