Skip to content

Commit

Permalink
Merge pull request #27 from Rue-pro/feat-add-edit-last-note-fields
Browse files Browse the repository at this point in the history
feat: add editing latest note fields
  • Loading branch information
Rue-pro authored May 21, 2024
2 parents 9d76814 + 189b6a3 commit 8637dbb
Show file tree
Hide file tree
Showing 49 changed files with 733 additions and 379 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ coverage
/playwright-report/
/blob-report/
/playwright/.cache/

*.circleDep.txt
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"stylelint-prettier": "5.0.0",
"typescript": "5.4.2",
"vite": "5.1.5",
"vite-plugin-circular-dependency": "0.4.1",
"vitest": "1.3.1"
}
}
26 changes: 26 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions public/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@
"CONTEXT_MENU_ADD_NOTE_AUTOMATICALLY": {
"message": "Add note"
},
"CONTEXT_MENU_EDIT_LATEST_NOTE_TRANSLATION": {
"message": "Edit latest note translation"
},
"CONTEXT_MENU_EDIT_LATEST_NOTE_CONTEXT": {
"message": "Edit latest note context"
},
"CONTEXT_MENU_EDIT_LATEST_NOTE_TRANSCRIPTION": {
"message": "Edit latest note transcription"
},
"ERROR_CAN_NOT_IDENTIFY_DICTIONARY_ADD_NOTE_AUTOMATICALLY": {
"message": "Adding note automatically failed, can't identify dictionary"
},
Expand Down Expand Up @@ -180,5 +189,11 @@
},
"CLEAR": {
"message": "Clear"
},
"ERROR_CAN_NOT_GET_ACTIVE_TAB": {
"message": "Can't get active tab"
},
"ERROR_CAN_NOT_GET_ACTIVE_TAB_ON_ACTIVATED": {
"message": "Can't get active tab while activating"
}
}
15 changes: 13 additions & 2 deletions src/__tests__/setupTests.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
import { chromeMock } from '@shared/shared/browser/__mocks__/chrome'
import { vi } from 'vitest'

global.chrome = chromeMock
import { i18nMock } from '@shared/shared/browser/i18n/__mocks__'
import { storageMock } from '@shared/shared/browser/storage/__mocks__/index.ts'

vi.mock('@shared/shared/browser/storage', () => {
return {
storage: storageMock,
}
})

vi.mock('@shared/shared/browser/i18n', () => ({
i18n: i18nMock,
}))
3 changes: 3 additions & 0 deletions src/background/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { addNewWord } from '@background/features/addNewWord'
import { autoAddNewNote } from '@background/features/autoAddNewNote'
import { editLatestNote } from '@background/features/editLatestNote'

import { browser } from '@background/shared/browser'

Expand All @@ -18,6 +19,8 @@ browser.contextMenus.removeAll(() => {
addNewWord(PARENT_ID)

autoAddNewNote(PARENT_ID)

editLatestNote(PARENT_ID)
})

$notes.listen(() => {})
1 change: 1 addition & 0 deletions src/background/features/editLatestNote/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ui'
55 changes: 55 additions & 0 deletions src/background/features/editLatestNote/ui.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { browser } from '@background/shared/browser'
import {
TOnClickContextMenuInfoProps,
TOnClickContextMenuTabProps,
} from '@background/shared/browser/contextMenus'
import { currentPageLanguageStore } from '@background/shared/entities/language'

import { INoteSelectors } from '@shared/entities/note'
import { editNote } from '@shared/entities/note/model/store'

