-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat/multiple sessions one window (#225)
Co-authored-by: Lucas Maupin <[email protected]>
- Loading branch information
1 parent
79611dc
commit 08e4b92
Showing
32 changed files
with
1,772 additions
and
1,571 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains 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
This file contains 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions
29
src/components/accessing-local-storage/access-local-storage.ts
This file contains 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,29 @@ | ||
import { useCallback } from "react"; | ||
import { createStorage, StorageType } from "@martinstark/storage-ts"; | ||
|
||
type Schema = { | ||
username: string; | ||
}; | ||
|
||
// Create a store of the desired type. If it is not available, | ||
// in-memory storage will be used as a fallback. | ||
const store = createStorage<Schema>({ | ||
type: StorageType.LOCAL, | ||
prefix: "id", | ||
silent: true, | ||
}); | ||
|
||
export function useStorage<Key extends keyof Schema>(key: Key) { | ||
const readFromStorage = useCallback((): Schema[Key] | null => { | ||
return store.read(key); | ||
}, [key]); | ||
|
||
const writeToStorage = useCallback( | ||
(value: Schema[Key]): void => { | ||
store.write(key, value); | ||
}, | ||
[key] | ||
); | ||
|
||
return { readFromStorage, writeToStorage }; | ||
} |
This file contains 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,151 @@ | ||
import styled from "@emotion/styled"; | ||
import { useEffect, useState } from "react"; | ||
import { useNavigate, useParams } from "react-router-dom"; | ||
import { useGlobalState } from "../../global-state/context-provider"; | ||
import { JoinProduction } from "../landing-page/join-production"; | ||
import { ProductionLine } from "../production-line/production-line"; | ||
import { SecondaryButton } from "../landing-page/form-elements"; | ||
import { NavigateToRootButton } from "../navigate-to-root-button/navigate-to-root-button"; | ||
import { DisplayContainerHeader } from "../landing-page/display-container-header"; | ||
import { Modal } from "../modal/modal"; | ||
import { VerifyDecision } from "../verify-decision/verify-decision"; | ||
import { ModalConfirmationText } from "../modal/modal-confirmation-text"; | ||
|
||
const Container = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
flex-wrap: wrap; | ||
padding: 2rem; | ||
`; | ||
|
||
const CallsContainer = styled.div` | ||
display: flex; | ||
flex-direction: row; | ||
flex-wrap: wrap; | ||
padding: 2rem; | ||
`; | ||
|
||
const CallContainer = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
padding: 2rem; | ||
max-width: 40rem; | ||
min-width: 30rem; | ||
`; | ||
|
||
const AddCallContainer = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
padding: 4rem; | ||
max-width: 40rem; | ||
min-width: 30rem; | ||
`; | ||
|
||
const ButtonWrapper = styled.div` | ||
margin: 0 1rem 1rem 0; | ||
:last-of-type { | ||
margin: 0 0 4rem; | ||
} | ||
`; | ||
|
||
export const CallsPage = () => { | ||
const [productionId, setProductionId] = useState<string | null>(null); | ||
const [addCallActive, setAddCallActive] = useState(false); | ||
const [confirmExitModalOpen, setConfirmExitModalOpen] = useState(false); | ||
const [{ calls, selectedProductionId }, dispatch] = useGlobalState(); | ||
const { productionId: paramProductionId, lineId: paramLineId } = useParams(); | ||
const navigate = useNavigate(); | ||
|
||
const isEmpty = Object.values(calls).length === 0; | ||
const isSingleCall = Object.values(calls).length === 1; | ||
|
||
useEffect(() => { | ||
if (selectedProductionId) { | ||
setProductionId(selectedProductionId); | ||
} | ||
}, [selectedProductionId]); | ||
|
||
useEffect(() => { | ||
if (isEmpty && !paramProductionId && !paramLineId) { | ||
navigate("/"); | ||
} | ||
}, [isEmpty, paramProductionId, paramLineId, navigate]); | ||
|
||
const runExitAllCalls = async () => { | ||
setProductionId(null); | ||
navigate("/"); | ||
Object.entries(calls).forEach(([callId]) => { | ||
if (callId) { | ||
dispatch({ | ||
type: "REMOVE_CALL", | ||
payload: { id: callId }, | ||
}); | ||
} | ||
}); | ||
}; | ||
|
||
return ( | ||
<Container> | ||
<ButtonWrapper> | ||
<NavigateToRootButton | ||
resetOnExitRequest={() => setConfirmExitModalOpen(true)} | ||
/> | ||
{confirmExitModalOpen && ( | ||
<Modal onClose={() => setConfirmExitModalOpen(false)}> | ||
<DisplayContainerHeader>Confirm</DisplayContainerHeader> | ||
<ModalConfirmationText> | ||
Are you sure you want to leave all calls? | ||
</ModalConfirmationText> | ||
<VerifyDecision | ||
confirm={runExitAllCalls} | ||
abort={() => setConfirmExitModalOpen(false)} | ||
/> | ||
</Modal> | ||
)} | ||
</ButtonWrapper> | ||
<CallsContainer> | ||
{Object.entries(calls).map( | ||
([callId, callState]) => | ||
callId && | ||
callState.joinProductionOptions && ( | ||
<CallContainer key={callId}> | ||
<ProductionLine | ||
id={callId} | ||
callState={callState} | ||
isSingleCall={isSingleCall} | ||
/> | ||
</CallContainer> | ||
) | ||
)} | ||
{!isEmpty && ( | ||
<AddCallContainer> | ||
<ButtonWrapper> | ||
<SecondaryButton | ||
type="button" | ||
onClick={() => setAddCallActive(!addCallActive)} | ||
> | ||
Add Call | ||
</SecondaryButton> | ||
</ButtonWrapper> | ||
{addCallActive && productionId && ( | ||
<JoinProduction | ||
addAdditionalCallId={productionId} | ||
closeAddCallView={() => setAddCallActive(false)} | ||
/> | ||
)} | ||
</AddCallContainer> | ||
)} | ||
{isEmpty && paramProductionId && paramLineId && ( | ||
<CallContainer> | ||
<JoinProduction | ||
preSelected={{ | ||
preSelectedProductionId: paramProductionId, | ||
preSelectedLineId: paramLineId, | ||
}} | ||
/> | ||
</CallContainer> | ||
)} | ||
</CallsContainer> | ||
</Container> | ||
); | ||
}; |
This file contains 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
Oops, something went wrong.