├── .editorconfig ├── .env.example ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── build.yml ├── .gitignore ├── .npmrc ├── .vscode ├── launch.json └── tasks.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── afterSignHook.js ├── appIcon └── icon.png ├── babel.config.js ├── build ├── entitlements.mac.inherit.plist └── icons │ ├── 1024x1024.png │ ├── 128x128.png │ ├── 16x16.png │ ├── 24x24.png │ ├── 256x256.png │ ├── 32x32.png │ ├── 48x48.png │ ├── 512x512.png │ ├── 64x64.png │ ├── icon.icns │ └── icon.ico ├── crowdin.yml ├── package.json ├── postcss.config.js ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── css │ │ └── tailwind.css │ └── icons │ │ ├── arrow-left.svg │ │ ├── arrow-right.svg │ │ ├── back.svg │ │ ├── dropdown.svg │ │ ├── editor │ │ ├── bold.svg │ │ ├── bullet-list.svg │ │ ├── checkbox.svg │ │ ├── code.svg │ │ ├── detail.svg │ │ ├── divider.svg │ │ ├── heading-one.svg │ │ ├── heading-three.svg │ │ ├── heading-two.svg │ │ ├── italic.svg │ │ ├── pen.svg │ │ └── strikethrough.svg │ │ ├── link.svg │ │ ├── moon.svg │ │ ├── nothing-found.svg │ │ ├── search-something.svg │ │ ├── sun.svg │ │ └── tick.svg ├── background.js ├── components │ ├── app-header.vue │ ├── day-switcher.vue │ ├── editor.vue │ ├── language-dropdown.vue │ ├── settings │ │ └── allow-prerelease.vue │ ├── slash-commands │ │ ├── CommandsList.vue │ │ ├── commands.js │ │ └── suggestions.js │ ├── theme-switcher.vue │ ├── update-dropdown.vue │ └── week-switcher.vue ├── i18n.js ├── locales │ ├── ar-AR.json │ ├── bn-IN.json │ ├── ca-ES.json │ ├── cs-CZ.json │ ├── da-DK.json │ ├── de-DE.json │ ├── el-GR.json │ ├── en-US.json │ ├── es-ES.json │ ├── fa-IR.json │ ├── fr-FR.json │ ├── hi-IN.json │ ├── hr-HR.json │ ├── id-ID.json │ ├── it-IT.json │ ├── ko-KR.json │ ├── nl-NL.json │ ├── np-NP.json │ ├── pl-PL.json │ ├── pt-BR.json │ ├── ru-RU.json │ ├── sl-SI.json │ ├── tr-TR.json │ ├── uk-UA.json │ └── zh-CN.json ├── main.js ├── router │ └── index.js ├── store │ ├── index.js │ └── modules │ │ ├── app │ │ ├── actions.js │ │ ├── getters.js │ │ ├── helper.js │ │ ├── index.js │ │ ├── mutations.js │ │ ├── state.js │ │ └── types.js │ │ ├── calendar │ │ ├── actions.js │ │ ├── getters.js │ │ ├── helper.js │ │ ├── index.js │ │ ├── mutations.js │ │ ├── state.js │ │ └── types.js │ │ └── file │ │ ├── actions.js │ │ ├── getters.js │ │ ├── helper.js │ │ ├── index.js │ │ ├── mutations.js │ │ ├── state.js │ │ └── types.js ├── translation.js ├── updater.js └── views │ ├── Home.vue │ ├── Layout.vue │ ├── Search.vue │ └── Settings.vue ├── tailwind.config.js ├── vue.config.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = false 8 | insert_final_newline = false -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APPLE_ID= 2 | APPLE_ID_PASSWORD= -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [lostdesign] 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "\U0001F41B - BUG TITLE HERE" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - linked version: [e.g. 1.0.0] 28 | - operating system [e.g. macOS Catalina XX.XX, windows 10] 29 | 30 | **Smartphone (please complete the following information):** 31 | - Device: [e.g. iPhone6] 32 | - OS: [e.g. iOS8.1] 33 | - Browser [e.g. stock browser, safari] 34 | - Version [e.g. 22] 35 | 36 | **Additional context** 37 | Add any other context about the problem here. 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: DO NOT ADD FEATURE REQUESTS HERE! Use discussions! 4 | title: USE DISCUSSIONS, NOT ISSUES <3 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | Please go here and add the feature request there instead: https://github.com/lostdesign/linked/discussions 10 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build/release 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'feature/**' 7 | - 'fix/**' 8 | tags: 9 | - '*' 10 | 11 | jobs: 12 | release: 13 | runs-on: ${{ matrix.os }} 14 | env: 15 | TIPTAP_PRO_TOKEN: ${{ secrets.TIPTAP_PRO_TOKEN }} 16 | 17 | strategy: 18 | matrix: 19 | os: [ macos-latest, ubuntu-latest, windows-latest ] 20 | 21 | steps: 22 | - name: Check out Git repository 23 | uses: actions/checkout@v1 24 | 25 | - name: Install Node.js, NPM and Yarn 26 | uses: actions/setup-node@v1 27 | with: 28 | node-version: 16 29 | 30 | - name: Install pacman dependencies 31 | if: startsWith(matrix.os, 'ubuntu') 32 | run: sudo apt-get install -y libarchive-tools 33 | 34 | - name: Build/release Electron app 35 | uses: samuelmeuli/action-electron-builder@v1 36 | continue-on-error: true 37 | env: 38 | APPLE_ID: ${{secrets.APPLE_ID}} 39 | APPLE_ID_PASSWORD: ${{secrets.APPLE_ID_PASSWORD}} 40 | with: 41 | mac_certs: ${{ secrets.CSC_LINK }} 42 | mac_certs_password: ${{ secrets.CSC_KEY_PASSWORD }} 43 | 44 | skip_build: true 45 | use_vue_cli: true 46 | 47 | # GitHub token, automatically provided to the action 48 | # (No need to define this secret in the repo settings) 49 | github_token: ${{ secrets.github_token }} 50 | 51 | # If the commit is tagged with a version (e.g. "v1.0.0"), 52 | # release the app after building 53 | release: ${{ startsWith(github.ref, 'refs/tags/v') }} 54 | 55 | - name: Archive build artifacts for each os 56 | uses: actions/upload-artifact@v2 57 | with: 58 | name: all-os-built-executables 59 | retention-days: 3 60 | path: dist_electron -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | pnpm-debug.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | 25 | #Electron-builder output 26 | /dist_electron 27 | privateKey 28 | /package-lock.json 29 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | @tiptap-pro:registry=https://registry.tiptap.dev/ 2 | //registry.tiptap.dev/:_authToken=TIPTAP_PRO_TOKEN -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Electron: Main", 6 | "type": "node", 7 | "request": "launch", 8 | "protocol": "inspector", 9 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", 10 | "windows": { 11 | "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" 12 | }, 13 | "preLaunchTask": "electron-debug", 14 | "args": [ 15 | "--remote-debugging-port=9223", 16 | "./dist_electron" 17 | ], 18 | "outFiles": [ 19 | "${workspaceFolder}/dist_electron/**/*.js" 20 | ] 21 | }, 22 | { 23 | "name": "Electron: Renderer", 24 | "type": "chrome", 25 | "request": "attach", 26 | "port": 9223, 27 | "urlFilter": "http://localhost:*", 28 | "timeout": 30000, 29 | "webRoot": "${workspaceFolder}/src", 30 | "sourceMapPathOverrides": { 31 | "webpack:///src/*": "${webRoot}/*" 32 | } 33 | } 34 | ], 35 | "compounds": [ 36 | { 37 | "name": "Electron: All", 38 | "configurations": [ 39 | "Electron: Main", 40 | "Electron: Renderer" 41 | ] 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "electron-debug", 8 | "type": "process", 9 | "command": "./node_modules/.bin/vue-cli-service", 10 | "windows": { 11 | "command": "./node_modules/.bin/vue-cli-service.cmd" 12 | }, 13 | "isBackground": true, 14 | "args": [ 15 | "electron:serve", 16 | "--debug" 17 | ], 18 | "problemMatcher": { 19 | "owner": "custom", 20 | "pattern": { 21 | "regexp": "" 22 | }, 23 | "background": { 24 | "beginsPattern": "Starting development server\\.\\.\\.", 25 | "endsPattern": "Not launching electron as debug argument was passed\\." 26 | } 27 | } 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.4.8](https://github.com/lostdesign/linked/compare/v1.4.7...v1.4.8) - 2022-02-05 2 | 3 | - 🐛 fix app-header 4 | 5 | ## [1.4.7](https://github.com/lostdesign/linked/compare/v1.4.6...v1.4.7) - 2022-02-05 6 | 7 | - ⬆️ upgrade tiptap & electron 8 | 9 | ## [1.4.6](https://github.com/lostdesign/linked/compare/v1.4.5...v1.4.6) - 2022-02-05 10 | 11 | - 🐛 fix bubble menu 12 | 13 | ## [1.4.5](https://github.com/lostdesign/linked/compare/v1.4.4...v1.4.5) - 2022-02-05 14 | 15 | - 🐛 fixes #87 16 | 17 | ## [1.4.4](https://github.com/lostdesign/linked/compare/v1.4.3...v1.4.4) - 2022-02-05 18 | 19 | - 🐛 fixes #96 20 | 21 | ## [1.4.3](https://github.com/lostdesign/linked/compare/v1.4.2...v1.4.3) - 2022-02-05 22 | 23 | - 🐛 fix checkbox spacing 24 | - 🐛 fixes #81 25 | 26 | ## [1.4.2](https://github.com/lostdesign/linked/compare/v1.4.1...v1.4.2) - 2022-02-04 27 | 28 | - 🐛 fix file migration 29 | - 🐛 fix search index reset on file migration 30 | 31 | ## [1.4.1](https://github.com/lostdesign/linked/compare/v1.4.0...v1.4.1) - 2022-02-02 32 | 33 | - 📄 update readme 34 | - 💄fix search result ui 35 | - 🐛 remove overwrite option on move 36 | - ♻️ replace notification with dialog 37 | 38 | 39 | ## [1.4.0](https://github.com/lostdesign/linked/compare/v1.3.11...v1.4.0) - 2022-02-01 40 | 41 | - 🐛 fix color and path 42 | - ✨ custom file location+migration 43 | - ♻️ bump node version 44 | - 🔥delete brazil translation 45 | - 🌐 update translations 46 | - ✨add reindex method 47 | - ✨ add keyboard shortcuts and search result selection 48 | - ♻️ update tailwind 49 | - ✨ Add check for updates menu option 50 | - ✨ Improve updates system 51 | - 🌐 Add catalan language 52 | - ♻️ change US translation for search placeholder 53 | 54 | ## [1.3.12](https://github.com/lostdesign/linked/compare/v1.3.11...v1.3.12) - 2021-11-13 55 | 56 | - 🚑 hotfix, Korean translation broke the app due to a missing code property 57 | 58 | ## [1.3.11](https://github.com/lostdesign/linked/compare/v1.3.10...v1.3.11) - 2021-11-12 59 | - 💬 Added arabic translation by @ViNoS-ab in #107 60 | ### New Contributors 61 | @ViNoS-ab made their first contribution in #107 62 | 63 | ## [1.3.10](https://github.com/lostdesign/linked/compare/v1.3.9...v1.3.10) - 2021-11-09 64 | 65 | - 🐛 fixes #105 66 | - latest-linux.yml now back, providing autoupdate for .AppImage 67 | - .deb & .rpm now automatically attaching to a release, previously were missing due to failing .snap build 68 | - ♻️ removes .msi since it did not work 69 | 70 | ## [1.3.9](https://github.com/lostdesign/linked/compare/v1.3.7...v1.3.9) - 2021-11-09 71 | 72 | - ♻️ added .rpm by @KorbsStudio 73 | - ♻️ added .msi(needs to be fixed in one of the next release, it failed) 74 | 75 | ## [1.3.8](https://github.com/lostdesign/linked/compare/v1.3.7...v1.3.8) - 2021-11-09 76 | Pipeline failed, skipping this version. 77 | 78 | 79 | ## [1.3.7](https://github.com/lostdesign/linked/compare/v1.3.6...v1.3.7) - 2021-11-08 80 | 81 | - 🐛 fixed a UI bug where the app would have its shell would use the OS thememode and the app itself would use the set thememode 82 | 83 | ## [1.3.6](https://github.com/lostdesign/linked/compare/v1.3.5...v1.3.6) - 2021-10-27 84 | 85 | - 💄 tiny ui refinements 86 | - bubble menu received a border 87 | - selected theme now has active state 88 | - primary color has more ✨ pop ✨ 89 | - marking text has been desaturated 90 | - links now are visible as such lostdesign/linked 91 | - 🐛 code block now can simply be deleted if its empty, by using backspace #99 (reported by @Ryaaahs) 92 | - ♻️ refactored code 93 | 94 | ### PR's merged 95 | 96 | - 🐛 collapse keyboard shortcuts by @lostdesign in #97 97 | - 🚧 ui fixes by @lostdesign in #100 98 | 99 | ## [1.3.5](https://github.com/lostdesign/linked/compare/v1.3.4...v1.3.5) - 2021-08-31 100 | 101 | - 🌐 add Dutch and French translations by @JonasPardon 102 | 103 | ## [1.3.4](https://github.com/lostdesign/linked/compare/v1.3.3...v1.3.4) - 2021-08-10 104 | 105 | - 🐛 fix broken releases 106 | - 📝 update readme 107 | 108 | ## [1.3.3](https://github.com/lostdesign/linked/compare/v1.3.2...v1.3.3) - 2021-08-09 109 | 110 | - ♻️ add themeswitcher component, add app store module, refactor theme … 111 | - ♻️ reformat code 112 | - ✨ add electron-storage 113 | 114 | ## [1.3.2](https://github.com/lostdesign/linked/compare/v1.3.1...v1.3.2) - 2021-07-08 115 | 116 | - ♻️ fix keyboard shortcuts 117 | - ♻️ refactor i18n 118 | - ♻️ format code 119 | - 🐛 fix editor not focusing on body click 120 | - ♻️ update screenshot 121 | - 🌐 add korean translation 122 | - 👷 fix artifacts 123 | - 👷 ️fix artifacts not including files 124 | - 👷 adjust build step only keeping each os artifact 125 | - 👷 fix wrong windows property -> win, add artifacts 126 | - 👷‍ fixing build not producing zip file, adding windows portable and more linux extensions 127 | - 📝 add changelog 128 | 129 | ## [1.3.1](https://github.com/lostdesign/linked/compare/v1.3.0...v1.3.1) - 2021-06-14 130 | 131 | - 🚑 fix keyboard shortcuts, fix week not switching 132 | 133 | ## [1.3.0](https://github.com/lostdesign/linked/compare/v1.2.2...v1.3.0) - 2021-06-14 134 | 135 | - 🐛 fix broken week-switcher 136 | - 🐛 fix minHeight of window 137 | - ♻️ refactor type imports 138 | - 🔥 delete old mixins 139 | - ♻️ move shortcuts, refactor mixin to store 140 | - ♻️ refactor app into components 141 | - ✨ add file store module 142 | - ✨ add calendar store module 143 | - ✨ add vuex 144 | 145 | ## [1.2.2](https://github.com/lostdesign/linked/compare/v1.2.1...v1.2.2) - 2021-06-14 146 | 147 | - ♻️ refactor code to components 148 | - 🐛 fixes #44 code color in lightmode 149 | 150 | ## [1.2.1](https://github.com/lostdesign/linked/compare/v1.2.0...v1.2.1) - 2021-06-14 151 | 152 | - 🌐 add Turkish translation thanks to @fazilaltinel 153 | - ♻️ add prev/next week/day menu items 154 | 155 | ## [1.2.0](https://github.com/lostdesign/linked/compare/v1.1.9...v1.2.0) - 2021-06-08 156 | 157 | - ✨ add nativeapp menu 158 | 159 | ## [1.1.9](https://github.com/lostdesign/linked/compare/v1.1.8...v1.1.9) - 2021-06-07 160 | 161 | - 🌐 add Croatian translation thanks to @dftd 162 | - 🌐 add Spanish translations thanks to @mwager 163 | - 💚 fix ci only run on feat/fix and tag 164 | 165 | ## [1.1.8](https://github.com/lostdesign/linked/compare/v1.1.6...v1.1.8) - 2021-06-01 166 | 167 | Skipped `1.1.7` due to broken pipeline. 168 | 169 | - 💛 fixed pipeline not building app 170 | - 💛 fixed pipeline now throws if notarising failed 171 | - 📝 updated readme to be more detailed 172 | - 📌 pinned dependencies, bumped electron-builder 173 | 174 | ## [1.1.6](https://github.com/lostdesign/linked/compare/v1.1.5...v1.1.6) - 2021-05-31 175 | 176 | This version was not code signed, due to the pipeline silently failing. 177 | 178 | - ✨ add russian translation 179 | 180 | ## [1.1.5](https://github.com/lostdesign/linked/compare/v1.1.4...v1.1.5) - 2021-05-30 181 | 182 | This version was not code signed, due to the pipeline silently failing. 183 | 184 | - ✨ add brazilian portoguese thanks to @felixguilherme #40 185 | - 🐛 fixed icons not displaying properly 186 | - 🐛 fixed dropdown ui displaying incorrectly in light mode 187 | 188 | ## [1.1.4](https://github.com/lostdesign/linked/compare/v1.1.3...v1.1.4) - 2021-05-29 189 | 190 | This version was not code signed, due to the pipeline silently failing. 191 | 192 | - ✨ add localization 193 | - 💄 adjust calendar to match localization 194 | - 💄 remove redundant day, extend week day labels to be bit longer 195 | - ⚡️ improve performance 196 | - 📖 add contributing.md and other repo-related files 197 | 198 | ## [1.1.3](https://github.com/lostdesign/linked/compare/v1.1.2...v1.1.3) - 2021-04-09 199 | 200 | This version was not code signed, due to the pipeline silently failing. 201 | 202 | - ✨ inline and floating menu 203 | - ✨ added image support 204 | - ✨ added horizontal line 205 | - ✨ added undo/redo 206 | - ✨ added link support 207 | - ♻️ fixed focussing the editor (again) 208 | - 💄 minor UI adjustments (changed icons) 209 | - 🐛 fixed minor layout bug 210 | - 🔥 removed text-align 211 | 212 | ## [1.1.2](https://github.com/lostdesign/linked/compare/v1.1.1...v1.1.2) - 2021-03-30 213 | 214 | - 🐛 fix sticky header 215 | 216 | ## [1.1.1](https://github.com/lostdesign/linked/compare/v1.1.0...v1.1.1) - 2021-03-29 217 | 218 | - 🐛 fixes editor freezing on enter 219 | 220 | ## [1.1.0](https://github.com/lostdesign/linked/compare/v1.0.5...v1.1.0) - 2021-03-29 221 | 222 | for unkown reasons the renderer will freeze upon pressing ENTER 223 | 224 | - ♻️ rewrite calendar js 225 | - ✨ add calendar week 226 | - ✨ add week change via buttons 227 | 228 | ## [1.0.5](https://github.com/lostdesign/linked/compare/v1.0.3...v1.0.5) - 2021-03-29 229 | 230 | - 🐛 fix background color bug 231 | - 🐛 fix sticky heading 232 | 233 | ## [1.0.4](https://github.com/lostdesign/linked/compare/v1.0.3...v1.0.4) - 2021-03-29 234 | 235 | - ✨ changed app icon 236 | 237 | ## [1.0.3](https://github.com/lostdesign/linked/compare/v1.0.2...v1.0.3) - 2021-03-28 238 | 239 | This version is equal to `1.0.2` and has only be published to test auto-updating. 240 | 241 | ## [1.0.2](https://github.com/lostdesign/linked/compare/v1.0.0...v1.0.2) - 2021-03-28 242 | 243 | Skipped `1.0.1` due to broken pipeline. 244 | 245 | - 👷‍♂️ fixed build 246 | - 🐛 fixed notarizing 247 | - 🐛 fixed codesigning 248 | 249 | ## [1.0.0](https://github.com/lostdesign/linked/compare/v0.5.0...v1.0.0) - 2021-03-28 250 | 251 | - ✨ added auto update 252 | - ✨ added codesigning 253 | - ✨ added notarizing 254 | - ♻️ refactored the code 255 | - ♻️ app frame now respects dark/light mode style 256 | 257 | ## [0.5.0](https://github.com/lostdesign/linked/compare/v0.4.1...v0.5.0) - 2021-03-24 258 | 259 | - ✨ add light/dark mode 260 | - 🐛 fix editor focus on click 261 | 262 | ## [0.4.1](https://github.com/lostdesign/linked/compare/v0.3.1...v0.4.1) - 2021-03-24 263 | 264 | Skipped `0.4.0` due to broken pipeline. 265 | 266 | - ✨ upgraded to tiptapv2 267 | - ✨ first windows build 268 | - 💄 changed design slightly 269 | 270 | ## [0.3.1](https://github.com/lostdesign/linked/compare/v0.3.0...v0.3.1) - 2021-03-23 271 | 272 | - 🐛 fix broken copy/paste 273 | 274 | ## [0.3.0](https://github.com/lostdesign/linked/compare/v0.2.1...v0.3.0) - 2021-03-23 275 | 276 | - ⏪ revert change from 0.2.0, see #16 277 | 278 | ## [0.2.1](https://github.com/lostdesign/linked/compare/v0.2.0...v0.2.1) - 2021-03-23 279 | 280 | - ♻️ remove static toolbar menu 281 | - 🐛 set app title 282 | 283 | ## [0.2.0](https://github.com/lostdesign/linked/compare/v0.1.0...v0.2.0) - 2021-03-23 284 | 285 | - 💥 switch to json files #16 286 | 287 | ## [0.1.0](https://github.com/lostdesign/linked/compare/v0.0.1...v0.1.0) - 2021-03-22 288 | 289 | - 💥 left/right arrow no longer switches days, now uses CTRL+SHIFT+Arrows 290 | - 💄 spacing has been adjusted 291 | - ✨ click anywhere in the editor area will focus into the editor 292 | 293 | ## [0.0.1](https://github.com/lostdesign/linked/releases/tag/v0.0.1) - 2021-03-22 294 | 295 | - ✨ auto saving per day 296 | - ✨ tiptap editor implemented 297 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | twitter @lostdesign. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via [github discussions](https://github.com/lostdesign/linked/discussions), 4 | before making a change. 5 | 6 | Please note we have a [code of conduct](/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. 7 | 8 | ## Commits 9 | 10 | 1. Use [gitmoji](https://gitmoji.dev/) followed by the message like: `✨ add new feature` 11 | 2. Do not bump the version in readme or package.json 12 | 3. Do not tag your commits 13 | 14 | ## Pull Request Process 15 | 16 | 1. Please do not open draft PRs. 17 | 2. Describe what you changed and why you propose this change as well as how to quickly test your addition. 18 | 3. Ensure any install or build dependencies are removed before the end of the layer when doing a 19 | build. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Promotional Image 2 |
3 | GitHub release (latest by date) 4 | Project downloads 5 | Discord 6 | GitHub issues 7 | 8 | # linked - daily journaling without distraction 9 | An easy, distraction-free way to record your thoughts, declutter your mind and keep the things you want to remember. We all only have so much room in our brains for things. Let Linked be the place to put something you want to remember and let you free up space for deeper thinking. 10 | 11 | **[You can download linked here for free!](https://github.com/lostdesign/linked/releases/latest)** 12 | 13 | **Join the discord at [https://discord.gg/uNjJzZvccr](https://discord.gg/uNjJzZvccr)** 14 | 15 | ## Features 16 | 17 | - 📅 Write down anything and as much as you want per day 18 | - 🔍 Search across all days 19 | - ✍️ Support for various text styles as well as todo, list and code blocks 20 | - 🖼 Linked comes in dark and light mode 21 | - 💻 Keyboard navigation for maximum productivity 22 | - 💾 Files are forever yours, you can find them at `~/Documents/linked` 23 | - 🌐 Multi language support 24 | 25 | ### Upcoming 26 | 27 | - 🔗 link days together for references 28 | - 🗓 Month overview 29 | - ⭐️ Rate your days 30 | - 📶 sync across devices 31 | - (📱 phone support?) 32 | 33 | ## 💖 Sponsor 34 | 35 | The app will always be opensource and free - if you enjoy the app, please consider [becoming a sponsor or leave a tip](https://github.com/sponsors/lostdesign). 36 | 37 | 38 | ## Keyboard Shortcuts 39 | 40 |
41 | Keyboard Shortcuts 42 | 43 | **Search** Cmd or Ctrl + K. 44 | 45 | **Today** Cmd or Ctrl + . 46 | 47 | **Next Day** Cmd or Ctrl + N 48 | 49 | **Previous Day** Cmd or Ctrl + P 50 | 51 | **Next Week** Cmd or Ctrl + Shift + N 52 | 53 | **Previous Week** Cmd or Ctrl + Shift + P 54 | 55 | **Settings** Cmd or Ctrl + , 56 | 57 | **Leave Settings** Esc 58 | 59 | **Exit Code Block** Cmd or Ctrl + Enter 60 |
61 | 62 | 63 | ## Contributing 64 | Please check [Contributing.md](/CONTRIBUTING.md) first before opening a pull request please. 65 | 66 |
67 | How to run locally 68 | 69 | 70 | 1. Check your node version, it must be v15 or newer 71 | 72 | ``` 73 | node --version 74 | ``` 75 | 76 | 2. Clone the repository (make sure you have git installed) 77 | 78 | ``` 79 | git clone https://github.com/lostdesign/linked.git 80 | ``` 81 | 82 | 3. Change to the newly downloaded directory 83 | 84 | ``` 85 | cd linked/ 86 | ``` 87 | 88 | 4. Install project dependencies 89 | 90 | ``` 91 | yarn 92 | ``` 93 | 94 | 5. Start the application 95 | 96 | ``` 97 | yarn electron:serve 98 | ``` 99 |
100 | 101 | Make sure to follow [@uselinked](https://twitter.com/uselinked) on twitter to get the latest news about the project or feel free to check [github discussions](https://github.com/lostdesign/linked/discussions). 102 | 103 | -------------------------------------------------------------------------------- /afterSignHook.js: -------------------------------------------------------------------------------- 1 | // "afterSign": "./afterSignHook.js", 2 | 3 | require('dotenv').config() 4 | const fs = require('fs') 5 | const path = require('path') 6 | var electron_notarize = require('electron-notarize') 7 | 8 | module.exports = async function(params) { 9 | if (process.platform !== 'darwin') { 10 | return 11 | } 12 | 13 | console.log('afterSign hook triggered', params) 14 | 15 | let appId = 'design.lost.linked' 16 | 17 | let appPath = path.join( 18 | params.appOutDir, 19 | `${params.packager.appInfo.productFilename}.app` 20 | ) 21 | if (!fs.existsSync(appPath)) { 22 | console.log('skip') 23 | return 24 | } 25 | 26 | console.log(`Notarizing ${appId} found at ${appPath}`) 27 | 28 | try { 29 | await electron_notarize.notarize({ 30 | appBundleId: appId, 31 | appPath: appPath, 32 | appleId: process.env.APPLE_ID, 33 | appleIdPassword: process.env.APPLE_ID_PASSWORD 34 | }) 35 | } catch (error) { 36 | console.error(error) 37 | process.exit(1) 38 | } 39 | 40 | console.log(`Done notarizing ${appId}`) 41 | } 42 | -------------------------------------------------------------------------------- /appIcon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/appIcon/icon.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/cli-plugin-babel/preset'] 3 | } 4 | -------------------------------------------------------------------------------- /build/entitlements.mac.inherit.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-jit 6 | 7 | com.apple.security.cs.allow-unsigned-executable-memory 8 | 9 | 10 | -------------------------------------------------------------------------------- /build/icons/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/1024x1024.png -------------------------------------------------------------------------------- /build/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/128x128.png -------------------------------------------------------------------------------- /build/icons/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/16x16.png -------------------------------------------------------------------------------- /build/icons/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/24x24.png -------------------------------------------------------------------------------- /build/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/256x256.png -------------------------------------------------------------------------------- /build/icons/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/32x32.png -------------------------------------------------------------------------------- /build/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/48x48.png -------------------------------------------------------------------------------- /build/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/512x512.png -------------------------------------------------------------------------------- /build/icons/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/64x64.png -------------------------------------------------------------------------------- /build/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/icon.icns -------------------------------------------------------------------------------- /build/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/build/icons/icon.ico -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: /src/locales/en-US.json 3 | translation: /src/locales/%locale%.json 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "linked", 3 | "version": "1.5.2", 4 | "private": true, 5 | "description": "Link your thoughts to days.", 6 | "author": "André Weller (https://lost.design/)", 7 | "scripts": { 8 | "serve": "vue-cli-service serve", 9 | "build": "vue-cli-service build", 10 | "lint": "vue-cli-service lint", 11 | "build:all": "yarn run build:osx && yarn run build:win && yarn run build:linux", 12 | "build:linux": "yarn electron:build -p never -- --linux", 13 | "build:osx": "yarn electron:build -p never", 14 | "build:win": "yarn electron:build -p never -- --win --x64 --ia32", 15 | "electron:build": "vue-cli-service electron:build", 16 | "electron:icon": "electron-icon-builder --input=./appIcon/icon.png --output=./build --flatten", 17 | "electron:serve": "vue-cli-service electron:serve", 18 | "i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\"", 19 | "postinstall": "electron-builder install-app-deps", 20 | "postuninstall": "electron-builder install-app-deps", 21 | "publish:all": "yarn run publish:osx && yarn run publish:win && yarn run publish:linux", 22 | "publish:linux": "yarn electron:build -- --linux -p always", 23 | "publish:osx": "yarn electron:build -p always", 24 | "publish:win": "yarn electron:build -- --win --x64 --ia32 -p always" 25 | }, 26 | "main": "background.js", 27 | "dependencies": { 28 | "@sentry/electron": "2.5.4", 29 | "@tiptap/core": "2.0.0-beta.172", 30 | "@tiptap/extension-bold": "2.0.0-beta.26", 31 | "@tiptap/extension-bullet-list": "2.0.0-beta.26", 32 | "@tiptap/extension-character-count": "^2.0.0-beta.26", 33 | "@tiptap/extension-code-block": "2.0.0-beta.37", 34 | "@tiptap/extension-document": "2.0.0-beta.15", 35 | "@tiptap/extension-gapcursor": "^2.0.0-beta.34", 36 | "@tiptap/extension-heading": "2.0.0-beta.26", 37 | "@tiptap/extension-highlight": "2.0.0-beta.33", 38 | "@tiptap/extension-history": "2.0.0-beta.21", 39 | "@tiptap/extension-horizontal-rule": "^2.0.0-beta.199", 40 | "@tiptap/extension-image": "2.0.0-beta.25", 41 | "@tiptap/extension-italic": "2.0.0-beta.26", 42 | "@tiptap/extension-link": "2.0.0-beta.36", 43 | "@tiptap/extension-list-item": "2.0.0-beta.20", 44 | "@tiptap/extension-paragraph": "2.0.0-beta.23", 45 | "@tiptap/extension-placeholder": "^2.0.0-beta.48", 46 | "@tiptap/extension-strike": "2.0.0-beta.27", 47 | "@tiptap/extension-task-item": "2.0.0-beta.31", 48 | "@tiptap/extension-task-list": "2.0.0-beta.26", 49 | "@tiptap/extension-text": "2.0.0-beta.15", 50 | "@tiptap/pm": "^2.0.3", 51 | "@tiptap/suggestion": "^2.0.0-beta.90", 52 | "@tiptap/vue-2": "2.0.0-beta.77", 53 | "core-js": "^3.20.3", 54 | "electron-store": "8.0.1", 55 | "electron-updater": "4.6.5", 56 | "flexsearch": "0.7.21", 57 | "fs-extra": "^10.0.0", 58 | "highlight.js": "10.6.0", 59 | "lodash": "^4.17.21", 60 | "luxon": "2.3.0", 61 | "node-fetch": "^2.6.7", 62 | "tippy.js": "^6.3.7", 63 | "v8-compile-cache": "^2.3.0", 64 | "vue": "2.6.14", 65 | "vue-i18n": "8.27.0", 66 | "vue-router": "3.5.3", 67 | "vuex": "^3.6.2" 68 | }, 69 | "devDependencies": { 70 | "@vue/cli-plugin-babel": "~4.5.0", 71 | "@vue/cli-plugin-eslint": "~4.5.0", 72 | "@vue/cli-service": "~4.5.0", 73 | "autoprefixer": "^9", 74 | "babel-eslint": "10.1.0", 75 | "dotenv": "16.0.0", 76 | "electron": "17.0.0", 77 | "electron-builder": "23.0.2", 78 | "electron-devtools-installer": "3.1.1", 79 | "electron-icon-builder": "1.0.2", 80 | "electron-notarize": "1.0.0", 81 | "eslint": "7.32.0", 82 | "eslint-plugin-vue": "7.20.0", 83 | "postcss": "^7", 84 | "prompts": "2.3.2", 85 | "tailwindcss": "npm:@tailwindcss/postcss7-compat", 86 | "vue-cli-plugin-electron-builder": "~2.1.1", 87 | "vue-cli-plugin-i18n": "~2.3.1", 88 | "vue-svg-loader": "0.17.0-beta.2", 89 | "vue-template-compiler": "2.6.14" 90 | }, 91 | "eslintConfig": { 92 | "root": true, 93 | "env": { 94 | "node": true 95 | }, 96 | "globals": { 97 | "__static": "readable", 98 | "mainStorage": "writable" 99 | }, 100 | "extends": [ 101 | "plugin:vue/essential", 102 | "eslint:recommended" 103 | ], 104 | "parserOptions": { 105 | "parser": "babel-eslint" 106 | }, 107 | "rules": {} 108 | }, 109 | "browserslist": [ 110 | "> 1%", 111 | "last 2 versions", 112 | "not dead" 113 | ], 114 | "keywords": [ 115 | "journal", 116 | "calendar" 117 | ], 118 | "license": "GPL-3.0", 119 | "repository": { 120 | "type": "git", 121 | "url": "https://github.com/lostdesign/linked" 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {} 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostdesign/linked/94389fab45b06db5fbdf32b945e7a279899ee532/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 91 | -------------------------------------------------------------------------------- /src/assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | h1 { 6 | @apply text-4xl font-bold mb-2; 7 | } 8 | 9 | h2 { 10 | @apply text-2xl font-bold mb-2; 11 | } 12 | 13 | h3 { 14 | @apply text-xl font-bold mb-2; 15 | } 16 | 17 | ::-webkit-scrollbar { 18 | display: none; 19 | } 20 | 21 | blockquote { 22 | @apply border-l-4 border-gray-600 text-gray-400 py-4 pl-4 m-2 italic; 23 | } 24 | blockquote p { 25 | display: inline; 26 | } 27 | 28 | mark { 29 | @apply bg-yellow-200; 30 | } 31 | 32 | .editor { 33 | position: relative; 34 | } 35 | .editor__floating-menu { 36 | position: absolute; 37 | z-index: 1; 38 | margin-top: -0.25rem; 39 | visibility: hidden; 40 | opacity: 0; 41 | transition: opacity 0.2s, visibility 0.2s; 42 | } 43 | .editor__floating-menu.is-active { 44 | opacity: 1; 45 | visibility: visible; 46 | } 47 | 48 | ul[data-type='todo_list'] { 49 | padding-left: 0; 50 | } 51 | li[data-type='todo_item'] { 52 | display: flex; 53 | flex-direction: row; 54 | } 55 | ul[data-type='taskList'] input[type='checkbox'] { 56 | margin-right: 0.5rem; 57 | user-select: none; 58 | -webkit-user-select: none; 59 | cursor: pointer; 60 | } 61 | 62 | .menubar__button { 63 | @apply text-gray-800 py-2 px-3 rounded-sm text-xs font-black; 64 | } 65 | 66 | code { 67 | @apply bg-gray-800 dark:text-gray-100 text-gray-200 p-2 rounded-lg block box-border text-xs; 68 | } 69 | 70 | pre::before { 71 | content: attr(data-language); 72 | text-transform: uppercase; 73 | display: block; 74 | text-align: right; 75 | font-weight: bold; 76 | font-size: 0.6rem; 77 | } 78 | pre code .hljs-comment, 79 | pre code .hljs-quote { 80 | color: #999; 81 | } 82 | pre code .hljs-variable, 83 | pre code .hljs-template-variable, 84 | pre code .hljs-attribute, 85 | pre code .hljs-tag, 86 | pre code .hljs-name, 87 | pre code .hljs-regexp, 88 | pre code .hljs-link, 89 | pre code .hljs-name, 90 | pre code .hljs-selector-id, 91 | pre code .hljs-selector-class { 92 | color: #f2777a; 93 | } 94 | pre code .hljs-number, 95 | pre code .hljs-meta, 96 | pre code .hljs-built_in, 97 | pre code .hljs-builtin-name, 98 | pre code .hljs-literal, 99 | pre code .hljs-type, 100 | pre code .hljs-params { 101 | color: #f99157; 102 | } 103 | pre code .hljs-string, 104 | pre code .hljs-symbol, 105 | pre code .hljs-bullet { 106 | color: #9c9; 107 | } 108 | pre code .hljs-title, 109 | pre code .hljs-section { 110 | color: #fc6; 111 | } 112 | pre code .hljs-keyword, 113 | pre code .hljs-selector-tag { 114 | color: #69c; 115 | } 116 | pre code .hljs-emphasis { 117 | font-style: italic; 118 | } 119 | pre code .hljs-strong { 120 | font-weight: 700; 121 | } 122 | .ProseMirror:focus { 123 | outline: none; 124 | } 125 | 126 | .ProseMirror > ol, 127 | ul { 128 | list-style-type: disc !important; 129 | margin: 0 0.8rem !important; 130 | padding: 0.5rem !important; 131 | } 132 | 133 | ul[data-type='taskList'] { 134 | list-style: none; 135 | padding: 0 !important; 136 | margin: 0 !important; 137 | } 138 | ul[data-type='taskList'] li { 139 | display: flex; 140 | align-items: center; 141 | } 142 | ul[data-type='taskList'] li > input { 143 | flex: 0 0 auto; 144 | margin-right: 0.5rem; 145 | } 146 | ul[data-type='taskList'] input[type='checkbox'] { 147 | cursor: pointer; 148 | } 149 | ul[data-type='taskList'] { 150 | list-style: none; 151 | padding: 0; 152 | } 153 | ul[data-type='taskList'] li { 154 | display: flex; 155 | align-items: center; 156 | } 157 | ul[data-type='taskList'] li > input { 158 | flex: 0 0 auto; 159 | margin-right: 0.5rem; 160 | } 161 | 162 | .floating-menu { 163 | display: flex; 164 | padding: 0.2rem 0; 165 | border-radius: 0.5rem; 166 | margin-top: -0.2rem; 167 | margin-left: -0.5rem; 168 | transition: visibility 0.1s ease, opacity 0.1s ease; 169 | } 170 | .floating-menu button { 171 | @apply px-1 dark:text-gray-600; 172 | } 173 | .floating-menu button:hover, 174 | .floating-menu button.is-active { 175 | @apply text-gray-700 dark:text-gray-400; 176 | } 177 | 178 | .bubble-menu { 179 | @apply flex bg-gray-100 dark:bg-secondary-black ring-2 ring-gray-400 dark:ring-gray-700 shadow-2xl; 180 | padding: 0.3rem; 181 | margin-bottom: 0.3rem; 182 | border-radius: 0.5rem; 183 | transition: visibility 0.1s ease, opacity 0.1s ease; 184 | z-index: 10; 185 | } 186 | 187 | .bubble-menu button { 188 | @apply text-gray-600 dark:text-gray-500 px-2 py-1 rounded-lg; 189 | border: none; 190 | background: none; 191 | font-size: 0.85rem; 192 | font-weight: 500; 193 | } 194 | 195 | .bubble-menu button:focus, 196 | .bubble-menu button:hover, 197 | .bubble-menu button.is-active { 198 | @apply text-white bg-gray-400 dark:bg-gray-700 focus:bg-gray-700 outline-none; 199 | } 200 | 201 | .ProseMirror a { 202 | @apply cursor-pointer text-bright-pink underline; 203 | } 204 | 205 | .ProseMirror a:hover { 206 | @apply text-pink; 207 | } 208 | 209 | 210 | /* Placeholder styles */ 211 | .ProseMirror .is-empty:first-child::before { 212 | @apply text-gray-600 font-normal; 213 | content: attr(data-placeholder); 214 | float: left; 215 | pointer-events: none; 216 | height: 0; 217 | } 218 | /* Reset placeholder text for codeblocks */ 219 | .ProseMirror pre[data-placeholder="Type / for blocks"]::before { 220 | content: '' !important; 221 | } 222 | 223 | hr { 224 | @apply border-t border-gray-400 dark:border-gray-500 my-3; 225 | } -------------------------------------------------------------------------------- /src/assets/icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/icons/back.svg: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/dropdown.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/editor/bold.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/editor/bullet-list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/assets/icons/editor/checkbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/editor/code.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/editor/detail.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/editor/divider.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/editor/heading-one.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/editor/heading-three.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/editor/heading-two.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/editor/italic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/editor/pen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/editor/strikethrough.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/moon.svg: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/sun.svg: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/tick.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | require('v8-compile-cache') 4 | 5 | import { 6 | app, 7 | protocol, 8 | BrowserWindow, 9 | ipcMain, 10 | nativeTheme, 11 | Menu, 12 | Notification, 13 | dialog 14 | } from 'electron' 15 | 16 | const isDevelopment = process.env.NODE_ENV !== 'production' 17 | const isWindows = process.platform === 'win32' 18 | const isMacOS = process.platform === 'darwin' 19 | 20 | let win 21 | 22 | // Turn off software rasterizer for less resource usage 23 | app.commandLine.appendSwitch('disable-software-rasterizer', 'true') 24 | app.setAppUserModelId(process.execPath) 25 | 26 | protocol.registerSchemesAsPrivileged([ 27 | { scheme: 'app', privileges: { secure: true, standard: true } } 28 | ]) 29 | 30 | const path = require('path') 31 | export const DAILY = 1000 * 60 * 60 * 24 32 | export const WEEKLY = DAILY * 7 33 | const basePath = path.join(app.getPath('documents'), 'linked') 34 | 35 | const Store = require('electron-store') 36 | global.storage = new Store({ 37 | watch: true, 38 | defaults: { 39 | isSetupFinished: false, 40 | language: 'en-US', 41 | theme: 'dark', 42 | searchMode: 'forward', 43 | enableUpdates: true, 44 | updateInterval: DAILY, 45 | dataPath: basePath, 46 | allowPrerelease: false 47 | } 48 | }) 49 | 50 | import updater from './updater' 51 | 52 | const template = [ 53 | { 54 | label: app.name, 55 | submenu: [ 56 | { role: 'about' }, 57 | { 58 | label: 'Settings', 59 | accelerator: 'CommandOrControl + ,', 60 | click() { 61 | reopenWindowAndSendWebContents('open-settings') 62 | } 63 | }, 64 | { type: 'separator' }, 65 | { role: 'quit' } 66 | ] 67 | }, 68 | { 69 | label: 'Edit', 70 | submenu: [ 71 | { role: 'undo' }, 72 | { role: 'redo' }, 73 | { type: 'separator' }, 74 | { role: 'cut' }, 75 | { role: 'copy' }, 76 | { role: 'paste' }, 77 | ...(isMacOS 78 | ? [ 79 | { role: 'delete' }, 80 | { role: 'selectAll' }, 81 | { type: 'separator' }, 82 | { 83 | label: 'Speech', 84 | submenu: [{ role: 'startSpeaking' }, { role: 'stopSpeaking' }] 85 | } 86 | ] 87 | : [{ role: 'delete' }, { type: 'separator' }, { role: 'selectAll' }]) 88 | ] 89 | }, 90 | { 91 | label: 'View', 92 | submenu: [ 93 | { 94 | label: 'Today', 95 | click() { 96 | reopenWindowAndSendWebContents('set-today') 97 | }, 98 | accelerator: 'CommandOrControl + .' 99 | }, 100 | { 101 | label: 'Search', 102 | click() { 103 | reopenWindowAndSendWebContents('set-search') 104 | }, 105 | accelerator: 'CommandOrControl + K' 106 | }, 107 | { type: 'separator' }, 108 | { 109 | label: 'Previous Day', 110 | click() { 111 | reopenWindowAndSendWebContents('previous-day') 112 | }, 113 | accelerator: 'CommandOrControl + P' 114 | }, 115 | { 116 | label: 'Next Day', 117 | click() { 118 | reopenWindowAndSendWebContents('next-day') 119 | }, 120 | accelerator: 'CommandOrControl + N' 121 | }, 122 | { type: 'separator' }, 123 | { 124 | label: 'Previous Week', 125 | click() { 126 | reopenWindowAndSendWebContents('previous-week') 127 | }, 128 | accelerator: 'CommandOrControl + Shift + P' 129 | }, 130 | { 131 | label: 'Next Week', 132 | click() { 133 | reopenWindowAndSendWebContents('next-week') 134 | }, 135 | accelerator: 'CommandOrControl + Shift + N' 136 | }, 137 | { type: 'separator' }, 138 | { role: 'reload' }, 139 | { role: 'minimize' } 140 | ] 141 | }, 142 | { 143 | role: 'help', 144 | submenu: [ 145 | { 146 | label: 'Documentation', 147 | click: async () => { 148 | const { shell } = require('electron') 149 | await shell.openExternal('https://uselinked.com/') 150 | } 151 | }, 152 | { 153 | label: 'Check for updates', 154 | click: async () => updater.askForUpdates() 155 | } 156 | ] 157 | } 158 | ] 159 | 160 | const menu = Menu.buildFromTemplate(template) 161 | Menu.setApplicationMenu(menu) 162 | 163 | const createWindow = () => { 164 | win = new BrowserWindow({ 165 | width: 470, 166 | minWidth: 450, 167 | height: 850, 168 | minHeight: 450, 169 | title: 'linked', 170 | backgroundColor: '#161616', 171 | webPreferences: { 172 | devTools: process.env.NODE_ENV === 'development', 173 | nodeIntegration: true, 174 | contextIsolation: false, 175 | enableRemoteModule: true, 176 | spellcheck: false 177 | } 178 | }) 179 | 180 | if (process.env.WEBPACK_DEV_SERVER_URL) { 181 | win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) 182 | if (!process.env.IS_TEST) win.webContents.openDevTools() 183 | } else { 184 | const { createProtocol } = require('vue-cli-plugin-electron-builder/lib') 185 | createProtocol('app') 186 | win.loadURL('app://./index.html') 187 | nativeTheme.themeSource = global.storage.get('theme') 188 | } 189 | 190 | win.on('closed', () => { win = null }) 191 | } 192 | 193 | app.on('window-all-closed', () => { 194 | if (!isMacOS) { 195 | app.quit() 196 | } 197 | }) 198 | 199 | app.on('window-all-closed', () => { if (!isMacOS) app.quit() }) 200 | app.on('activate', () => { if (win === null) createWindow()} ) 201 | 202 | import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer' 203 | 204 | app.whenReady().then(async () => { 205 | if (isDevelopment && !process.env.IS_TEST) { 206 | try { 207 | await installExtension(VUEJS_DEVTOOLS) 208 | } catch (e) { 209 | console.error('Vue Devtools failed to install:', e.toString()) 210 | } 211 | } 212 | createWindow() 213 | updater.setupUpdates() 214 | }) 215 | 216 | if (isDevelopment) { 217 | if (isWindows) { 218 | process.on('message', (data) => { 219 | if (data === 'graceful-exit') { 220 | app.quit() 221 | } 222 | }) 223 | } else { 224 | process.on('SIGTERM', () => { 225 | app.quit() 226 | }) 227 | } 228 | } 229 | 230 | const reopenWindowAndSendWebContents = (message) => { 231 | if (!win) { 232 | createWindow() 233 | app.whenReady().then(() => { 234 | setTimeout(() => { 235 | win.webContents.send(message) 236 | }, 300) 237 | }) 238 | } 239 | win.webContents.send(message) 240 | } 241 | 242 | /* 243 | * IPC MAIN COMMUNICATION 244 | */ 245 | 246 | ipcMain.handle('GET_STORAGE_VALUE', (event, key) => { 247 | return global.storage.get(key) 248 | }) 249 | 250 | ipcMain.handle('SET_STORAGE_VALUE', (event, key, data) => { 251 | return global.storage.set(key, data) 252 | }) 253 | 254 | ipcMain.handle('DELETE_STORAGE_VALUE', (event, key) => { 255 | return global.storage.delete(key) 256 | }) 257 | 258 | ipcMain.handle('SET_DATA_PATH', async () => { 259 | const currentPath = global.storage.get('dataPath') 260 | const result = await dialog.showOpenDialog(win, { 261 | properties: ['openDirectory', 'createDirectory'] 262 | }) 263 | 264 | if (result.canceled === true) { 265 | new Notification({ 266 | title: 'Action aborted', 267 | body: 'Your previous settings still apply.' 268 | }).show() 269 | 270 | return currentPath 271 | } 272 | 273 | const newPath = result.filePaths.length > 0 274 | ? result.filePaths[0] 275 | : basePath 276 | 277 | searchIndex = new Document({ 278 | document: { 279 | id: 'date', 280 | index: ['content'], 281 | store: true 282 | }, 283 | tokenize: global.storage.get('searchMode') 284 | }) 285 | 286 | if ((await fs.promises.readdir(newPath)).length !== 0) { 287 | await dialog.showMessageBox(win, { 288 | message: 'Directory not empty!', 289 | detail: `${newPath} is not empty, please choose another directory or add an empty directory at the desired location first.`, 290 | type: 'error', 291 | buttons: ['Close'], 292 | defaultId: 1, 293 | noLink: true 294 | }) 295 | 296 | return global.storage.get('dataPath') 297 | } 298 | 299 | const fsEx = require('fs-extra') 300 | try { 301 | await fsEx.move(currentPath, newPath, { overwrite: true }) 302 | } catch (e) { 303 | await dialog.showMessageBox(win, { 304 | message: 'An error occured!', 305 | detail: e.toString(), 306 | type: 'error', 307 | buttons: ['Close'], 308 | defaultId: 1, 309 | noLink: true 310 | }) 311 | return global.storage.get('dataPath') 312 | } 313 | 314 | global.storage.set('dataPath', newPath) 315 | await repairSearchDatabase() 316 | 317 | new Notification({ 318 | title: 'Successfully set new path!', 319 | body: `Your data now is being read from ${newPath}.` 320 | }).show() 321 | 322 | return global.storage.get('dataPath') 323 | }) 324 | 325 | 326 | ipcMain.handle('TOGGLE_THEME', (event, mode) => { 327 | if (mode === 'light') { 328 | nativeTheme.themeSource = 'light' 329 | } else { 330 | nativeTheme.themeSource = 'dark' 331 | } 332 | return nativeTheme.shouldUseDarkColors 333 | }) 334 | 335 | const fs = require('fs') 336 | 337 | ipcMain.handle('FETCH_FILE', async (event, args) => { 338 | const [year, fileName] = args 339 | const dataPath = getFilePath(year) 340 | const filePath = `${dataPath}/${fileName}.json` 341 | let file 342 | 343 | // create the file if it does not exist yet 344 | if (!fs.existsSync(filePath)) { 345 | file = fs.promises.mkdir(dataPath, { recursive: true }).then(() => { 346 | return fs.promises.writeFile(filePath, getDefaultData()).then(() => { 347 | return fs.promises.readFile(filePath, 'utf-8').then((data) => { 348 | return JSON.parse(data) 349 | }) 350 | }) 351 | }) 352 | } else { 353 | file = fs.promises.readFile(filePath, 'utf-8').then(data => JSON.parse(data)) 354 | } 355 | 356 | // return the file 357 | return file 358 | }) 359 | 360 | import { Document } from 'flexsearch' 361 | 362 | let searchIndex = new Document({ 363 | document: { 364 | id: 'date', 365 | index: ['content'], 366 | store: true 367 | }, 368 | tokenize: global.storage.get('searchMode') 369 | }) 370 | 371 | const searchIndexPath = `${app.getPath('userData')}/search-index/` 372 | 373 | const createSearchIndexFolder = () => { 374 | !fs.existsSync(searchIndexPath) && fs.mkdirSync(searchIndexPath, { recursive: true }) 375 | } 376 | 377 | const exportIndex = async () => { 378 | createSearchIndexFolder() 379 | searchIndex.export( 380 | (key, data) => fs.writeFileSync(`${searchIndexPath}${key}.json`, data !== undefined ? data : '') 381 | ) 382 | } 383 | 384 | const retrieveIndex = async () => { 385 | createSearchIndexFolder() 386 | const keys = fs 387 | .readdirSync(searchIndexPath, { withFileTypes: true }) 388 | .filter(item => !item.isDirectory()) 389 | .map(item => item.name) 390 | 391 | for (let i = 0, key; i < keys.length; i += 1) { 392 | key = keys[i] 393 | 394 | // TODO: mac sometimes creates this file in the search index folder, which causes the app to exit 395 | if (key === '.DS_Store') continue 396 | 397 | const data = fs.readFileSync(`${searchIndexPath}${key}`, 'utf8') 398 | searchIndex.import(key.slice(0, -5), data === undefined ? null : data) 399 | } 400 | } 401 | 402 | 403 | ipcMain.handle('SAVE_FILE', (event, args) => { 404 | const [year, fileName, content, rating] = args 405 | const dataPath = getFilePath(year, fileName) 406 | const filePath = `${dataPath}/${fileName}.json` 407 | 408 | searchIndex.update(fileName, { 409 | date: fileName, 410 | content: tokenizer(content) 411 | }) 412 | 413 | fs.promises.writeFile( 414 | filePath, 415 | JSON.stringify({ 416 | content: content, 417 | rating: rating 418 | }) 419 | ) 420 | 421 | exportIndex() 422 | }) 423 | 424 | ipcMain.handle('SEARCH', async (event, search) => { 425 | const results = searchIndex.search(search) 426 | 427 | if (results.length >= 1 ) { 428 | const dates = results[0].result 429 | let dataResult = [] 430 | 431 | for (const date of dates) { 432 | await fs.promises.readFile(`${getFilePath(date.substring(0,4))}/${date}.json`, 'utf-8').then((data) => { 433 | dataResult.push({ 434 | date: date, 435 | ...JSON.parse(data) 436 | }) 437 | }) 438 | } 439 | 440 | return dataResult.sort((a, b) => { 441 | let keyA = new Date(a.date), keyB = new Date(b.date) 442 | 443 | if (keyA < keyB) return 1 444 | if (keyA > keyB) return -1 445 | 446 | return 0 447 | }) 448 | } 449 | return {} 450 | }) 451 | 452 | ipcMain.handle('LOAD_SEARCH_INDEX', async () => { 453 | return retrieveIndex() 454 | }) 455 | 456 | /** 457 | * Cleans the content from any html elements, as well as deleting any 458 | * base64 images and removing duplicates. 459 | * @param content 460 | * @returns { String } 461 | */ 462 | const tokenizer = (content) => { 463 | const cleanedHtml = content.replace(/(<([^>]+)>)/gi, ' ').split(' ') 464 | return cleanedHtml.filter((word, index, self) => self.indexOf(word) === index) 465 | } 466 | 467 | ipcMain.handle('REINDEX_ALL', async () => repairSearchDatabase()) 468 | 469 | const repairSearchDatabase = async () => { 470 | searchIndex = new Document({ 471 | document: { 472 | id: 'date', 473 | index: ['content'], 474 | store: true 475 | }, 476 | tokenize: global.storage.get('searchMode') 477 | }) 478 | 479 | const isYearFolder = (folder) => /\b\d{4}\b/g.test(folder) 480 | const dataPath = global.storage.get('dataPath') 481 | 482 | const getYearFolderFiles = (year) => 483 | fs.promises.readdir(getFilePath(year)) 484 | .then((files) => files.map((file) => `${year}/${file}`)) 485 | 486 | const years = 487 | await fs.promises.readdir(`${dataPath}`) 488 | .then((folders) => folders.filter(isYearFolder)) 489 | 490 | 491 | await Promise.all(years.map(getYearFolderFiles)) 492 | .then((yearFiles) => yearFiles.flat()) 493 | .then((dirtyFiles) => dirtyFiles.filter(file => file.match(/^(.*\.json$).*$/))) 494 | .then((cleanFiles) => 495 | cleanFiles.map((file) => { 496 | return { 497 | data: JSON.parse(fs.readFileSync(`${dataPath}/${file}`, "utf8")), 498 | date: file 499 | } 500 | }) 501 | ) 502 | .then((files) => 503 | files.forEach((file) => { 504 | let fileName = file.date.substring(5) 505 | fileName = fileName.slice(0, fileName.length-5) 506 | 507 | try { 508 | searchIndex.update(fileName, { 509 | date: fileName, 510 | content: tokenizer(file.data.content) 511 | }) 512 | } catch (e) { 513 | console.log('could not index day', fileName, file.data.content) 514 | } 515 | }) 516 | ) 517 | .then(() => exportIndex()) 518 | .then(() => { 519 | new Notification({ 520 | title: 'Search Index Updated!', 521 | body: 'Your database was successfully indexed! You may now search across all your data.' 522 | }).show() 523 | }) 524 | 525 | return true 526 | } 527 | 528 | /** 529 | * Construct the base path where files are stored and loaded from 530 | */ 531 | const getFilePath = (year) => { 532 | return `${global.storage.get('dataPath')}/${year}` 533 | } 534 | 535 | const getDefaultData = () => { 536 | return JSON.stringify({ 537 | content: '', 538 | rating: 0 539 | }) 540 | } 541 | -------------------------------------------------------------------------------- /src/components/app-header.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | -------------------------------------------------------------------------------- /src/components/day-switcher.vue: -------------------------------------------------------------------------------- 1 | 56 | 57 | 76 | -------------------------------------------------------------------------------- /src/components/editor.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 143 | -------------------------------------------------------------------------------- /src/components/language-dropdown.vue: -------------------------------------------------------------------------------- 1 | 101 | 102 | 154 | -------------------------------------------------------------------------------- /src/components/settings/allow-prerelease.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 28 | -------------------------------------------------------------------------------- /src/components/slash-commands/CommandsList.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 133 | 134 | -------------------------------------------------------------------------------- /src/components/slash-commands/commands.js: -------------------------------------------------------------------------------- 1 | import { Extension } from '@tiptap/core' 2 | import Suggestion from '@tiptap/suggestion' 3 | 4 | export default Extension.create({ 5 | name: 'slashCommand', 6 | 7 | addOptions() { 8 | return { 9 | suggestion: { 10 | char: '/', 11 | command: ({ editor, range, props }) => { 12 | props.command({ editor, range }) 13 | }, 14 | }, 15 | } 16 | }, 17 | 18 | addProseMirrorPlugins() { 19 | return [ 20 | Suggestion({ 21 | editor: this.editor, 22 | ...this.options.suggestion, 23 | }), 24 | ] 25 | }, 26 | }) -------------------------------------------------------------------------------- /src/components/slash-commands/suggestions.js: -------------------------------------------------------------------------------- 1 | import tippy from 'tippy.js' 2 | import { VueRenderer } from '@tiptap/vue-2' 3 | import CommandsList from './CommandsList.vue' 4 | import { translate } from '../../translation' 5 | 6 | export default { 7 | items: async ({ query }) => { 8 | const translationKey = 'commands.blocks' 9 | 10 | return [ 11 | { 12 | title: await translate(`${translationKey}.h1.title`), 13 | icon: 'heading-one', 14 | command: ({ editor, range }) => { 15 | editor.chain().focus().deleteRange(range).setNode('heading', { level: 1 }).run() 16 | }, 17 | }, 18 | { 19 | title: await translate(`${translationKey}.h2.title`), 20 | icon: 'heading-two', 21 | command: ({ editor, range }) => { 22 | editor.chain().focus().deleteRange(range).setNode('heading', { level: 2 }).run() 23 | }, 24 | }, 25 | { 26 | title: await translate(`${translationKey}.h3.title`), 27 | icon: 'heading-three', 28 | command: ({ editor, range }) => { 29 | editor.chain().focus().deleteRange(range).setNode('heading', { level: 3 }).run() 30 | }, 31 | }, 32 | { 33 | title: await translate(`${translationKey}.bold.title`), 34 | icon: 'bold', 35 | command: ({ editor, range }) => { 36 | editor.chain().focus().deleteRange(range).setMark('bold').run() 37 | }, 38 | }, 39 | { 40 | title: await translate(`${translationKey}.italic.title`), 41 | icon: 'italic', 42 | command: ({ editor, range }) => { 43 | editor.chain().focus().deleteRange(range).setMark('italic').run() 44 | }, 45 | }, 46 | { 47 | title: await translate(`${translationKey}.unorderedList.title`), 48 | icon: 'bullet-list', 49 | command: ({ editor, range }) => { 50 | editor.chain().focus().deleteRange(range).toggleBulletList().run() 51 | }, 52 | }, 53 | { 54 | title: await translate(`${translationKey}.task.title`), 55 | icon: 'check-box', 56 | command: ({editor, range}) => { 57 | editor.chain().focus().deleteRange(range).toggleTaskList().run() 58 | } 59 | }, 60 | { 61 | title: await translate(`${translationKey}.codeBlock.title`), 62 | icon: 'code-block', 63 | command: ({ editor, range }) => { 64 | editor.chain().focus().deleteRange(range).setCodeBlock().run() 65 | }, 66 | }, 67 | { 68 | title: await translate(`${translationKey}.divider.title`), 69 | icon: 'divider', 70 | command: ({ editor, range }) => { 71 | editor.chain().focus().deleteRange(range).setHorizontalRule().run() 72 | }, 73 | } 74 | ].filter(item => { 75 | return ( 76 | item.title?.toLowerCase().includes(query.toLowerCase()) 77 | || item.description?.toLowerCase().includes(query.toLowerCase()) 78 | ) 79 | }).slice(0, 10) 80 | }, 81 | 82 | render: () => { 83 | let component 84 | let popup 85 | 86 | return { 87 | onStart: props => { 88 | component = new VueRenderer(CommandsList, { 89 | parent: this, 90 | propsData: props, 91 | editor: props.editor, 92 | }) 93 | 94 | popup = tippy('body', { 95 | getReferenceClientRect: props.clientRect, 96 | appendTo: () => document.body, 97 | content: component.element, 98 | showOnCreate: true, 99 | interactive: true, 100 | trigger: 'manual', 101 | placement: 'bottom-start', 102 | }) 103 | }, 104 | 105 | onUpdate(props) { 106 | component.updateProps(props) 107 | 108 | popup[0].setProps({ 109 | getReferenceClientRect: props.clientRect, 110 | }) 111 | }, 112 | 113 | onKeyDown(props) { 114 | if (props.event.key === 'Escape') { 115 | popup[0].hide() 116 | 117 | return true 118 | } 119 | 120 | return component.ref?.onKeyDown(props) 121 | }, 122 | 123 | onExit() { 124 | popup[0].destroy() 125 | component.destroy() 126 | }, 127 | } 128 | }, 129 | } -------------------------------------------------------------------------------- /src/components/theme-switcher.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 62 | -------------------------------------------------------------------------------- /src/components/update-dropdown.vue: -------------------------------------------------------------------------------- 1 | 101 | 102 | 140 | -------------------------------------------------------------------------------- /src/components/week-switcher.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 66 | -------------------------------------------------------------------------------- /src/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | 4 | Vue.use(VueI18n) 5 | 6 | export const loadLocaleMessages = () => { 7 | const locales = require.context( 8 | './locales', 9 | true, 10 | /[A-Za-z0-9-_,\s]+\.json$/i 11 | ) 12 | 13 | const messages = {} 14 | 15 | locales.keys().map((key) => { 16 | const matched = key.match(/([A-Za-z0-9-_]+)\./i) 17 | 18 | if (matched && matched.length > 1) { 19 | const locale = matched[1] 20 | messages[locale] = locales(key) 21 | } 22 | }) 23 | 24 | return messages 25 | } 26 | 27 | export default new VueI18n({ 28 | locale: localStorage.lang || 'en-US', 29 | fallbackLocale: 'en-US', 30 | messages: loadLocaleMessages() 31 | }) 32 | -------------------------------------------------------------------------------- /src/locales/ar-AR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "العربية", 3 | "code": "ar-AR", 4 | "home": { 5 | "calendarWeek": "الأسبوع" 6 | }, 7 | "settings": { 8 | "back": "رجوع", 9 | "title": "الإعدادات", 10 | "designMode": { 11 | "title": "المظهر", 12 | "hint": "اختر بين موضوع فاتح أو داكن." 13 | }, 14 | "languages": { 15 | "title": "اللغة", 16 | "hint": "ما هي اللغة التي تريد استخدامها؟" 17 | }, 18 | "data": { 19 | "title": "مسار البيانات", 20 | "hint": "أين يجب تخزين بياناتك؟ الموقع الحالي:", 21 | "choose": "حدد موقعًا جديدًا" 22 | }, 23 | "updates": { 24 | "title": "الفاصل الزمني للتحديث", 25 | "hint": "كم مرة للتحقق من الإصدارات الجديدة؟", 26 | "daily": "اليومي", 27 | "weekly": "أسبوعي" 28 | }, 29 | "search": { 30 | "placeholder": "ابحث في ملاحظاتك ...", 31 | "no_result": "لا توجد نتائج لـ
{searchTerm} .", 32 | "start_searching": "ابحث عن كلمات أو عبارات فردية ، كما يمكنك استخدام أحرف البدل مثل أحب * ...", 33 | "result_amount": "النتائج", 34 | "index": { 35 | "title": "فهرس قاعدة البيانات", 36 | "hint": "ببدء الفهرسة ، سيتم مسح أيامك وإضافتها إلى قاعدة بيانات البحث. هذا ضروري فقط لبيانات المخزون قبل الإصدار 1.4.0. يمكنك العثور على مزيد من المعلومات على الموقع.", 37 | "start": "إصلاح قاعدة البيانات الآن" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "برنامج الاختبار التجريبي", 42 | "hint": "من خلال تمكين خانة الاختيار، ستتلقى إصدارات اختبارية من الإصدارات المرتبطة قبل إصدارها.", 43 | "enabled": "استخدام الإصدارات التجريبية" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "لم يتم العثور على أمر مطابق", 48 | "type_slash": "اكتب / للكتل", 49 | "blocks": { 50 | "h1": { 51 | "title": "العنوان 1", 52 | "description": "عنوان من المستوى الأول." 53 | }, 54 | "h2": { 55 | "title": "العنوان 2", 56 | "description": "عنوان من المستوى الثاني." 57 | }, 58 | "h3": { 59 | "title": "العنوان 3", 60 | "description": "عنوان من المستوى الثالث." 61 | }, 62 | "bold": { 63 | "title": "غامق", 64 | "description": "كتابة النص بخط عريض" 65 | }, 66 | "italic": { 67 | "title": "مائل", 68 | "description": "كتابة النص مائل" 69 | }, 70 | "task": { 71 | "title": "تودو", 72 | "description": "يضيف خانة اختيار المهام." 73 | }, 74 | "unorderedList": { 75 | "title": "القائمة النقطية", 76 | "description": "قائمة نقطية غير مرتبة." 77 | }, 78 | "codeBlock": { 79 | "title": "الرمز", 80 | "description": "يضيف كتلة كود." 81 | }, 82 | "divider": { 83 | "title": "مقسم أفقي", 84 | "description": "يضيف مقسمًا أفقيًا." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/bn-IN.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "বাংলা", 3 | "code": "bn-IN", 4 | "home": { 5 | "calendarWeek": "সপ্তাহ" 6 | }, 7 | "settings": { 8 | "back": "পূর্বে", 9 | "title": "সেটিংস্‌ সমূহ", 10 | "designMode": { 11 | "title": "রঙের ধরন", 12 | "hint": "আপনি হাল্কা বা গাঢ় এই দুইধরনের মধ্যে একটি বেছে নিতে পারেন" 13 | }, 14 | "languages": { 15 | "title": "ভাষা", 16 | "hint": "আপনি কোন ভাষায় লিঙ্কড ব্যবহার করতে চান?" 17 | }, 18 | "data": { 19 | "title": "তথ্যপথ", 20 | "hint": "আপনার তথ্য কোথায় সঞ্চিত থাকবে? বর্তমানে সঞ্চিত হয়: ", 21 | "choose": "নতুন তথ্যপথ বেছে নিন" 22 | }, 23 | "updates": { 24 | "title": "পরিবর্ধন", 25 | "hint": "কতক্ষণ অন্তর পরিবর্ধনের খোঁজ করবো?", 26 | "daily": "প্রত্যহ", 27 | "weekly": "সাপ্তাহিক" 28 | }, 29 | "search": { 30 | "placeholder": "আপনার টীকার খোঁজ করুন", 31 | "no_result": "
{searchTerm} এর জন্য কোনো ফলাফল পাওয়া যায়নি।", 32 | "start_searching": "শব্দ, বাক্য বা এমনকি আপনি ওয়াইল্ডকার্ড ব্যবহার করতে পারেন। যেমন আমি ভালবাসি * ...", 33 | "result_amount": "ফলাফল", 34 | "index":{ 35 | "title": "তথ্যভাণ্ডার সূচক", 36 | "hint": "সূচকীকরণের সূচনা করা হলে লিঙ্কড আপনার প্রত্যেকদিনের টীকাগুলিকে বিবেচনা করবে এবং তথ্য সুচকে যুক্ত করবে। এটি কেবলমাত্র একবারই করার দরকার হবে v1.4.0 তে পরিবর্ধন করার পর। আমাদের ওয়েবসাইটে এই বিষয়ে বিস্তারিত পাবেন।", 37 | "start": "তথ্যভাণ্ডারের মেরামতি করুন" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "পুর্বমুক্তি প্রকল্প", 42 | "hint": "চিন্হিতকরণের মাধ্যমে আপনি পরীক্ষণীয় নির্মাণগুলি ব্যবহার ও পরীক্ষা করতে পারবেন।" , 43 | "enabled": "পুর্বমুক্তি নির্মাণগুলি ব্যবহার করুন" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "এমন কোনো কম্যান্ড খুঁজে পাওয়া যায়নি", 48 | "type_slash": "ব্লকের জন্য / লিখুন", 49 | "blocks": { 50 | "h1": { 51 | "title": "শীর্ষক ১", 52 | "description": "প্রথম ক্রমের শীর্ষক" 53 | }, 54 | "h2": { 55 | "title": "শীর্ষক ২", 56 | "description": "দ্বিতীয় ক্রমের শীর্ষক" 57 | }, 58 | "h3": { 59 | "title": "শীর্ষক ৩", 60 | "description": "তৃতীয় ক্রমের শীর্ষক" 61 | }, 62 | "bold": { 63 | "title": "প্রগল্ভ", 64 | "description": "লেখনী মোটা হরফে লিখুন।" 65 | }, 66 | "italic": { 67 | "title": "বক্র", 68 | "description": "লেখনী বক্র হরফে লিখুন।" 69 | }, 70 | "task": { 71 | "title": "করণীয়", 72 | "description": "একটি করণীয় কাজের বন্ধণী যুক্ত করুন। " 73 | }, 74 | "unorderedList": { 75 | "title": "অবিন্যস্ত তালিকা", 76 | "description": "একটি অবিন্যস্ত তালিকা।" 77 | }, 78 | "codeBlock": { 79 | "title": "কোড", 80 | "description": "একগুচ্ছ কোড যুক্ত করুন।" 81 | }, 82 | "divider": { 83 | "title": "অনুভূমিক রেখা", 84 | "description": "একটি অনুভূমিক রেখা যুক্ত করুন" 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/ca-ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Català", 3 | "code": "ca-ES", 4 | "home": { 5 | "calendarWeek": "Setmana" 6 | }, 7 | "settings": { 8 | "back": "Tornar", 9 | "title": "Configuració", 10 | "designMode": { 11 | "title": "Mode de disseny", 12 | "hint": "Trieu entre un tema clar o fosc." 13 | }, 14 | "languages": { 15 | "title": "Idioma", 16 | "hint": "En quina llengua t'agradaria utilitzar linked?" 17 | }, 18 | "data": { 19 | "title": "Ruta de dades", 20 | "hint": "On s'han d'emmagatzemar les teves dades? Localització actual: ", 21 | "choose": "Seleccioneu una nova ubicació" 22 | }, 23 | "updates": { 24 | "title": "Interval d'actualització", 25 | "hint": "Amb quina freqüència cal comprovar si hi ha noves versions?", 26 | "daily": "Diàriament", 27 | "weekly": "Setmanalment" 28 | }, 29 | "search": { 30 | "placeholder": "Cerca les teves notes...", 31 | "no_result": "No hi ha cap resultat per a
{searchTerm}.", 32 | "start_searching": "Cerqueu paraules o frases individuals, també podeu utilitzar comodins com ara M'encanta *...", 33 | "result_amount": "resultats", 34 | "index": { 35 | "title": "índex de base de dades", 36 | "hint": "En començar la indexació, els vostres dies s'escanejaran i s'afegiran a la base de dades de cerca. Això només és necessari per a les dades d'inventari anteriors a la versió 1.4.0. Podeu trobar més informació al web.", 37 | "start": "Repareu la base de dades ara" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Programa de versions de proves", 42 | "hint": "En activar la casella, rebreu versions de prova del linked abans de la seva publicació.", 43 | "enabled": "Utilitza versions de proves" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No s'ha trobat cap ordre coincident", 48 | "type_slash": "Tipus / per als blocs", 49 | "blocks": { 50 | "h1": { 51 | "title": "Encapçalament 1", 52 | "description": "Un encapçalament de nivell u." 53 | }, 54 | "h2": { 55 | "title": "Encapçalament 2", 56 | "description": "Un encapçalament de nivell dos." 57 | }, 58 | "h3": { 59 | "title": "Encapçalament 3", 60 | "description": "Un encapçalament de nivell tres." 61 | }, 62 | "bold": { 63 | "title": "Negreta", 64 | "description": "Escriu el text en negreta." 65 | }, 66 | "italic": { 67 | "title": "Cursiva", 68 | "description": "Escriu el text en cursiva." 69 | }, 70 | "task": { 71 | "title": "Per fer", 72 | "description": "Afegeix una casella que indica tasca a fer" 73 | }, 74 | "unorderedList": { 75 | "title": "Llista", 76 | "description": "Una llista desordenada." 77 | }, 78 | "codeBlock": { 79 | "title": "Codi", 80 | "description": "Afegeix un bloc de codi." 81 | }, 82 | "divider": { 83 | "title": "Divisor horitzontal", 84 | "description": "Afegeix un divisor horitzontal." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/cs-CZ.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Čeština", 3 | "code": "cs-CZ", 4 | "home": { 5 | "calendarWeek": "Týden" 6 | }, 7 | "settings": { 8 | "back": "Zpět", 9 | "title": "Nastavení", 10 | "designMode": { 11 | "title": "Vzhled", 12 | "hint": "Můžete si vybrat mezi světlým a tmavým režimem." 13 | }, 14 | "languages": { 15 | "title": "Jazyk", 16 | "hint": "V jakém jazyce preferujete používat linked?" 17 | }, 18 | "data": { 19 | "title": "Cesta k datovému úložišti", 20 | "hint": "Kde by měla být vaše data uložena? V současné době jsou uložena v:", 21 | "choose": "Vyberte nové umístění" 22 | }, 23 | "updates": { 24 | "title": "Četnost aktualizací", 25 | "hint": "Jak dlouho kontrolovat aktualizace?", 26 | "daily": "Denně", 27 | "weekly": "Týdně" 28 | }, 29 | "search": { 30 | "placeholder": "Prohledejte své poznámky...", 31 | "no_result": "Nic nenalezeno pro
{searchTerm}.", 32 | "start_searching": "Hledejte slova, věty, nebo dokonce můžete použít i pokročilé zástupné znaky jako například Mám rád * ...", 33 | "result_amount": "Výsledky", 34 | "index": { 35 | "title": "Databázový index", 36 | "hint": "Spuštěním indexování linked prohledá vaše dny a přidá je do vyhledávacího indexu. Toto je nutné provést pouze jednou po aktualizaci na verzi 1.4.0.", 37 | "start": "Opravit databázi nyní" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta testovací program", 42 | "hint": "Zaškrtnutím políčka budete dostávat testovací verze linked předtím, než budou vydány oficiálně.", 43 | "enabled": "Použít beta verze" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "Nebyl nalezen žádný odpovídající příkaz", 48 | "type_slash": "Zadejte / pro bloky", 49 | "blocks": { 50 | "h1": { 51 | "title": "Nadpis 1", 52 | "description": "Nadpis první úrovně." 53 | }, 54 | "h2": { 55 | "title": "Nadpis 2", 56 | "description": "Nadpis druhé úrovně." 57 | }, 58 | "h3": { 59 | "title": "Nadpis 3", 60 | "description": "Nadpis třetí úrovně." 61 | }, 62 | "bold": { 63 | "title": "Tučně", 64 | "description": "Psaní textu tučně." 65 | }, 66 | "italic": { 67 | "title": "Kurzíva", 68 | "description": "Psaní textu kurzívou." 69 | }, 70 | "task": { 71 | "title": "Úkol", 72 | "description": "Přidá zaškrtávací políčko pro úkol." 73 | }, 74 | "unorderedList": { 75 | "title": "Seznam s odrážkami", 76 | "description": "Nečíslovaný seznam s odrážkami." 77 | }, 78 | "codeBlock": { 79 | "title": "Kód", 80 | "description": "Přidá blok pro zápis zdrojového kódu." 81 | }, 82 | "divider": { 83 | "title": "Horizontální rozdělovač", 84 | "description": "Přidá horizontální rozdělovač." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/da-DK.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Dansk", 3 | "code": "da-DK", 4 | "home": { 5 | "calendarWeek": "Uge" 6 | }, 7 | "settings": { 8 | "back": "Tilbage", 9 | "title": "Indstillinger", 10 | "designMode": { 11 | "title": "Design tilstand", 12 | "hint": "Du kan vælge mellem lys og mørk tilstand" 13 | }, 14 | "languages": { 15 | "title": "Sprog", 16 | "hint": "På hvilket sprog foretrækker du at bruge linked?" 17 | }, 18 | "data": { 19 | "title": "Datasti", 20 | "hint": "Hvor skal dine data opbevares? Opbevares i øjeblikket: ", 21 | "choose": "Vælg ny placering" 22 | }, 23 | "updates": { 24 | "title": "Opdaterings Hyppighed", 25 | "hint": "Hvor ofte skal der tjekkes for opdateringer?", 26 | "daily": "Dagligt", 27 | "weekly": "Ugentligt" 28 | }, 29 | "search": { 30 | "placeholder": "Søg efter dine noter ...", 31 | "no_result": "Der var ingen resultater for
{searchTerm}.", 32 | "start_searching": "Søg efter ord, sætninger eller gør brug af advanceret jokertegn som Jeg elsker * ...", 33 | "result_amount": "Resultater", 34 | "index": { 35 | "title": "Database Indeks", 36 | "hint": "Ved at starte indeksering vil linked scanne dine dage og tilføje dem til søgeindekset. Dette er kun nødvendigt én gang efter opdatering til v1.4.0.", 37 | "start": "Reparer database nu" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "Ved at markere afkrydsningsfeltet vil du modtage test byg af linked før deres udgivelse.", 43 | "enabled": "Brug beta versioner" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "Ingen matchende kommando fundet", 48 | "type_slash": "Tast / for blokke", 49 | "blocks": { 50 | "h1": { 51 | "title": "Overskrift 1", 52 | "description": "Niveau et overskrift." 53 | }, 54 | "h2": { 55 | "title": "Overskrift 2", 56 | "description": "Niveau to overskrift." 57 | }, 58 | "h3": { 59 | "title": "Overskrift 3", 60 | "description": "Niveau tre overskrift." 61 | }, 62 | "bold": { 63 | "title": "Fremhævet", 64 | "description": "Skriv din tekst i fremhævet tilstand." 65 | }, 66 | "italic": { 67 | "title": "Kursiv", 68 | "description": "Skriv din tekst i kursiv tilstand." 69 | }, 70 | "task": { 71 | "title": "Opgave", 72 | "description": "Tilføjer et afkrydsningsfelt til en opgave." 73 | }, 74 | "unorderedList": { 75 | "title": "Punktliste", 76 | "description": "En punktliste." 77 | }, 78 | "codeBlock": { 79 | "title": "Kode", 80 | "description": "Tilføjer en kodeblok." 81 | }, 82 | "divider": { 83 | "title": "Vandret Skillevæg", 84 | "description": "Tilføjer en vandret skillevæg." 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/locales/de-DE.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Deutsch", 3 | "code": "de-DE", 4 | "home": { 5 | "calendarWeek": "Woche" 6 | }, 7 | "settings": { 8 | "back": "Zurück", 9 | "title": "Einstellungen", 10 | "designMode": { 11 | "title": "Design Modus", 12 | "hint": "Wähle zwischen einem hellen oder dunklen Design." 13 | }, 14 | "languages": { 15 | "title": "Sprache", 16 | "hint": "In welcher Sprache möchtest du linked nutzen?" 17 | }, 18 | "data": { 19 | "title": "Datenpfad", 20 | "hint": "Wo sollen deine Daten gespeichert werden? Aktueller Speicherort: ", 21 | "choose": "Neuen Ort auswählen" 22 | }, 23 | "updates": { 24 | "title": "Update Intervall", 25 | "hint": "Wie oft soll nach neuen Versionen gesucht werden?", 26 | "daily": "Täglich", 27 | "weekly": "Wöchentlich" 28 | }, 29 | "search": { 30 | "placeholder": "Suche in deinen Notizen...", 31 | "no_result": "Es gab kein Ergebnis für
{searchTerm}.", 32 | "start_searching": "Such nach einzelnen Wörtern oder Sätzen, du kannst dabei auch Wildcards nutzen wie z.B. Ich liebe * ...", 33 | "result_amount": "Ergebnisse", 34 | "index": { 35 | "title": "Datenbank Index", 36 | "hint": "Durch das starten der Indizierung werden deine Tage gescannt und der Suchdatenbank hinzugefügt. Dies ist nur notwendig für Bestandsdaten vor der Version 1.4.0.", 37 | "start": "Datenbank jetzt reparieren" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Programm", 42 | "hint": "Wenn die Checkbox ausgewählt ist, erhälst du Test Versionen von linked bevor diese veröffentlicht werden.", 43 | "enabled": "Beta Versionen nutzen" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "Kein Ergebnis.", 48 | "type_slash": "Tippe / für Aktionen", 49 | "blocks": { 50 | "h1": { 51 | "title": "Überschrift 1", 52 | "description": "Eine Überschrift mit Level 1." 53 | }, 54 | "h2": { 55 | "title": "Überschrift 2", 56 | "description": "Eine Überschrift mit Level 2." 57 | }, 58 | "h3": { 59 | "title": "Überschrift 3", 60 | "description": "Eine Überschrift mit Level 3." 61 | }, 62 | "bold": { 63 | "title": "Fett", 64 | "description": "Schreibt deinen Text in fett." 65 | }, 66 | "italic": { 67 | "title": "Kursiv", 68 | "description": "Schreibt deinen Text in kursiv." 69 | }, 70 | "task": { 71 | "title": "Aufgabe", 72 | "description": "Eine Checkbox zum abhaken." 73 | }, 74 | "unorderedList": { 75 | "title": "Liste", 76 | "description": "Eine unsortierte Liste." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Ein Codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontale Linie", 84 | "description": "Eine horizontale Linie." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/el-GR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ελληνικά", 3 | "code": "el-GR", 4 | "home": { 5 | "calendarWeek": "Εβδομάδα" 6 | }, 7 | "settings": { 8 | "back": "Επιστροφή", 9 | "title": "Ρυθμίσεις", 10 | "designMode": { 11 | "title": "Εμφάνιση", 12 | "hint": "Μπορείτε να διαλέξετε μεταξύ ανοιχτόχρωμης ή σκούρας εμφάνισης." 13 | }, 14 | "languages": { 15 | "title": "Γλώσσα", 16 | "hint": "Σε ποιά γλώσσα επιθυμείτε να χρησιμοποιείτε το linked;" 17 | }, 18 | "data": { 19 | "title": "Τοποθεσία Δεδομένων", 20 | "hint": "Πού επιθυμείτε να αποθηκεύσετε τα δεδομένα σας; Ενεργή τοποθεσία: ", 21 | "choose": "Επιλέξτε καινούργια τοποθεσία" 22 | }, 23 | "updates": { 24 | "title": "Συχνότητα Ενημερώσεων", 25 | "hint": "Πόσο συχνά επιθυμείτε τον έλεγχο διαθέσιμων ενημερώσεων;", 26 | "daily": "Ημερησίως", 27 | "weekly": "Εβδομαδιαίως" 28 | }, 29 | "search": { 30 | "placeholder": "Εύρεση Σημειώσεων...", 31 | "no_result": "Κανένα αποτέλεσμα για
{searchTerm}.", 32 | "start_searching": "Χρησιμοποιείστε λέξεις, προτάσεις ή ακόμη και μεταχαρακτήρες όπως Μ'αρέσει το *...", 33 | "result_amount": "Αποτελέσματα", 34 | "index": { 35 | "title": "Κατάταξη Βάσης Δεδομένων", 36 | "hint": "Ξεκινώντας την διαδικασία κατάταξης δεδομένων, το linked θα σαρώσει τις ημέρες και θα τις προσθέσει στη βάση εύρεσης δεδομένων. Αυτή η ενέργεια είναι απαραίτητη μόνο κατόπιν αναβάθμισης της εφαρμογής στην έκδοση v1.4.0. Μάθετε περισσότερα στη σελίδα μας.", 37 | "start": "Αποκατάσταση Βάσης Δεδομένων" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "Δεν βρέθηκε αντίστοιχη εντολή", 48 | "type_slash": "Τύπος / για μπλοκ", 49 | "blocks": { 50 | "h1": { 51 | "title": "Επικεφαλής 1", 52 | "description": "Επικεφαλίδα επιπέδου ένα." 53 | }, 54 | "h2": { 55 | "title": "Επικεφαλής 2", 56 | "description": "Τίτλος επιπέδου δύο." 57 | }, 58 | "h3": { 59 | "title": "Επικεφαλής 3", 60 | "description": "Τίτλος επιπέδου τρία." 61 | }, 62 | "bold": { 63 | "title": "Τολμηρό", 64 | "description": "Γράφοντας το κείμενό σας με έντονη γραφή." 65 | }, 66 | "italic": { 67 | "title": "Πλάγια", 68 | "description": "Γράφοντας το κείμενό σας πλάγια." 69 | }, 70 | "task": { 71 | "title": "Εργασία", 72 | "description": "Προσθέτει ένα πλαίσιο ελέγχου εργασία." 73 | }, 74 | "unorderedList": { 75 | "title": "Λίστα επιλογών", 76 | "description": "Μια μη ταξινομημένη λίστα με κουκκίδες." 77 | }, 78 | "codeBlock": { 79 | "title": "Κωδικός", 80 | "description": "Προσθέτει ένα codeblock." 81 | }, 82 | "divider": { 83 | "title": "Οριζόντιο διαχωριστικό", 84 | "description": "Προσθέτει ένα οριζόντιο διαχωριστικό." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "English (US)", 3 | "code": "en-US", 4 | "home": { 5 | "calendarWeek": "Week" 6 | }, 7 | "settings": { 8 | "back": "Back", 9 | "title": "Settings", 10 | "designMode": { 11 | "title": "Design mode", 12 | "hint": "You can choose between a light and dark mode." 13 | }, 14 | "languages": { 15 | "title": "Language", 16 | "hint": "In which language do you prefer to use linked?" 17 | }, 18 | "data": { 19 | "title": "Datapath", 20 | "hint": "Where should your data be stored? Currently stored at: ", 21 | "choose": "Choose new location" 22 | }, 23 | "updates": { 24 | "title": "Update Frequency", 25 | "hint": "How often to check for updates?", 26 | "daily": "Daily", 27 | "weekly": "Weekly" 28 | }, 29 | "search": { 30 | "placeholder": "Search for your notes ...", 31 | "no_result": "There was no result for
{searchTerm}.", 32 | "start_searching": "Search for words, sentences or even use advanced wildcards like I love * ...", 33 | "result_amount": "Results", 34 | "index": { 35 | "title": "Database Index", 36 | "hint": "By starting the indexing, linked will scan your days and add them to the search index. This is only necessary once after updating to v1.4.0.", 37 | "start": "Repair database now" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/locales/es-ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Español", 3 | "code": "es-ES", 4 | "home": { 5 | "calendarWeek": "Semana" 6 | }, 7 | "settings": { 8 | "back": "Volver", 9 | "title": "Ajustes", 10 | "designMode": { 11 | "title": "Modo de diseño", 12 | "hint": "Elige entre un tema claro u oscuro." 13 | }, 14 | "languages": { 15 | "title": "Idioma", 16 | "hint": "¿En qué idioma le gustaría usar Linked?" 17 | }, 18 | "data": { 19 | "title": "Ruta de dades", 20 | "hint": "¿Dónde deben almacenarse sus datos? Ubicación actual: ", 21 | "choose": "Seleccionar nueva ubicación" 22 | }, 23 | "updates": { 24 | "title": "intervalo de actualización", 25 | "hint": "¿Con qué frecuencia buscar nuevas versiones?", 26 | "daily": "A diario", 27 | "weekly": "Semanalmente" 28 | }, 29 | "search": { 30 | "placeholder": "Busca en tus notas...", 31 | "no_result": "No hubo resultados para
{searchTerm}.", 32 | "start_searching": "Busque palabras o frases individuales, también puede usar comodines como Me encanta *...", 33 | "result_amount": "resultados", 34 | "index": { 35 | "title": "índice de la base de datos", 36 | "hint": "Al iniciar la indexación, sus días serán escaneados y agregados a la base de datos de búsqueda. Esto solo es necesario para los datos de inventario anteriores a la versión 1.4.0. Puede encontrar más información en el sitio web.", 37 | "start": "Reparar base de datos ahora" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Programa de pruebas beta", 42 | "hint": "Al activar la casilla, recibirá compilaciones de prueba de los enlaces antes de su publicación.", 43 | "enabled": "Utilizar versiones beta" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No se encontró ningún comando coincidente", 48 | "type_slash": "Tipo / para bloques", 49 | "blocks": { 50 | "h1": { 51 | "title": "Título 1", 52 | "description": "Un encabezado de nivel uno." 53 | }, 54 | "h2": { 55 | "title": "Título 2", 56 | "description": "Un encabezado de nivel dos." 57 | }, 58 | "h3": { 59 | "title": "Título 3", 60 | "description": "Un encabezado de nivel tres." 61 | }, 62 | "bold": { 63 | "title": "Negrita", 64 | "description": "Escribir su texto en negrita." 65 | }, 66 | "italic": { 67 | "title": "Cursiva", 68 | "description": "Escribir su texto en cursiva." 69 | }, 70 | "task": { 71 | "title": "Que hacer", 72 | "description": "Agrega una casilla de verificación de tareas pendientes." 73 | }, 74 | "unorderedList": { 75 | "title": "Lista", 76 | "description": "Una lista desordenada." 77 | }, 78 | "codeBlock": { 79 | "title": "Código", 80 | "description": "Agrega un bloque de código." 81 | }, 82 | "divider": { 83 | "title": "Divisor horizontal", 84 | "description": "Añade un divisor horizontal." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/fa-IR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "فارسی (ایران)", 3 | "code": "fa-IR", 4 | "home": { 5 | "calendarWeek": "هفته" 6 | }, 7 | "settings": { 8 | "back": "بازگشت", 9 | "title": "تنظیمات", 10 | "designMode": { 11 | "title": "حالت نمایش", 12 | "hint": "شما می‌توانید از میان تاریک و روشن انتخاب کنید." 13 | }, 14 | "languages": { 15 | "title": "زبان", 16 | "hint": "می‌خواهید لینکد را با چه زبانی استفاده کنید؟" 17 | }, 18 | "data": { 19 | "title": "مسیر دیتا", 20 | "hint": "دیتای برنامه کجا ذخیره شود؟ در حال حاظر اینجاست: ", 21 | "choose": "مسیر خود را انتخاب کنید" 22 | }, 23 | "updates": { 24 | "title": "بازه‌ی بروزرسانی", 25 | "hint": "بروزرسانی هرچند وقت انجام شود؟", 26 | "daily": "روزانه", 27 | "weekly": "هفتگی" 28 | }, 29 | "search": { 30 | "placeholder": "جستجو برای نوشته‌ها ...", 31 | "no_result": "هیچ نتیجه‌ای برای
{searchTerm} پیدا نشد.", 32 | "start_searching": "جستجو برای کلمات، جمله‌ها و یا حتی عبارات شرطی مانند I love * ...", 33 | "result_amount": "نتایج", 34 | "index": { 35 | "title": "ایندکس کردن دیتابیس", 36 | "hint": "با شروع ایندکس کردن، لینکد اطلاعات روزها برای جستجوی سریع‌تر را ایندکس می‌کند. این کار فقط یک بار پس از آپدیت به نسخه‌ی 1.4.0 الزامی است.", 37 | "start": "بازسازی پایگاه داده" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "تست نسخه‌ی بتا", 42 | "hint": "با فعال کردن این گزینه، شما نسخه‌های بتا را پیش از انتشار دریافت خواهید کرد.", 43 | "enabled": "استفاده از نسخه‌های بتا" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/fr-FR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Français", 3 | "code": "fr-FR", 4 | "home": { 5 | "calendarWeek": "Semaine" 6 | }, 7 | "settings": { 8 | "back": "Retour", 9 | "title": "Paramètres", 10 | "designMode": { 11 | "title": "Thème", 12 | "hint": "Choisissez un thème clair ou sombre." 13 | }, 14 | "languages": { 15 | "title": "Langue", 16 | "hint": "Dans quelle langue souhaitez-vous utiliser linked ?" 17 | }, 18 | "data": { 19 | "title": "Chemin de stockage", 20 | "hint": "Où vos données doivent-elles être stockées ? Localisation actuelle : ", 21 | "choose": "Sélectionnez un nouvel emplacement" 22 | }, 23 | "updates": { 24 | "title": "Intervalle de mise à jour", 25 | "hint": "À quelle fréquence vérifier les nouvelles versions ?", 26 | "daily": "Tous les jours", 27 | "weekly": "Toutes les semaines" 28 | }, 29 | "search": { 30 | "placeholder": "Cherchez dans vos notes...", 31 | "no_result": "Aucun résultat pour
{searchTerm}.", 32 | "start_searching": "Recherchez des mots, des phrases, ou utilisez des caractères génériques tels que J'aime * ...", 33 | "result_amount": "résultats", 34 | "index": { 35 | "title": "Indice de base de données", 36 | "hint": "En commençant l'indexation, vos journées seront scannées et ajoutées à la base de données de recherche. Cela n'est nécessaire que pour les données d'inventaire antérieures à la version 1.4.0. Vous pouvez trouver plus d'informations sur le site Web.", 37 | "start": "Réparer la base de données maintenant" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Programme de test bêta", 42 | "hint": "En cochant cette case, vous recevrez des versions de test des liens avant leur publication.", 43 | "enabled": "Utiliser les versions bêta" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "Aucune commande correspondante trouvée", 48 | "type_slash": "Type / pour blocs", 49 | "blocks": { 50 | "h1": { 51 | "title": "Titre 1", 52 | "description": "Une rubrique de niveau 1." 53 | }, 54 | "h2": { 55 | "title": "Titre 2", 56 | "description": "Une rubrique de niveau 2." 57 | }, 58 | "h3": { 59 | "title": "Titre 3", 60 | "description": "Une rubrique de niveau 3." 61 | }, 62 | "bold": { 63 | "title": "Gras", 64 | "description": "Écrire votre texte en gras." 65 | }, 66 | "italic": { 67 | "title": "Italiques", 68 | "description": "Écrire votre texte en italique." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Ajoute une case à cocher pour les tâches à accomplir." 73 | }, 74 | "unorderedList": { 75 | "title": "Liste à puces", 76 | "description": "Une liste à puces non ordonnée." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Ajoute un bloc de code." 81 | }, 82 | "divider": { 83 | "title": "Diviseur horizontal", 84 | "description": "Ajoute un séparateur horizontal." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/hi-IN.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "हिन्दी", 3 | "code": "hi-IN", 4 | "home": { 5 | "calendarWeek": "सप्ताह" 6 | }, 7 | "settings": { 8 | "back": "वापस", 9 | "title": "सेटिंग्स", 10 | "designMode": { 11 | "title": "डिज़ाइन मोड", 12 | "hint": "आप लाइट और डार्क मोड के बीच चयन कर सकते हैं।" 13 | }, 14 | "languages": { 15 | "title": "भाषा", 16 | "hint": "आप किस भाषा में लिंक्ड का उपयोग करना पसंद करते हैं?" 17 | }, 18 | "data": { 19 | "title": "डेटा पथ", 20 | "hint": "आपका डेटा कहाँ संग्रहीत किया जाना चाहिए? वर्तमान में यहां संग्रहीत: ", 21 | "choose": "नया स्थान चुनें" 22 | }, 23 | "updates": { 24 | "title": "अपडेट आवृत्ति", 25 | "hint": "अपडेट के लिए कितनी बार जांचना है?", 26 | "daily": "रोज", 27 | "weekly": "साप्ताहिक" 28 | }, 29 | "search": { 30 | "placeholder": "अपने नोट्स खोजें ...", 31 | "no_result": "
{searchTerm} के लिए कोई परिणाम नहीं था।", 32 | "start_searching": "शब्दों, वाक्यों की खोज करें या यहां तक ​​कि उन्नत वाइल्डकार्ड का उपयोग करें जैसे मुझे पसंद * ...", 33 | "result_amount": "परिणाम", 34 | "index": { 35 | "title": "डेटाबेस अनुक्रमणिका", 36 | "hint": "अनुक्रमण शुरू करके, लिंक्ड आपके दिनों को स्कैन करेगा और उन्हें खोज अनुक्रमणिका में जोड़ देगा। यह केवल एक बार v1.4.0 में अद्यतन करने के बाद आवश्यक है। हमारी वेबसाइट पर और जानें।", 37 | "start": "अब डेटाबेस की मरम्मत करें" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/hr-HR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Hrvatski", 3 | "code": "hr-HR", 4 | "home": { 5 | "calendarWeek": "Tjedan" 6 | }, 7 | "settings": { 8 | "back": "Natrag", 9 | "title": "Postavke", 10 | "designMode": { 11 | "title": "Tema", 12 | "hint": "Birajte između svijetle ili tamne teme." 13 | }, 14 | "languages": { 15 | "title": "Jezik", 16 | "hint": "Na kojem jeziku želite koristiti linked?" 17 | }, 18 | "data": { 19 | "title": "Put podataka", 20 | "hint": "Gdje bi trebali biti pohranjeni vaši podaci? Trenutna lokacija: ", 21 | "choose": "Odaberite novu lokaciju" 22 | }, 23 | "updates": { 24 | "title": "interval ažuriranja", 25 | "hint": "Koliko često provjeravati nove verzije?", 26 | "daily": "Dnevno", 27 | "weekly": "Tjedni" 28 | }, 29 | "search": { 30 | "placeholder": "Pretražite svoje bilješke...", 31 | "no_result": "Nije bilo rezultata za
{searchTerm}.", 32 | "start_searching": "Tražite pojedinačne riječi ili izraze, također možete koristiti zamjenske znakove kao što je Volim * ...", 33 | "result_amount": "rezultate", 34 | "index": { 35 | "title": "Indeks baze podataka", 36 | "hint": "Početkom indeksiranja, vaši će dani biti skenirani i dodati u bazu podataka pretraživanja. Ovo je potrebno samo za podatke inventara prije verzije 1.4.0. Posjetite web stranicu za više informacija.", 37 | "start": "Popravi bazu podataka sada" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Program beta testiranja", 42 | "hint": "Omogućavanjem potvrdnog okvira primit ćete testne verzije povezanih prije njihove objave.", 43 | "enabled": "Koristite beta verzije" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "Nije pronađena odgovarajuća naredba", 48 | "type_slash": "Tip / za blokove", 49 | "blocks": { 50 | "h1": { 51 | "title": "Naslov 1", 52 | "description": "Naslov prve razine." 53 | }, 54 | "h2": { 55 | "title": "Naslov 2", 56 | "description": "Naslov druge razine." 57 | }, 58 | "h3": { 59 | "title": "Naslov 3", 60 | "description": "Naslov treće razine." 61 | }, 62 | "bold": { 63 | "title": "Podebljani", 64 | "description": "Pisanje teksta podebljano." 65 | }, 66 | "italic": { 67 | "title": "Kurziv", 68 | "description": "Pisanje teksta kurzivom." 69 | }, 70 | "task": { 71 | "title": "Zadatak", 72 | "description": "Dodaje okvir za izbor obaveza." 73 | }, 74 | "unorderedList": { 75 | "title": "Popis nabrajanja", 76 | "description": "Neuređeni popis s nabrajanim oznakama." 77 | }, 78 | "codeBlock": { 79 | "title": "Kodirati", 80 | "description": "Dodaje blok koda." 81 | }, 82 | "divider": { 83 | "title": "Horizontalni razdjelnik", 84 | "description": "Dodaje vodoravni razdjelnik." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/id-ID.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Bahasa Indonesia", 3 | "code": "id-ID", 4 | "home": { 5 | "calendarWeek": "MINGGU" 6 | }, 7 | "settings": { 8 | "back": "Kembali", 9 | "title": "Pengaturan", 10 | "designMode": { 11 | "title": "Mode desain", 12 | "hint": "Pilih antara tema terang atau gelap." 13 | }, 14 | "languages": { 15 | "title": "Bahasa", 16 | "hint": "Dalam bahasa apa Anda ingin menggunakan linked?" 17 | }, 18 | "data": { 19 | "title": "Jalur data", 20 | "hint": "Di mana data Anda harus disimpan? Lokasi saat ini: ", 21 | "choose": "Pilih lokasi baru" 22 | }, 23 | "updates": { 24 | "title": "Interval pembaruan", 25 | "hint": "Seberapa sering memeriksa versi baru?", 26 | "daily": "Sehari-hari", 27 | "weekly": "Mingguan" 28 | }, 29 | "search": { 30 | "placeholder": "Cari catatan Anda...", 31 | "no_result": "Tidak ada hasil untuk
{searchTerm}.", 32 | "start_searching": "Cari kata atau frasa individual, Anda juga dapat menggunakan karakter pengganti seperti Saya suka * ...", 33 | "result_amount": "hasil", 34 | "index": { 35 | "title": "Indeks basis data", 36 | "hint": "Dengan memulai pengindeksan, hari-hari Anda akan dipindai dan ditambahkan ke database pencarian. Ini hanya diperlukan untuk data inventaris sebelum versi 1.4.0. Kunjungi situsnya untuk informasi lebih lanjut.", 37 | "start": "Perbaiki database sekarang" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/it-IT.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Italiano", 3 | "code": "it-IT", 4 | "home": { 5 | "calendarWeek": "Settimana" 6 | }, 7 | "settings": { 8 | "back": "Indietro", 9 | "title": "Impostazioni", 10 | "designMode": { 11 | "title": "Modalità design", 12 | "hint": "Puoi scegliere tra una modalità chiara e scura." 13 | }, 14 | "languages": { 15 | "title": "Lingua", 16 | "hint": "In quale lingua preferisci usare linked?" 17 | }, 18 | "data": { 19 | "title": "Percorso dati", 20 | "hint": "Dove dovrebbero essere memorizzati i tuoi dati? Attualmente memorizzati in: ", 21 | "choose": "Scegli una nuova posizione" 22 | }, 23 | "updates": { 24 | "title": "Frequenza di aggiornamento", 25 | "hint": "Con quale frequenza controllare gli aggiornamenti?", 26 | "daily": "Ogni giorno", 27 | "weekly": "Ogni settimana" 28 | }, 29 | "search": { 30 | "placeholder": "Cerca le tue note ...", 31 | "no_result": "Nessun risultato per
{searchTerm}.", 32 | "start_searching": "Cerca parole, frasi o usa anche caratteri jolly avanzati come Io amo * ...", 33 | "result_amount": "Risultati", 34 | "index": { 35 | "title": "Indice del Database", 36 | "hint": "Avviando l'indicizzazione, linked analizzerà i tuoi giorni e li aggiungerà all'indice di ricerca. Questo è necessario solo una volta dopo l'aggiornamento alla versione v1.4.0. Scopri di più sul nostro sito web.", 37 | "start": "Ripara il database ora" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/locales/ko-KR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "한국어", 3 | "code": "ko-KR", 4 | "home": { 5 | "calendarWeek": "주" 6 | }, 7 | "settings": { 8 | "back": "이전", 9 | "title": "설정", 10 | "designMode": { 11 | "title": "테마", 12 | "hint": "밝은 테마 또는 어두운 테마 중에서 선택합니다." 13 | }, 14 | "languages": { 15 | "title": "언어", 16 | "hint": "연결된 언어를 어떤 언어로 사용하시겠습니까?" 17 | }, 18 | "data": { 19 | "title": "데이터 경로", 20 | "hint": "데이터를 어디에 저장해야 합니까? 현재 위치: ", 21 | "choose": "새 위치 선택" 22 | }, 23 | "updates": { 24 | "title": "업데이트 간격", 25 | "hint": "얼마나 자주 새 버전을 확인합니까?", 26 | "daily": "일일", 27 | "weekly": "주간" 28 | }, 29 | "search": { 30 | "placeholder": "메모 검색...", 31 | "no_result": "
{searchTerm}에 대한 검색결과가 없습니다.", 32 | "start_searching": "개별 단어나 구를 검색하고 I love * ...와 같은 와일드카드를 사용할 수도 있습니다.", 33 | "result_amount": "결과", 34 | "index": { 35 | "title": "데이터베이스", 36 | "hint": "인덱싱을 시작하면 귀하의 날짜가 스캔되어 검색 데이터베이스에 추가됩니다. 이는 버전 1.4.0 이전의 인벤토리 데이터에만 필요합니다. 자세한 내용은 웹 사이트를 방문하십시오.", 37 | "start": "지금 데이터베이스 복구" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/nl-NL.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Nederlands", 3 | "code": "nl-NL", 4 | "home": { 5 | "calendarWeek": "Week" 6 | }, 7 | "settings": { 8 | "back": "Terug", 9 | "title": "Instellingen", 10 | "designMode": { 11 | "title": "Designmodus", 12 | "hint": "Kies tussen een licht of donker thema." 13 | }, 14 | "languages": { 15 | "title": "Taal", 16 | "hint": "In welke taal wil je linked gebruiken?" 17 | }, 18 | "data": { 19 | "title": "Gegevenspad", 20 | "hint": "Waar moeten uw gegevens worden opgeslagen? Huidige locatie: ", 21 | "choose": "Selecteer nieuwe locatie" 22 | }, 23 | "updates": { 24 | "title": "Bijwerkingsonderbreking", 25 | "hint": "Hoe vaak controleren op nieuwe versies?", 26 | "daily": "Dagelijks", 27 | "weekly": "Wekelijks" 28 | }, 29 | "search": { 30 | "placeholder": "Zoek uw notities...", 31 | "no_result": "Er was geen resultaat voor
{searchTerm}.", 32 | "start_searching": "Zoek naar afzonderlijke woorden of woordgroepen, u kunt ook jokertekens gebruiken zoals I love * ...", 33 | "result_amount": "resultaten", 34 | "index": { 35 | "title": "Database-index", 36 | "hint": "Door te beginnen met indexeren, worden uw dagen gescand en toegevoegd aan de zoekdatabase. Dit is alleen nodig voor inventarisgegevens ouder dan versie 1.4.0. Bezoek de website voor meer informatie.", 37 | "start": "Database nu repareren" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/np-NP.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "नेपाली", 3 | "code": "ne-NE", 4 | "home": { 5 | "calendarWeek": "हप्ता" 6 | }, 7 | "settings": { 8 | "back": "फिर्ता", 9 | "title": "सेटिंग्स", 10 | "designMode": { 11 | "title": "डिजाइन मोड", 12 | "hint": "तपाईं लाइट कि डार्क मोडबिच छनोट गर्न सक्नुहुन्छ।" 13 | }, 14 | "languages": { 15 | "title": "भाषा", 16 | "hint": "तपाईंलाई कुन भाषा प्रयोग गर्न चाहनु हुन्छ?" 17 | }, 18 | "data": { 19 | "title": "डेटा पाथ", 20 | "hint": "तपाईंको डेटा कहाँ संग्रह गर्न चाहनु हुन्छ? अहिले यहां संग्रहीत छ: ", 21 | "choose": "नयाँ स्थान छान्नुहोस्" 22 | }, 23 | "updates": { 24 | "title": "अपडेट आवृत्ति", 25 | "hint": "अपडेटको लागि कति पटक जाँच्न चाहनु हुन्छ?", 26 | "daily": "हरेक दिन", 27 | "weekly": "हरेक हप्ता" 28 | }, 29 | "search": { 30 | "placeholder": "आफ्नो नोट्स खोज्नुहोस् ...", 31 | "no_result": "
{searchTerm} को लागि केही परिणाम भेटिएन।", 32 | "start_searching": "शब्द, वाक्य खोज गर्नुहोस् या वाइल्डकार्ड प्रयोग गर्नुहोस् जस्तै मलाई मन पर्यो * ...", 33 | "result_amount": "परिणाम", 34 | "index": { 35 | "title": "डेटाबेस अनुक्रमणिका", 36 | "hint": "अनुक्रमण शुरू गरेर, लिंक्ड तपाईंको दिनहरु को स्क्यान गरेर त्यासलाई खोज अनुक्रमणिकामा जोडिदिन्छ। यो केवल v1.4.0 मा अपडेट गरेपछि एक पटक मात्र आवश्यक छ। थप जानकारीको लागि हाम्रो वेबसाइट हेर्नुहोला।", 37 | "start": "अब डेटाबेसको मर्मत गर्नुहोस्" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/pl-PL.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Polski", 3 | "code": "pl-PL", 4 | "home": { 5 | "calendarWeek": "Tydzień" 6 | }, 7 | "settings": { 8 | "back": "Powrót", 9 | "title": "Ustawienia", 10 | "designMode": { 11 | "title": "Tryb designera", 12 | "hint": "Możesz wybrać pomiędzy jasnym i ciemnym motywem" 13 | }, 14 | "languages": { 15 | "title": "Język", 16 | "hint": "W jakim języku preferujesz używania linked?" 17 | }, 18 | "data": { 19 | "title": "Ścieżka danych", 20 | "hint": "Gdzie powinny być przechowyane dane aplikacji? Teraz przychowywane są w: ", 21 | "choose": "Wybierz nową lokalizację" 22 | }, 23 | "updates": { 24 | "title": "Częstotliwość aktualizacji", 25 | "hint": "Jak często będą wyszukiwane nowe aktualizacje?", 26 | "daily": "Codziennie", 27 | "weekly": "Co tydzień" 28 | }, 29 | "search": { 30 | "placeholder": "Przeszukaj swoje notatki...", 31 | "no_result": "Nie znaleziono wyników dla
{searchTerm}.", 32 | "start_searching": "Szukaj słów, zdań albo nawet użyj zaawansowanych symboli wieloznacznych jak Kocham * ...", 33 | "result_amount": "Wyniki", 34 | "index": { 35 | "title": "Indeks bazy danych", 36 | "hint": "Po uruchomieniu indeksowania linked przeskanuje Twoje dni i doda je do indeksu wyszukiwania. Jest to konieczne tylko raz po aktualizacji do wersji 1.4.0. Dowiedz się więcej na naszej stronie internetowej.", 37 | "start": "Napraw bazę danych" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/pt-BR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Português Brasil", 3 | "code": "pt-BR", 4 | "home": { 5 | "calendarWeek": "Semana" 6 | }, 7 | "settings": { 8 | "back": "Voltar", 9 | "title": "Configurações", 10 | "designMode": { 11 | "title": "Modo Design", 12 | "hint": "Você pode escolher entre o modo claro e o modo escuro." 13 | }, 14 | "languages": { 15 | "title": "Idioma", 16 | "hint": "Em qual idioma você prefere usar o linked?" 17 | }, 18 | "data": { 19 | "title": "Local dos Dados", 20 | "hint": "Onde seus dados devem ser guardados? Atualmente são guardados em: ", 21 | "choose": "Escolha um novo local" 22 | }, 23 | "updates": { 24 | "title": "Frequência de Atualizações", 25 | "hint": "Com qual frequência checar por atualizações?", 26 | "daily": "Diária", 27 | "weekly": "Semanal" 28 | }, 29 | "search": { 30 | "placeholder": "Procurar por suas notas ...", 31 | "no_result": "Não houveram resultados para
{searchTerm}.", 32 | "start_searching": "Procure por palavras, sentenças ou mesmo use curingas avançados como Eu amo * ...", 33 | "result_amount": "Resulados", 34 | "index": { 35 | "title": "Índice do Banco de Dados", 36 | "hint": "Para começar a indexação, linked vai escanear seus dias e adicioná-los para o índice de pesquisa. Isso só é necessário uma vez depois de atualizar para v1.4.0. Descubra mais em nosso Website.", 37 | "start": "Reparar banco de dados agora" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/ru-RU.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Русский", 3 | "code": "ru-RU", 4 | "home": { 5 | "calendarWeek": "Неделя" 6 | }, 7 | "settings": { 8 | "back": "Назад", 9 | "title": "Настройки", 10 | "designMode": { 11 | "title": "Режим Дизайна", 12 | "hint": "Выберите между светлой или темной темой." 13 | }, 14 | "languages": { 15 | "title": "Язык", 16 | "hint": "На каком языке вы хотели бы использовать ссылку?" 17 | }, 18 | "data": { 19 | "title": "путь к данным", 20 | "hint": "Где должны храниться ваши данные? Текущее местоположение: ", 21 | "choose": "Выберите новое местоположение" 22 | }, 23 | "updates": { 24 | "title": "интервал обновления", 25 | "hint": "Как часто проверять наличие новых версий?", 26 | "daily": "Ежедневно", 27 | "weekly": "Еженедельно" 28 | }, 29 | "search": { 30 | "placeholder": "Поиск в заметках...", 31 | "no_result": "Не найдено результатов для
{searchTerm}.", 32 | "start_searching": "Ищите отдельные слова или фразы, вы также можете использовать подстановочные знаки, такие как I love * ...", 33 | "result_amount": "Результаты", 34 | "index": { 35 | "title": "индекс базы данных", 36 | "hint": "Запустив индексацию, ваши дни будут просканированы и добавлены в базу поиска. Это необходимо только для данных инвентаризации до версии 1.4.0. Дополнительную информацию вы можете найти на веб-сайте.", 37 | "start": "Восстановить базу данных сейчас" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/sl-SI.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Slovenščina", 3 | "code": "sl-SI", 4 | "home": { 5 | "calendarWeek": "Teden" 6 | }, 7 | "settings": { 8 | "back": "Nazaj", 9 | "title": "Nastavitve", 10 | "designMode": { 11 | "title": "Tema", 12 | "hint": "Izbirate lahko med svetlim in temnim načinom" 13 | }, 14 | "languages": { 15 | "title": "Jezik", 16 | "hint": "V katerem jeziku najraje uporabljate linked?" 17 | }, 18 | "data": { 19 | "title": "Pot do podatkov", 20 | "hint": "Kje naj bodo shranjeni vaši podatki? Trenutno shranjeno na:", 21 | "choose": "Izberite novo lokacijo" 22 | }, 23 | "updates": { 24 | "title": "Pogostost preverjanja posodobitev", 25 | "hint": "Kako pogosto preverjati posodobitve?", 26 | "daily": "Dnevno", 27 | "weekly": "Tedensko" 28 | }, 29 | "search": { 30 | "placeholder": "Poiščite svoje zapiske...", 31 | "no_result": "Ni bilo nobenega rezultata za
{searchTerm}", 32 | "start_searching": "Iščite besede, stavke ali celo uporabite napredne nadomestne znake, kot je Kupi * jabolka...", 33 | "result_amount": "Rezultatov", 34 | "index": { 35 | "title": "Indeks baze podatkov", 36 | "hint": "Z začetkom indeksiranja bo linked skeniral vaše dneve in jih dodal v iskalni indeks. To je potrebno le enkrat po posodobitvi na v1.4.0. Več o tem na naši spletni strani", 37 | "start": "Popravi bazo podatkov" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/locales/tr-TR.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Türkçe", 3 | "code": "tr-TR", 4 | "home": { 5 | "calendarWeek": "Hafta" 6 | }, 7 | "settings": { 8 | "back": "Geri", 9 | "title": "Ayarlar", 10 | "designMode": { 11 | "title": "Tasarım modu", 12 | "hint": "Açık veya koyu bir tema arasında seçim yapın." 13 | }, 14 | "languages": { 15 | "title": "Dil", 16 | "hint": "Bağlantıyı hangi dilde kullanmak istersiniz?" 17 | }, 18 | "data": { 19 | "title": "Veri yolu", 20 | "hint": "Verileriniz nerede saklanmalı? Mevcut konum: ", 21 | "choose": "Yeni konum seçin" 22 | }, 23 | "updates": { 24 | "title": "Güncelleme aralığı", 25 | "hint": "Yeni sürümler ne sıklıkla kontrol edilir?", 26 | "daily": "Günlük", 27 | "weekly": "Haftalık" 28 | }, 29 | "search": { 30 | "placeholder": "Notlarınızı arayın...", 31 | "no_result": "
{searchTerm} için sonuç bulunamadı.", 32 | "start_searching": "Tek tek kelimeleri veya kelime öbeklerini arayın, ayrıca I love * ... gibi joker karakterler de kullanabilirsiniz", 33 | "result_amount": "Sonuçlar", 34 | "index": { 35 | "title": "Veritabanı dizini", 36 | "hint": "İndekslemeye başladığınızda günleriniz taranacak ve arama veritabanına eklenecektir. Bu yalnızca 1.4.0 sürümünden önceki envanter verileri için gereklidir. Daha fazla bilgi için web sitesini ziyaret edin.", 37 | "start": "Veritabanını şimdi onar" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/uk-UA.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Український", 3 | "code": "uk-UA", 4 | "home": { 5 | "calendarWeek": "Тиждень" 6 | }, 7 | "settings": { 8 | "back": "Назад", 9 | "title": "Налаштування", 10 | "designMode": { 11 | "title": "Тема", 12 | "hint": "Ви можете вибрати між світлим та темним режимом" 13 | }, 14 | "languages": { 15 | "title": "Мова", 16 | "hint": "Якій мові ви віддаєте перевагу під час використання linked?" 17 | }, 18 | "data": { 19 | "title": "Шлях до даних", 20 | "hint": "Де повинні зберігатися ваші дані? На даний момент зберігається:", 21 | "choose": "Виберіть нове місце розташування" 22 | }, 23 | "updates": { 24 | "title": "Частота оновлення", 25 | "hint": "Як часто перевіряти наявність оновлень?", 26 | "daily": "Щоденно", 27 | "weekly": "Щотижня" 28 | }, 29 | "search": { 30 | "placeholder": "Пошукайте свої записи...", 31 | "no_result": "Не було результату для
{searchTerm}", 32 | "start_searching": "Шукайте слова, речення або навіть використовуйте розширені символи підстановки, як Купити зелені * ...", 33 | "result_amount": "Результати", 34 | "index": { 35 | "title": "Індекс бази даних", 36 | "hint": "Починаючи індексацію, linked сканує ваші дні та додасть їх до індексу пошуку. Це необхідно лише один раз після оновлення до v1.4.0. Дізнайтеся більше на нашому веб-сайті.", 37 | "start": "Ремонт бази даних" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/locales/zh-CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "中文 (简体)", 3 | "code": "zh-CN", 4 | "home": { 5 | "calendarWeek": "星期" 6 | }, 7 | "settings": { 8 | "back": "返回", 9 | "title": "设置", 10 | "designMode": { 11 | "title": "主题色", 12 | "hint": "你可以在亮色和暗色之间选择。" 13 | }, 14 | "languages": { 15 | "title": "语言", 16 | "hint": "你更喜欢以哪种语言使用 linked?" 17 | }, 18 | "data": { 19 | "title": "数据目录", 20 | "hint": "你的数据存放在哪里?当前存放在:", 21 | "choose": "选择一个位置" 22 | }, 23 | "updates": { 24 | "title": "更新频率", 25 | "hint": "多久检查一次更新?", 26 | "daily": "每天", 27 | "weekly": "每周" 28 | }, 29 | "search": { 30 | "placeholder": "查找你的备忘事项……", 31 | "no_result": "没有找到结果:
{searchTerm}.", 32 | "start_searching": "查找单词、句子,或者使用高级通配符,像这样 我爱* ……", 33 | "result_amount": "查找结果", 34 | "index": { 35 | "title": "数据库索引", 36 | "hint": "通过建立索引,linked 将会扫描你的每一天,然后添加到搜索索引。只有更新到 v1.4.0 后这才是必须的。在我们的网站可以查看更多信息。", 37 | "start": "立即修复索引数据库" 38 | } 39 | }, 40 | "allowPrerelease": { 41 | "title": "Beta Test Program", 42 | "hint": "By enabling the checkbox, you will receive test builds of linked before their release.", 43 | "enabled": "Use beta versions" 44 | } 45 | }, 46 | "commands": { 47 | "no_result": "No matching command found", 48 | "type_slash": "Type / for blocks", 49 | "blocks": { 50 | "h1": { 51 | "title": "Heading 1", 52 | "description": "A level one heading." 53 | }, 54 | "h2": { 55 | "title": "Heading 2", 56 | "description": "A level two heading." 57 | }, 58 | "h3": { 59 | "title": "Heading 3", 60 | "description": "A level three heading." 61 | }, 62 | "bold": { 63 | "title": "Bold", 64 | "description": "Writing your text bold." 65 | }, 66 | "italic": { 67 | "title": "Italic", 68 | "description": "Writing your text italic." 69 | }, 70 | "task": { 71 | "title": "Todo", 72 | "description": "Adds a todo checkbox." 73 | }, 74 | "unorderedList": { 75 | "title": "Bullet list", 76 | "description": "A unordered bullet list." 77 | }, 78 | "codeBlock": { 79 | "title": "Code", 80 | "description": "Adds a codeblock." 81 | }, 82 | "divider": { 83 | "title": "Horizontal Divider", 84 | "description": "Adds a horizontal divider." 85 | } 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from '@/store' 3 | import {Translations} from '@/translation' 4 | 5 | 6 | import App from './App.vue' 7 | import router from './router' 8 | import '@/assets/css/tailwind.css' 9 | import i18n from './i18n' 10 | 11 | const Storage = require('electron-store') 12 | window.mainStorage = new Storage({ 13 | watch: true, 14 | defaults: {} 15 | }) 16 | 17 | Vue.config.productionTip = false 18 | Vue.use(Translations) 19 | 20 | new Vue({ 21 | router, 22 | store, 23 | i18n, 24 | render: h => h(App) 25 | }).$mount('#app') 26 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Home from '@/views/Home.vue' 4 | import Settings from '@/views/Settings.vue' 5 | import Search from '@/views/Search.vue' 6 | 7 | Vue.use(VueRouter) 8 | const routes = [ 9 | { 10 | path: '/', 11 | name: 'Home', 12 | component: Home 13 | }, 14 | { 15 | path: '/settings', 16 | name: 'Settings', 17 | component: Settings 18 | }, 19 | { 20 | path: '/search', 21 | name: 'Search', 22 | component: Search 23 | } 24 | ] 25 | 26 | const router = new VueRouter({ 27 | mode: 'hash', 28 | base: process.env.BASE_URL, 29 | routes 30 | }) 31 | 32 | export default router 33 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | import calendar from '@/store/modules/calendar' 5 | import file from '@/store/modules/file' 6 | import app from '@/store/modules/app' 7 | 8 | Vue.use(Vuex) 9 | 10 | export default new Vuex.Store({ 11 | modules: { 12 | calendar, 13 | file, 14 | app 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /src/store/modules/app/actions.js: -------------------------------------------------------------------------------- 1 | import { Actions, Mutations } from '@/store/modules/app/types' 2 | import { Actions as CalendarActions } from '@/store/modules/calendar/types' 3 | import { 4 | getLanguage, 5 | getTheme, 6 | getUpdateInterval, 7 | setLanguage, 8 | setTheme, 9 | loadSearchIndex, 10 | setUpdateInterval, 11 | getDataPath, 12 | setDataPath, 13 | setAllowPrerelease, 14 | getAllowPrerelease 15 | } from '@/store/modules/app/helper' 16 | 17 | export default { 18 | async [Actions.INIT_APP](context) { 19 | const theme = await getTheme() 20 | context.commit(Mutations.SET_THEME, theme) 21 | 22 | const language = await getLanguage() 23 | context.commit(Mutations.SET_LANGUAGE, language) 24 | 25 | 26 | await context.dispatch('calendar/' + CalendarActions.SET_CURRENT_WEEK, '', { 27 | root: true 28 | }) 29 | 30 | await loadSearchIndex() 31 | 32 | const dataPath = await getDataPath() 33 | context.commit(Mutations.SET_DATA_PATH, dataPath) 34 | 35 | const allowPrerelease = await getAllowPrerelease() 36 | context.commit(Mutations.SET_ALLOW_PRERELEASE, allowPrerelease) 37 | }, 38 | 39 | async [Actions.SYNC_UPDATE_INTERVAL](context) { 40 | const updateInterval = await getUpdateInterval() 41 | context.commit(Mutations.SET_UPDATE_INTERVAL, updateInterval) 42 | }, 43 | 44 | async [Actions.SET_LANGUAGE](context, language) { 45 | setLanguage(language).then(() => { 46 | context.commit(Mutations.SET_LANGUAGE, language) 47 | }) 48 | }, 49 | 50 | async [Actions.SET_THEME](context, theme) { 51 | setTheme(theme).then(() => { 52 | context.commit(Mutations.SET_THEME, theme) 53 | }) 54 | }, 55 | 56 | async [Actions.SET_UPDATE_INTERVAL](context, interval) { 57 | setUpdateInterval(interval).then(() => { 58 | context.commit(Mutations.SET_UPDATE_INTERVAL, interval) 59 | }) 60 | }, 61 | 62 | async [Actions.SET_DATA_PATH](context) { 63 | setDataPath().then((path) => { 64 | context.commit(Mutations.SET_DATA_PATH, path) 65 | }) 66 | }, 67 | 68 | async [Actions.SET_ALLOW_PRERELEASE](context, allowPrerelease) { 69 | setAllowPrerelease(allowPrerelease).then(() => { 70 | context.commit(Mutations.SET_ALLOW_PRERELEASE, allowPrerelease) 71 | }) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/store/modules/app/getters.js: -------------------------------------------------------------------------------- 1 | import { Getters } from './types' 2 | 3 | export default { 4 | [Getters.GET_LANGUAGE](state) { 5 | return state.language 6 | }, 7 | 8 | [Getters.GET_THEME](state) { 9 | return state.theme 10 | }, 11 | 12 | [Getters.GET_UPDATE_INTERVAL](state) { 13 | return state.updateInterval 14 | }, 15 | 16 | [Getters.GET_DATA_PATH](state) { 17 | return state.dataPath 18 | }, 19 | 20 | [Getters.GET_ALLOW_PRERELEASE](state) { 21 | return state.allowPrerelease 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/store/modules/app/helper.js: -------------------------------------------------------------------------------- 1 | const { ipcRenderer } = require('electron') 2 | const DAILY = 1000 * 60 * 60 * 24 3 | const WEEKLY = DAILY * 7 4 | 5 | /* 6 | * Electron Storage Getters 7 | */ 8 | export const getLanguage = async () => { 9 | return ipcRenderer.invoke('GET_STORAGE_VALUE', 'language') 10 | } 11 | 12 | export const getTheme = async () => { 13 | return ipcRenderer.invoke('GET_STORAGE_VALUE', 'theme') 14 | } 15 | 16 | export const getUpdateInterval = async () => { 17 | const updateInterval = await ipcRenderer.invoke('GET_STORAGE_VALUE', 'updateInterval') 18 | return updateInterval === DAILY ? 0 : 1 19 | } 20 | 21 | export const getDataPath = () => { 22 | return ipcRenderer.invoke('GET_STORAGE_VALUE', 'dataPath') 23 | } 24 | 25 | export const getAllowPrerelease = async () => { 26 | return ipcRenderer.invoke('GET_STORAGE_VALUE', 'allowPrerelease') 27 | } 28 | 29 | /* 30 | * Electron Storage Setters 31 | */ 32 | export const setTheme = async (theme) => { 33 | return ipcRenderer.invoke('SET_STORAGE_VALUE', 'theme', theme).then(() => { 34 | ipcRenderer.invoke('TOGGLE_THEME', theme) 35 | }) 36 | } 37 | 38 | export const setLanguage = async (language) => { 39 | localStorage.lang = language 40 | return ipcRenderer.invoke('SET_STORAGE_VALUE', 'language', language) 41 | } 42 | 43 | export const loadSearchIndex = async () => { 44 | await ipcRenderer.invoke('LOAD_SEARCH_INDEX') 45 | } 46 | 47 | export const reIndexAll = async () => { 48 | return await ipcRenderer.invoke('REINDEX_ALL') 49 | } 50 | 51 | export const setUpdateInterval = async (updateInterval) => { 52 | return ipcRenderer.invoke('SET_STORAGE_VALUE', 'updateInterval', updateInterval === 0 ? DAILY : WEEKLY) 53 | } 54 | 55 | export const setDataPath = () => { 56 | return ipcRenderer.invoke('SET_DATA_PATH') 57 | } 58 | 59 | export const setAllowPrerelease = async (value) => { 60 | return ipcRenderer.invoke('SET_STORAGE_VALUE', 'allowPrerelease', value) 61 | } -------------------------------------------------------------------------------- /src/store/modules/app/index.js: -------------------------------------------------------------------------------- 1 | import actions from './actions' 2 | import getters from './getters' 3 | import mutations from './mutations' 4 | import state from './state' 5 | 6 | export default { 7 | namespaced: true, 8 | state, 9 | actions, 10 | mutations, 11 | getters 12 | } 13 | -------------------------------------------------------------------------------- /src/store/modules/app/mutations.js: -------------------------------------------------------------------------------- 1 | import { Mutations } from './types' 2 | 3 | export default { 4 | [Mutations.SET_LANGUAGE](state, language) { 5 | state.language = language 6 | }, 7 | 8 | [Mutations.SET_THEME](state, theme) { 9 | state.theme = theme 10 | }, 11 | 12 | [Mutations.SET_UPDATE_INTERVAL](state, interval) { 13 | state.updateInterval = interval 14 | }, 15 | 16 | [Mutations.SET_DATA_PATH](state, path) { 17 | state.dataPath = path 18 | }, 19 | 20 | [Mutations.SET_ALLOW_PRERELEASE](state, allowPrerelease) { 21 | state.allowPrerelease = allowPrerelease 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/store/modules/app/state.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | language: null, 3 | theme: null, 4 | updateInterval: null, 5 | dataPath: null, 6 | allowPrerelease: null 7 | }) 8 | -------------------------------------------------------------------------------- /src/store/modules/app/types.js: -------------------------------------------------------------------------------- 1 | export const Getters = { 2 | GET_LANGUAGE: 'getLanguage', 3 | GET_THEME: 'getTheme', 4 | GET_UPDATE_INTERVAL: 'getUpdateInterval', 5 | GET_DATA_PATH: 'getDataPath', 6 | GET_ALLOW_PRERELEASE: 'getAllowPrerelease' 7 | } 8 | 9 | export const Actions = { 10 | SET_LANGUAGE: 'setLanguage', 11 | SET_THEME: 'setTheme', 12 | SET_UPDATE_INTERVAL: 'setUpdateInterval', 13 | SYNC_UPDATE_INTERVAL: 'syncUpdateInterval', 14 | SET_DATA_PATH: 'setDataPath', 15 | INIT_APP: 'initApp', 16 | SET_ALLOW_PRERELEASE: 'setAllowPrerelease' 17 | } 18 | 19 | export const Mutations = { 20 | SET_LANGUAGE: 'setLanguage', 21 | SET_THEME: 'setTheme', 22 | SET_UPDATE_INTERVAL: 'setUpdateInterval', 23 | SET_DATA_PATH: 'setDataPath', 24 | SET_ALLOW_PRERELEASE: 'setAllowPrerelease' 25 | } 26 | -------------------------------------------------------------------------------- /src/store/modules/calendar/actions.js: -------------------------------------------------------------------------------- 1 | import { Actions, Mutations, Getters } from '@/store/modules/calendar/types' 2 | import { 3 | shiftDate, 4 | setDate, 5 | getToday, 6 | getCurrentWeekDates 7 | } from '@/store/modules/calendar/helper' 8 | 9 | export default { 10 | [Actions.SET_DATE](context, date = setDate(getToday())) { 11 | context.commit(Mutations.SET_DATE, setDate(date)) 12 | }, 13 | [Actions.SET_DAY_TO](context, days) { 14 | context.commit( 15 | Mutations.SET_DATE, 16 | shiftDate(context.getters[Getters.GET_CURRENT_DATE], days) 17 | ) 18 | }, 19 | [Actions.SET_CURRENT_WEEK](context) { 20 | context.commit( 21 | Mutations.SET_CURRENT_WEEK, 22 | getCurrentWeekDates(context.getters[Getters.GET_CURRENT_DATE]) 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/store/modules/calendar/getters.js: -------------------------------------------------------------------------------- 1 | import { Getters } from './types' 2 | 3 | export default { 4 | [Getters.GET_CURRENT_DATE](state) { 5 | return state.currentDate 6 | }, 7 | [Getters.GET_CURRENT_WEEK](state) { 8 | return state.currentWeek 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/store/modules/calendar/helper.js: -------------------------------------------------------------------------------- 1 | import { DateTime } from 'luxon' 2 | 3 | const getToday = () => { 4 | return DateTime.now().toISODate() 5 | } 6 | 7 | /** 8 | * Set the current day by click. 9 | * @param {*} date 10 | * @returns 11 | */ 12 | const setDate = (date) => { 13 | return DateTime.fromISO(date).toISODate() 14 | } 15 | 16 | /** 17 | * Takes in any integer and shifts the date by the value of the integer. Returns a normal date string. 18 | * @param {number} date 19 | * @param {string} days 20 | * @returns {string} date 21 | */ 22 | const shiftDate = (date, days) => { 23 | return DateTime.fromISO(date).plus({ days: days }).toISODate() 24 | } 25 | 26 | /** 27 | * Format a date into any string. 28 | * @param {string} date 29 | * @param {string} format 30 | * @returns {string} 31 | */ 32 | const formatDate = (date, format) => { 33 | return DateTime.fromISO(date) 34 | .setLocale(localStorage.lang ?? 'en-US') 35 | .toFormat(format) 36 | } 37 | 38 | /** 39 | * Returns an array of date strings in YYYY-mm-dd for the current active week 40 | */ 41 | const getCurrentWeekDates = (date) => { 42 | let week = [] 43 | const startOfWeek = DateTime.fromISO(date).startOf('week') 44 | 45 | for (let i = 0; i <= 6; i++) { 46 | let day = startOfWeek 47 | .plus({ days: i }) 48 | .setLocale(localStorage.lang ?? 'en-US') 49 | week.push({ 50 | isoDate: day.toISODate(), 51 | day: day.toFormat('d'), 52 | weekDay: day.toFormat('EEE') 53 | }) 54 | } 55 | return week 56 | } 57 | 58 | export { getToday, setDate, shiftDate, formatDate, getCurrentWeekDates } 59 | -------------------------------------------------------------------------------- /src/store/modules/calendar/index.js: -------------------------------------------------------------------------------- 1 | import actions from './actions' 2 | import getters from './getters' 3 | import mutations from './mutations' 4 | import state from './state' 5 | 6 | export default { 7 | namespaced: true, 8 | state, 9 | actions, 10 | mutations, 11 | getters 12 | } 13 | -------------------------------------------------------------------------------- /src/store/modules/calendar/mutations.js: -------------------------------------------------------------------------------- 1 | import { Mutations } from './types' 2 | 3 | export default { 4 | [Mutations.SET_DATE](state, date) { 5 | state.currentDate = date 6 | }, 7 | [Mutations.SET_CURRENT_WEEK](state, week) { 8 | state.currentWeek = week 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/store/modules/calendar/state.js: -------------------------------------------------------------------------------- 1 | import { DateTime } from 'luxon' 2 | import { getCurrentWeekDates } from '@/store/modules/calendar/helper' 3 | 4 | export default () => ({ 5 | currentDate: DateTime.now().toISODate(), 6 | currentWeek: getCurrentWeekDates(DateTime.now().toISODate()) 7 | }) 8 | -------------------------------------------------------------------------------- /src/store/modules/calendar/types.js: -------------------------------------------------------------------------------- 1 | export const Getters = { 2 | GET_TODAY: 'getToday', 3 | GET_CURRENT_DATE: 'getCurrentDate', 4 | GET_CURRENT_WEEK: 'getCurrentWeek' 5 | } 6 | 7 | export const Actions = { 8 | SET_DATE: 'setDate', 9 | SET_DAY_TO: 'setDayTo', 10 | SET_CURRENT_WEEK: 'setCurrentWeek' 11 | } 12 | 13 | export const Mutations = { 14 | SET_DATE: 'setDate', 15 | SET_CURRENT_WEEK: 'setCurrentWeek' 16 | } 17 | -------------------------------------------------------------------------------- /src/store/modules/file/actions.js: -------------------------------------------------------------------------------- 1 | import { Actions, Mutations, Getters } from '@/store/modules/file/types' 2 | import { Getters as CalendarGetters } from '@/store/modules/calendar/types' 3 | import { fetchFile, saveFile } from '@/store/modules/file/helper' 4 | 5 | export default { 6 | async [Actions.FETCH_FILE](context, date) { 7 | const file = await fetchFile(date) 8 | 9 | context.commit(Mutations.SET_CONTENT, file.content) 10 | context.commit(Mutations.SET_RATING, file.rating) 11 | }, 12 | [Actions.SET_CONTENT](context, content) { 13 | context.commit(Mutations.SET_CONTENT, content) 14 | }, 15 | [Actions.SAVE_FILE](context) { 16 | saveFile( 17 | context.rootGetters[`calendar/${CalendarGetters.GET_CURRENT_DATE}`], 18 | context.getters[Getters.GET_FILE] 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/store/modules/file/getters.js: -------------------------------------------------------------------------------- 1 | import { Getters } from '@/store/modules/file/types' 2 | 3 | export default { 4 | [Getters.GET_CONTENT](state) { 5 | return state.content 6 | }, 7 | [Getters.GET_RATING](state) { 8 | return state.rating 9 | }, 10 | [Getters.GET_FILE](state) { 11 | return { 12 | content: state.content, 13 | rating: state.rating 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/store/modules/file/helper.js: -------------------------------------------------------------------------------- 1 | const { ipcRenderer } = require('electron') 2 | import { formatDate } from '@/store/modules/calendar/helper' 3 | 4 | const fetchFile = date => { 5 | return ipcRenderer.invoke('FETCH_FILE', [formatDate(date, 'y'), date]) 6 | } 7 | const saveFile = (date, file) => { 8 | return ipcRenderer.invoke('SAVE_FILE', [ 9 | formatDate(date, 'y'), 10 | date, 11 | file.content, 12 | file.rating 13 | ]) 14 | } 15 | 16 | const debounce = (func, wait) => { 17 | let timeout 18 | 19 | return function executedFunction(...args) { 20 | const later = () => { 21 | clearTimeout(timeout) 22 | func(...args) 23 | } 24 | clearTimeout(timeout) 25 | timeout = setTimeout(later, wait) 26 | } 27 | } 28 | 29 | export { debounce, fetchFile, saveFile } 30 | -------------------------------------------------------------------------------- /src/store/modules/file/index.js: -------------------------------------------------------------------------------- 1 | import actions from './actions' 2 | import getters from './getters' 3 | import mutations from './mutations' 4 | import state from './state' 5 | 6 | export default { 7 | namespaced: true, 8 | state, 9 | actions, 10 | mutations, 11 | getters 12 | } 13 | -------------------------------------------------------------------------------- /src/store/modules/file/mutations.js: -------------------------------------------------------------------------------- 1 | import { Mutations } from '@/store/modules/file/types' 2 | 3 | export default { 4 | [Mutations.SET_CONTENT](state, content) { 5 | state.content = content 6 | }, 7 | [Mutations.SET_RATING](state, rating) { 8 | state.rating = rating 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/store/modules/file/state.js: -------------------------------------------------------------------------------- 1 | export default () => ({ 2 | content: null, 3 | rating: null 4 | }) 5 | -------------------------------------------------------------------------------- /src/store/modules/file/types.js: -------------------------------------------------------------------------------- 1 | export const Getters = { 2 | GET_CONTENT: 'getContent', 3 | GET_RATING: 'getRating', 4 | GET_FILE: 'getFile' 5 | } 6 | 7 | export const Actions = { 8 | SET_CONTENT: 'setContent', 9 | FETCH_FILE: 'fetchFile', 10 | SAVE_FILE: 'saveFile' 11 | } 12 | 13 | export const Mutations = { 14 | SET_CONTENT: 'setContent', 15 | SET_RATING: 'setRating' 16 | } 17 | -------------------------------------------------------------------------------- /src/translation.js: -------------------------------------------------------------------------------- 1 | export const translate = async (identifier, data = {}) => { 2 | const language = await import(`./locales/${localStorage.lang ?? 'en-US'}.json`) 3 | 4 | let string = identifier 5 | .split('.') 6 | .reduce( 7 | (prev, curr) => prev && prev[curr], 8 | language.default 9 | ); 10 | for (const key in data) string = string.replace(`:${key}`, data[key]); 11 | return string; 12 | 13 | } 14 | 15 | export const Translations = { 16 | locale: localStorage.lang ?? 'en-US', 17 | translationStrings: import(`./locales/${this?.locale || 'en-US'}.json`), 18 | install(VueInstance) { 19 | VueInstance.prototype.$setLocale = function (locale) { 20 | this.locale = locale; 21 | }.bind(this); 22 | 23 | VueInstance.prototype.$getLocale = function () { 24 | return this.locale; 25 | }.bind(this); 26 | }, 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /src/updater.js: -------------------------------------------------------------------------------- 1 | import { dialog, Notification } from 'electron' 2 | import { autoUpdater } from 'electron-updater' 3 | import { DAILY, WEEKLY } from '@/background' 4 | 5 | autoUpdater.on('update-available', async (updateInfo) => { 6 | const { response } = await dialog.showMessageBox({ 7 | title: 'Update available', 8 | message: `Version ${updateInfo.version} is available, would you like to update now?`, 9 | detail: 'The app will download the update and restart once finished.', 10 | type: 'question', 11 | buttons: ['Remind me later', 'Install'], 12 | defaultId: 1, 13 | noLink: true 14 | }) 15 | if (response === 1) { 16 | global.storage.set('updateInterval', DAILY) 17 | await autoUpdater.downloadUpdate() 18 | } else { 19 | global.storage.set('updateInterval', WEEKLY) 20 | } 21 | }) 22 | 23 | autoUpdater.on('update-not-available', async () => { 24 | await new Notification({ 25 | title: 'No updates found.', 26 | body: 'You are already on the latest version of linked.' 27 | }).show() 28 | }) 29 | 30 | autoUpdater.on('update-downloaded', async () => { 31 | autoUpdater.quitAndInstall() 32 | }) 33 | 34 | const askForUpdates = async () => { 35 | if (!global.storage.get('enableUpdates')) return 36 | 37 | autoUpdater.autoDownload = false 38 | autoUpdater.allowPrerelease = global.storage.get('allowPrerelease') 39 | 40 | await autoUpdater.checkForUpdates() 41 | } 42 | 43 | const setupUpdates = () => { 44 | if (parseInt(global.storage.get('updateInterval')) === DAILY) { 45 | askForUpdates() 46 | } 47 | setInterval(() => askForUpdates(), global.storage.get('updateInterval')) 48 | } 49 | 50 | export default { setupUpdates, askForUpdates } 51 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 38 | -------------------------------------------------------------------------------- /src/views/Layout.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/views/Search.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/views/Settings.vue: -------------------------------------------------------------------------------- 1 | 98 | 99 | 148 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const colors = require('tailwindcss/colors') 2 | 3 | module.exports = { 4 | darkMode: 'class', 5 | purge: { 6 | enabled: false, 7 | content: ['./src/**/*.html', './src/**/*.vue', './src/**/*.svg'] 8 | }, 9 | theme: { 10 | extend: { 11 | colors: { 12 | 'pink': '#D1014C', 13 | 'bright-pink': '#FF005C', 14 | 'secondary-black': '#1f1f1f' 15 | } 16 | }, 17 | colors: { 18 | transparent: 'transparent', 19 | current: 'currentColor', 20 | black: '#141414', 21 | white: '#ffffff', 22 | gray: colors.gray, 23 | indigo: colors.indigo, 24 | red: colors.rose, 25 | yellow: colors.amber 26 | } 27 | }, 28 | variants: { 29 | extend: { 30 | ringWidth: ['hover'], 31 | ringColor: ['hover'], 32 | opacity: ['active', 'hover'], 33 | scale: ['active'], 34 | border: ['focus'], 35 | translate: ['active'], 36 | transform: ['active'], 37 | dark: ['hover'] 38 | } 39 | }, 40 | plugins: [] 41 | } 42 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | chainWebpack: config => { 3 | const svgRule = config.module.rule('svg') 4 | 5 | svgRule.uses.clear() 6 | 7 | svgRule 8 | .use('vue-loader') 9 | .loader('vue-loader') // or `vue-loader-v16` if you are using a preview support of Vue 3 in Vue CLI 10 | .end() 11 | .use('vue-svg-loader') 12 | .loader('vue-svg-loader') 13 | }, 14 | 15 | configureWebpack: { 16 | devtool: 'source-map' 17 | }, 18 | pluginOptions: { 19 | electronBuilder: { 20 | nodeIntegration: true, 21 | generateUpdatesFilesForAllChannels: true, 22 | builderOptions: { 23 | mac: { 24 | hardenedRuntime: true, 25 | entitlements: './build/entitlements.mac.inherit.plist', 26 | // Disabled m1 due to it messing with the auto updating 27 | //target: { 28 | // target: 'default', 29 | // arch: ['arm64', 'x64'] 30 | //} 31 | }, 32 | linux: { 33 | target: [ 34 | 'deb', 35 | 'rpm', 36 | 'pacman', 37 | 'AppImage' 38 | ] 39 | }, 40 | win: { 41 | icon: '/build/icons/256x256.png', 42 | target: ['nsis', 'portable'] 43 | }, 44 | publish: ['github'], 45 | appId: 'design.lost.linked', 46 | afterSign: './afterSignHook.js' 47 | } 48 | }, 49 | i18n: { 50 | locale: 'en-US', 51 | fallbackLocale: 'en-US', 52 | localeDir: 'locales', 53 | enableInSFC: false 54 | } 55 | } 56 | } 57 | --------------------------------------------------------------------------------