diff --git a/libs/client-shared/src/providers/Notifications/ui/notifications-provider.tsx b/libs/client-shared/src/providers/notifications/ui/notifications-provider.tsx similarity index 100% rename from libs/client-shared/src/providers/Notifications/ui/notifications-provider.tsx rename to libs/client-shared/src/providers/notifications/ui/notifications-provider.tsx diff --git a/libs/editor/src/components/settings/hooks/use-color-callback.ts b/libs/editor/src/components/settings/hooks/use-color-callback.ts new file mode 100644 index 00000000..73eb6ebd --- /dev/null +++ b/libs/editor/src/components/settings/hooks/use-color-callback.ts @@ -0,0 +1,17 @@ +import { CUSTOM_THEME } from '@/shared/consts' +import { useActions, useStore } from '@/shared/hooks' + +import { Hex, useDebounce } from '$/client-shared' + +export const useColorCallback = (cb: (hex: Hex) => void) => { + const { theme } = useStore() + const actions = useActions() + + return useDebounce((_: unknown, hex: Hex) => { + if (theme !== CUSTOM_THEME) { + actions.changeTheme(CUSTOM_THEME) + } + + return cb(hex) + }, 300) +} diff --git a/libs/editor/src/components/settings/ui/key-buildings/key-buildings.tsx b/libs/editor/src/components/settings/ui/key-buildings/key-buildings.tsx new file mode 100644 index 00000000..0c476e84 --- /dev/null +++ b/libs/editor/src/components/settings/ui/key-buildings/key-buildings.tsx @@ -0,0 +1,45 @@ +import { Typography } from 'antd' + +import { KeyBuildings as Keys } from '@/shared/consts' + +import { KeyBuildingStyles, SettingsText } from '../settings/settings.styles' + +import { WithChildren } from '$/client-shared' + +type KeyBuildingProps = WithChildren<{ + keyCode: string + experimental?: boolean +}> + +const KeyBuilding = ({ keyCode, children, experimental }: KeyBuildingProps) => { + return ( + + + {experimental ? '🧪' : '✌️'} Alt + {keyCode} + + +

{children}

+
+
+ ) +} + +const KeyBuildings = () => { + return ( + <> + + Open a file on your OS + + + Save a file on your OS + + Open new tab + Close current tab + Open/close terminal + Open/close test cases + Open/close settings + + ) +} + +export default KeyBuildings diff --git a/libs/editor/src/components/tabs/hooks/use-confirm.ts b/libs/editor/src/components/tabs/hooks/use-confirm.ts new file mode 100644 index 00000000..54c69901 --- /dev/null +++ b/libs/editor/src/components/tabs/hooks/use-confirm.ts @@ -0,0 +1,25 @@ +import { useState } from 'react' + +import { AnyFunction, Nullable } from '$/client-shared' + +export const useConfirm = () => { + const [confirmKey, setConfirmKey] = useState>(null) + + return { + protect(callback: AnyFunction) { + return (...args: any[]) => { + if (confirmKey) { + return + } + callback(...args) + } + }, + off() { + setConfirmKey(null) + }, + on(key: string) { + setConfirmKey(key) + }, + val: confirmKey + } +} diff --git a/libs/editor/src/components/tabs/hooks/use-mapped-tabs.ts b/libs/editor/src/components/tabs/hooks/use-mapped-tabs.ts new file mode 100644 index 00000000..7f9f3b1e --- /dev/null +++ b/libs/editor/src/components/tabs/hooks/use-mapped-tabs.ts @@ -0,0 +1,8 @@ +import { ContentTab } from '@/components/tabs' + +export const useMappedTabs = (content: ContentTab[]) => { + return content.map((tab) => ({ + label: tab.getLabel(), + key: tab.getKeyId() + })) +} diff --git a/libs/editor/src/components/tabs/lib/helpers/is-max-tabs-length.ts b/libs/editor/src/components/tabs/lib/helpers/is-max-tabs-length.ts new file mode 100644 index 00000000..6d492eba --- /dev/null +++ b/libs/editor/src/components/tabs/lib/helpers/is-max-tabs-length.ts @@ -0,0 +1,6 @@ +import { ContentTab } from '@/components/tabs' +import { maxTabsLength } from '@/shared/consts' + +export const isMaxTabsLength = (content: ContentTab[]) => { + return content.length >= maxTabsLength +} diff --git a/libs/editor/src/components/tabs/store/content-tab.ts b/libs/editor/src/components/tabs/store/content-tab.ts new file mode 100644 index 00000000..328f50b8 --- /dev/null +++ b/libs/editor/src/components/tabs/store/content-tab.ts @@ -0,0 +1,107 @@ +import { makeAutoObservable } from 'mobx' +import { v4 as generateId } from 'uuid' + +import { FileHandlerData } from '@/modules/editor-content/types' +import { LanguagesValues } from '@/shared/consts' + +import { ContentTabInstance } from '../types' + +import { Nullable } from '$/client-shared' + +type ContentTabArgs = Partial<{ + lastNumber: number + fileData: FileHandlerData + instance: ContentTabInstance +}> + +export class ContentTab { + private _key = generateId() + private _fileHandle: Nullable = null + private _label = 'Untitled' + private _content = '' + public idx = 0 + public lang: LanguagesValues = 'text' + public wasChanged = false + + constructor({ lastNumber, fileData, instance }: ContentTabArgs) { + makeAutoObservable(this) + + if (instance) { + this.initUsingInstance(instance) + } else if (fileData) { + this.initUsingFileData(fileData) + } + + if (lastNumber) { + this.idx = lastNumber + 1 + } + } + + public setFileHandle(fileHandle: FileSystemFileHandle) { + this._fileHandle = fileHandle + this.wasChanged = false + this.setLabel(fileHandle.name) + } + + public getFileHandle() { + return this._fileHandle + } + + public setLabel(newLabel: string) { + this._label = newLabel + } + + public getLabel() { + return this._label + } + + private updateLabel() { + // TODO: refactor + + if (this._fileHandle) { + if (!this.wasChanged) { + this.setLabel(`${this.getLabel()} •`) + } + this.wasChanged = true + + return + } + const firstLine = this._content.split('\n')[0].slice(0, 10) + const cropped = firstLine.replace(' ', '').replace('\n', '') + const newLabel = `${cropped.length > 1 ? firstLine : 'Untitled'} •` + this.wasChanged = true + + this.setLabel(newLabel) + } + + public setTabContent(content: string) { + this._content = content + + this.updateLabel() + } + + public getContent() { + return this._content + } + + public getKeyId() { + return this._key + } + + private initUsingFileData(fileData: FileHandlerData) { + this._fileHandle = fileData.fileHandle + this.lang = fileData.language + this._content = fileData.content + this._label = fileData.name + } + + private initUsingInstance(instance: ContentTabInstance) { + this._key = instance._key + this._label = instance._label + this.idx = instance.idx + this._content = instance._content + this._fileHandle = instance._fileHandle + this.wasChanged = instance.wasChanged + this.lang = instance.lang + } +} diff --git a/libs/editor/src/components/terminal/hooks/use-terminal-tabs.ts b/libs/editor/src/components/terminal/hooks/use-terminal-tabs.ts new file mode 100644 index 00000000..bde7fc14 --- /dev/null +++ b/libs/editor/src/components/terminal/hooks/use-terminal-tabs.ts @@ -0,0 +1,32 @@ +import { useCallback } from 'react' + +import { useModalsContext } from '@/shared/hooks' + +export type TerminalTabKeys = 'terminal' | 'test_cases' + +interface TerminalTab { + label: string + key: TerminalTabKeys +} + +const terminalTabs: TerminalTab[] = [ + { label: 'Terminal', key: 'terminal' }, + { label: 'Test cases', key: 'test_cases' } +] + +export const useTerminalTabs = () => { + const modalsContext = useModalsContext() + const activeKey = modalsContext.state.selectedTerminalTab + + const setActiveKey = useCallback((key: TerminalTabKeys) => { + modalsContext.update({ + selectedTerminalTab: key + }) + }, []) + + return { + key: activeKey, + set: setActiveKey, + val: terminalTabs + } +} diff --git a/libs/editor/src/modules/Aside/hooks/use-aside-animation.ts b/libs/editor/src/modules/aside/hooks/use-aside-animation.ts similarity index 100% rename from libs/editor/src/modules/Aside/hooks/use-aside-animation.ts rename to libs/editor/src/modules/aside/hooks/use-aside-animation.ts diff --git a/libs/editor/src/modules/Aside/hooks/use-editor-actions.ts b/libs/editor/src/modules/aside/hooks/use-editor-actions.ts similarity index 100% rename from libs/editor/src/modules/Aside/hooks/use-editor-actions.ts rename to libs/editor/src/modules/aside/hooks/use-editor-actions.ts diff --git a/libs/editor/src/modules/Header/hooks/use-code-runner.ts b/libs/editor/src/modules/header/hooks/use-code-runner.ts similarity index 100% rename from libs/editor/src/modules/Header/hooks/use-code-runner.ts rename to libs/editor/src/modules/header/hooks/use-code-runner.ts diff --git a/libs/editor/src/modules/Header/hooks/use-header-animation.ts b/libs/editor/src/modules/header/hooks/use-header-animation.ts similarity index 100% rename from libs/editor/src/modules/Header/hooks/use-header-animation.ts rename to libs/editor/src/modules/header/hooks/use-header-animation.ts diff --git a/libs/editor/src/modules/Header/ui/header-options/header-options.styles.ts b/libs/editor/src/modules/header/ui/header-options/header-options.styles.ts similarity index 100% rename from libs/editor/src/modules/Header/ui/header-options/header-options.styles.ts rename to libs/editor/src/modules/header/ui/header-options/header-options.styles.ts diff --git a/libs/editor/src/modules/Header/ui/header-options/header-options.tsx b/libs/editor/src/modules/header/ui/header-options/header-options.tsx similarity index 100% rename from libs/editor/src/modules/Header/ui/header-options/header-options.tsx rename to libs/editor/src/modules/header/ui/header-options/header-options.tsx diff --git a/libs/editor/src/modules/Header/ui/header-right-section/header-right-section.styles.ts b/libs/editor/src/modules/header/ui/header-right-section/header-right-section.styles.ts similarity index 100% rename from libs/editor/src/modules/Header/ui/header-right-section/header-right-section.styles.ts rename to libs/editor/src/modules/header/ui/header-right-section/header-right-section.styles.ts diff --git a/libs/editor/src/modules/Header/ui/header-right-section/header-right-section.tsx b/libs/editor/src/modules/header/ui/header-right-section/header-right-section.tsx similarity index 100% rename from libs/editor/src/modules/Header/ui/header-right-section/header-right-section.tsx rename to libs/editor/src/modules/header/ui/header-right-section/header-right-section.tsx