export const editLatestNote = (parentId: string) => {
currentPageLanguageStore.$currentPageLanguage.listen(() => {})

const fields: Array<keyof Omit<INoteSelectors, 'text'>> = [
'translation',
'context',
'transcription',
]
fields.forEach((field) => {
const handleClick = async (
info: TOnClickContextMenuInfoProps,
tab?: TOnClickContextMenuTabProps,
) => {
if (info.menuItemId === `edit_latest_note_${field}`) {
if (!tab?.id) return

editNote(currentPageLanguageStore.$currentPageLanguage.get(), {
...currentPageLanguageStore.$latestNote.get(),
translation: info.selectionText,
})
}
}

currentPageLanguageStore.$latestNote.listen((latestNote) => {
if (latestNote) {
browser.contextMenus.update(`edit_latest_note_${field}`, {
title: `${browser.i18n.getMessage(`CONTEXT_MENU_EDIT_LATEST_NOTE_${field.toUpperCase()}`)} ${latestNote.text}`,
})
} else {
browser.contextMenus.remove(`edit_latest_note_${field}`)
}
})

browser.contextMenus.create({
title: browser.i18n.getMessage(
`CONTEXT_MENU_EDIT_LATEST_NOTE_${field.toUpperCase()}`,
),
id: `edit_latest_note_${field}`,
parentId: parentId,
contexts: ['selection'],
})

browser.contextMenus.onClicked.addListener(handleClick)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { IContextMenus } from './types'
export const chromeContextMenus: IContextMenus = {
create: chrome.contextMenus.create,

update: chrome.contextMenus.update,

onClicked: chrome.contextMenus.onClicked,

removeAll: chrome.contextMenus.removeAll,

remove: chrome.contextMenus.remove,
}
7 changes: 7 additions & 0 deletions src/background/shared/browser/contextMenus/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ import { TTab } from '@shared/shared/browser/tabs'
export interface IContextMenus {
create: (menuConfig: IMenuConfig) => string | number

update: (
menuItemId: string | number,
menuConfig: Partial<IMenuConfig>,
) => void

remove: (menuItemId: string | number) => void

onClicked: {
addListener: (
callback: (
Expand Down
2 changes: 2 additions & 0 deletions src/background/shared/browser/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { i18n } from '@shared/shared/browser/i18n'
import { tabs } from '@shared/shared/browser/tabs'

import { contextMenus } from './contextMenus'

export const browser = {
contextMenus,
i18n,
tabs,
}
12 changes: 7 additions & 5 deletions src/content/dictionary/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ import {
getNoteFromDictionaryPageHandler,
} from '@shared/features/note/AutoAddNewNote'

import { GOOGLE_TRANSLATE } from '@shared/entities/dictionary'
import {
GOOGLE_TRANSLATE,
getDictionaryLanguageCodeByPageUrl,
} from '@shared/entities/dictionary'
import {
TLanguageCode,
getLanguageCodeByPageMetaData,
getLanguageCodeByPageUrl,
} from '@shared/entities/language'
import { $languages } from '@shared/entities/language/model/store'

import { getNotesFields } from './helpers/getNotesFields'

$languages.listen(() => {})

browser.runtime.onConnect.addListener(async function (port) {
$languages.listen(() => {})

if (port.name === 'CurrentPage') {
getLanguageFromPageHandler(port, () => {
let pageLanguage: TLanguageCode = 'other'
Expand All @@ -27,7 +29,7 @@ browser.runtime.onConnect.addListener(async function (port) {
if (isTranslatorPage) {
pageLanguage = GOOGLE_TRANSLATE.getLanguage()
} else {
pageLanguage = getLanguageCodeByPageUrl(window.location.href)
pageLanguage = getDictionaryLanguageCodeByPageUrl(window.location.href)
if (pageLanguage === 'other') {
pageLanguage = getLanguageCodeByPageMetaData()
}
Expand Down
3 changes: 0 additions & 3 deletions src/popup/app/Popup.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { NoteList } from '@popup/widgets/note/NoteList'
import { Settings } from '@popup/widgets/settings'

import { ErrorAlert } from '@popup/entities/error'

export const Popup = () => {
return (
<main>
<ErrorAlert />
<Settings />
<NoteList />
</main>
Expand Down
1 change: 0 additions & 1 deletion src/popup/app/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ main {
height: 480px;
padding: var(--spacing-5) var(--spacing-2);
overflow-y: auto;
scrollbar-gutter: stable both-edges;
}

ul {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,20 @@ export const SelectDictionaryList = () => {
<>
<Tabs defaultValue={currentPageLanguage}>
<TabsList arrows={true}>
{languages.map((language) => (
<Tab
key={language.value}
value={language.value}
{...a11yProps('language_navigation', language.value)}
>
{language.label}
</Tab>
))}
{languages.map((language) =>
language.value === 'other' ? null : (
<Tab
key={language.value}
value={language.value}
{...a11yProps('language_navigation', language.value)}
>
{language.label}
</Tab>
),
)}
</TabsList>
{languages.map((language) => {
return (
return language.value === 'other' ? null : (
<TabPanel
key={language.value}
{...a11yProps('language_navigation', language.value)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { waitFor } from '@tests/testUtils'
import { allTasks, cleanStores, keepMount } from 'nanostores'
import { afterEach, describe, expect, test } from 'vitest'
import { beforeEach, describe, expect, test } from 'vitest'

import { languageStore } from '@shared/entities/language'

import { storage } from '@shared/shared/browser/storage'

import {
checkIsSelected,
localStore,
Expand All @@ -13,10 +15,16 @@ import {
} from '../store'

describe('selectedLanguageCodes store', () => {
afterEach(async () => {
await chrome.storage.local.clear()
beforeEach(async () => {
await storage.clear()
cleanStores(languageStore.$languageCodes)
cleanStores(localStore.languageCodes)
cleanStores(localStore.islanguageCodesDirty)
cleanStores(localStore.defaultValue)
languageStore.$languages.set([])
localStore.languageCodes.set([])
localStore.islanguageCodesDirty.set(false)
localStore.defaultValue.set([])
})

describe('commmon', () => {
Expand Down
28 changes: 18 additions & 10 deletions src/popup/features/language/SelectLanguages/model/store.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import { atom } from 'nanostores'

import { TLanguageCode, languageStore } from '@shared/entities/language'
import {
LANGUAGES,
TLanguageCode,
languageStore,
} from '@shared/entities/language'

import { TResult } from '@shared/shared/libs/operationResult'

let defaultValue: TLanguageCode[] = []

export const localStore = {
languageCodes: atom<TLanguageCode[]>([]),
islanguageCodesDirty: atom(true),
defaultValue: atom<TLanguageCode[]>([]),
languageCodes: atom<TLanguageCode[]>(
LANGUAGES.map((language) => language.value),
),
islanguageCodesDirty: atom(false),
}

languageStore.$languages.listen((newValue) => {
if (localStore.islanguageCodesDirty.get()) {
const languageCodes = newValue.map((language) => language.value)
defaultValue = languageCodes
const islanguageCodesDirty = localStore.islanguageCodesDirty.get()
const languageCodes = newValue.map((language) => language.value)
if (islanguageCodesDirty) {
localStore.defaultValue.set(languageCodes)
} else {
localStore.defaultValue.set(languageCodes)
localStore.languageCodes.set(languageCodes)
}
})
Expand All @@ -29,15 +37,15 @@ export const toggle = async (languageCode: TLanguageCode) => {
? languageCodes.filter((lang) => lang !== languageCode)
: [...languageCodes, languageCode]

localStore.languageCodes.set(newSelectedLanguages)
localStore.languageCodes.set([...newSelectedLanguages, 'other'])
}

export const checkIsSelected = (languageCode: TLanguageCode): boolean => {
return localStore.languageCodes.get().includes(languageCode)
}

export const reset = () => {
localStore.languageCodes.set(defaultValue)
localStore.languageCodes.set(localStore.defaultValue.get())
}

export const syncLocalStoreWithLanguageStore = (): Promise<TResult> => {
Expand Down
Loading

0 comments on commit 8637dbb

Please sign in to comment.