1
0
mirror of https://github.com/laurent22/joplin.git synced 2026-03-21 10:25:18 +02:00

Compare commits

..

24 Commits

Author SHA1 Message Date
Laurent Cozic
04666be15f ts 2025-03-09 09:38:05 +00:00
Laurent Cozic
64d0bec2c5 fixed ts error 2025-03-08 11:12:56 +00:00
Laurent Cozic
ab28f2a794 init 2025-03-08 10:19:51 +00:00
Laurent Cozic
ab86b95fad Desktop, Mobile, Cli: Add setting migration for ocr.enabled 2025-03-07 15:47:44 +00:00
Laurent Cozic
0f07c0f53a Desktop, Mobile: Fixes #11673: Make tab size consistent between Markdown editor and viewer (and RTE) (#11940)
Co-authored-by: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com>
2025-03-07 15:42:32 +00:00
Dmitriy Q
a6d04c4781 All: Translation: Update ru_RU.po (#11937) 2025-03-06 23:44:58 -05:00
PARAMESH T S
bc27f47881 Desktop: Fixes #11923: Sharing a notebook with nobody prints "No user with ID public_key" (#11932)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
2025-03-06 15:58:10 +00:00
Henry Heino
d1d75449f5 Chore: CI: Upgrade Linux actions runner to Ubuntu 22.04 (#11927) 2025-03-06 00:19:57 +00:00
Laurent Cozic
bbea5388ed Doc: Describe how to migrate from Joplin Cloud Basic or Pro to Team 2025-03-05 19:42:47 +00:00
Laurent Cozic
99e773855e Chore: Improve error message when website does not build 2025-03-05 18:57:02 +00:00
Laurent Cozic
55b73347e5 Doc: Fixed downloading Apple Silicon version on Download page 2025-03-05 18:56:44 +00:00
Laurent Cozic
7e8dee4906 Desktop: Added keyboard shortcut and menu item for toggleEditorPlugin command 2025-03-05 00:43:39 +00:00
Laurent Cozic
69fb1ab104 Chore: Fixed test that fails on fast enough computers 2025-03-05 00:43:39 +00:00
Helmut K. C. Tessarek
67ae0ea2d1 Desktop: improve download in install script (#11921) 2025-03-04 19:06:31 -05:00
Celestial.y
cdb61b922b All: Translation: Update zh_CN.po (#11922) 2025-03-04 18:52:12 -05:00
pedr
da80443796 Chore: Remove file created during automated test (#11915) 2025-03-04 11:58:57 +00:00
Henry Heino
1924dd31d2 Desktop: Make "toggle all folders" button also expand the folder list (#11917) 2025-03-04 11:58:31 +00:00
Henry Heino
b831d8c068 Desktop: Accessibility: Improve "toggle all notebooks" accessibility (#11918) 2025-03-04 11:57:11 +00:00
Joplin Bot
4ad1b49769 Doc: Auto-update documentation
Auto-updated using release-website.sh
2025-03-04 02:03:55 +00:00
klxiang
0d6c1067e3 All: Translation: Update zh_CN.po (#11920) 2025-03-03 21:01:55 -05:00
Eric Duarte
0bdc38a6be All: Translation: Update es_ES.po (#11913) 2025-03-03 20:43:27 -05:00
Laurent Cozic
5c35569b5b Android 3.3.2 2025-03-03 22:36:37 +00:00
Laurent Cozic
5f02af9724 Server v3.3.4 2025-03-03 22:29:46 +00:00
Henry Heino
975f16d21c Server: Security: Improve request validation in default route (#11916) 2025-03-03 22:29:05 +00:00
56 changed files with 1131 additions and 1201 deletions

View File

@@ -1026,6 +1026,7 @@ packages/lib/commands/renderMarkup.test.js
packages/lib/commands/renderMarkup.js packages/lib/commands/renderMarkup.js
packages/lib/commands/showEditorPlugin.js packages/lib/commands/showEditorPlugin.js
packages/lib/commands/synchronize.js packages/lib/commands/synchronize.js
packages/lib/commands/toggleAllFolders.test.js
packages/lib/commands/toggleAllFolders.js packages/lib/commands/toggleAllFolders.js
packages/lib/commands/toggleEditorPlugin.js packages/lib/commands/toggleEditorPlugin.js
packages/lib/components/EncryptionConfigScreen/utils.test.js packages/lib/components/EncryptionConfigScreen/utils.test.js

View File

@@ -9,7 +9,7 @@ jobs:
matrix: matrix:
# Do not use unbuntu-latest because it causes `The operation was canceled` failures: # Do not use unbuntu-latest because it causes `The operation was canceled` failures:
# https://github.com/actions/runner-images/issues/6709 # https://github.com/actions/runner-images/issues/6709
os: [macos-13, ubuntu-20.04, windows-2019] os: [macos-13, ubuntu-22.04, windows-2019]
steps: steps:
# Trying to fix random networking issues on Windows # Trying to fix random networking issues on Windows
@@ -150,7 +150,7 @@ jobs:
matrix: matrix:
# Do not use unbuntu-latest because it causes `The operation was canceled` failures: # Do not use unbuntu-latest because it causes `The operation was canceled` failures:
# https://github.com/actions/runner-images/issues/6709 # https://github.com/actions/runner-images/issues/6709
os: [ubuntu-20.04] os: [ubuntu-22.04]
steps: steps:
- name: Install Docker Engine - name: Install Docker Engine

1
.gitignore vendored
View File

@@ -1001,6 +1001,7 @@ packages/lib/commands/renderMarkup.test.js
packages/lib/commands/renderMarkup.js packages/lib/commands/renderMarkup.js
packages/lib/commands/showEditorPlugin.js packages/lib/commands/showEditorPlugin.js
packages/lib/commands/synchronize.js packages/lib/commands/synchronize.js
packages/lib/commands/toggleAllFolders.test.js
packages/lib/commands/toggleAllFolders.js packages/lib/commands/toggleAllFolders.js
packages/lib/commands/toggleEditorPlugin.js packages/lib/commands/toggleEditorPlugin.js
packages/lib/components/EncryptionConfigScreen/utils.test.js packages/lib/components/EncryptionConfigScreen/utils.test.js

View File

@@ -80,7 +80,7 @@ async function setupDownloadPage() {
if (href.indexOf('-Setup') > 0) downloadLinks['windows'] = href; if (href.indexOf('-Setup') > 0) downloadLinks['windows'] = href;
if (href.indexOf('.dmg') > 0) downloadLinks['macOs'] = href; if (href.indexOf('.dmg') > 0) downloadLinks['macOs'] = href;
if (href.endsWith('arm64.DMG')) downloadLinks['macOsM1'] = href; if (href.indexOf('arm64.DMG') > 0) downloadLinks['macOsM1'] = href;
if (href.indexOf('.AppImage') > 0) downloadLinks['linux'] = href; if (href.indexOf('.AppImage') > 0) downloadLinks['linux'] = href;
}); });
@@ -98,6 +98,8 @@ async function setupDownloadPage() {
} else { } else {
const os = await getOs(); const os = await getOs();
console.info('Found OS: ' + os);
if (os === 'macOsUndefined') { if (os === 'macOsUndefined') {
// If we don't know which macOS version it is, we let the user choose. // If we don't know which macOS version it is, we let the user choose.
$('.main-content .intro').html('<p class="macos-m1-info">The macOS release is available for Intel processors or for Apple Silicon (M1) processors. Please select your version:</p>'); $('.main-content .intro').html('<p class="macos-m1-info">The macOS release is available for Intel processors or for Apple Silicon (M1) processors. Please select your version:</p>');

View File

@@ -67,10 +67,23 @@ showHelp() {
fi fi
} }
#-----------------------------------------------------
# Setup Download Helper: DL
#-----------------------------------------------------
if [[ `command -v wget2` ]]; then
DL='wget2 -qO'
elif [[ `command -v wget` ]]; then
DL='wget -qO'
elif [[ `command -v curl` ]]; then
DL='curl -sLo'
else
print "${COLOR_RED}Error: wget2, wget, and curl not found. Please install one of these tools.${COLOR_RESET}"
exit 1
fi
#----------------------------------------------------- #-----------------------------------------------------
# PARSE ARGUMENTS # PARSE ARGUMENTS
#----------------------------------------------------- #-----------------------------------------------------
optspec=":h-:" optspec=":h-:"
while getopts "${optspec}" OPT; do while getopts "${optspec}" OPT; do
[ "${OPT}" = " " ] && continue [ "${OPT}" = " " ] && continue
@@ -140,9 +153,9 @@ fi
# Get the latest version to download # Get the latest version to download
if [[ "$INCLUDE_PRE_RELEASE" == true ]]; then if [[ "$INCLUDE_PRE_RELEASE" == true ]]; then
RELEASE_VERSION=$(wget -qO - "https://api.github.com/repos/laurent22/joplin/releases" | grep -Po '"tag_name": ?"v\K.*?(?=")' | sort -rV | head -1) RELEASE_VERSION=$($DL - "https://api.github.com/repos/laurent22/joplin/releases" | grep -Po '"tag_name": ?"v\K.*?(?=")' | sort -rV | head -1)
else else
RELEASE_VERSION=$(wget -qO - "https://api.github.com/repos/laurent22/joplin/releases/latest" | grep -Po '"tag_name": ?"v\K.*?(?=")') RELEASE_VERSION=$($DL - "https://api.github.com/repos/laurent22/joplin/releases/latest" | grep -Po '"tag_name": ?"v\K.*?(?=")')
fi fi
# Check if it's in the latest version # Check if it's in the latest version
@@ -163,8 +176,8 @@ fi
#----------------------------------------------------- #-----------------------------------------------------
print 'Downloading Joplin...' print 'Downloading Joplin...'
TEMP_DIR=$(mktemp -d) TEMP_DIR=$(mktemp -d)
wget -O "${TEMP_DIR}/Joplin.AppImage" "https://objects.joplinusercontent.com/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage?source=LinuxInstallScript&type=$DOWNLOAD_TYPE" $DL "${TEMP_DIR}/Joplin.AppImage" "https://objects.joplinusercontent.com/v${RELEASE_VERSION}/Joplin-${RELEASE_VERSION}.AppImage?source=LinuxInstallScript&type=$DOWNLOAD_TYPE"
wget -O "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png $DL "${TEMP_DIR}/joplin.png" https://joplinapp.org/images/Icon512.png
#----------------------------------------------------- #-----------------------------------------------------
print 'Installing Joplin...' print 'Installing Joplin...'
@@ -287,7 +300,7 @@ echo "$RELEASE_VERSION" > "${INSTALL_DIR}/VERSION"
#----------------------------------------------------- #-----------------------------------------------------
if [[ "$SHOW_CHANGELOG" == true ]]; then if [[ "$SHOW_CHANGELOG" == true ]]; then
NOTES=$(wget -qO - https://api.github.com/repos/laurent22/joplin/releases/latest | grep -Po '"body": "\K.*(?=")') NOTES=$($DL - https://api.github.com/repos/laurent22/joplin/releases/latest | grep -Po '"body": "\K.*(?=")')
print "${COLOR_BLUE}Changelog:${COLOR_RESET}\n${NOTES}" print "${COLOR_BLUE}Changelog:${COLOR_RESET}\n${NOTES}"
fi fi

View File

@@ -4,15 +4,12 @@ import AutoUpdaterService, { defaultUpdateInterval, initialUpdateStartup } from
import type ShimType from '@joplin/lib/shim'; import type ShimType from '@joplin/lib/shim';
const shim: typeof ShimType = require('@joplin/lib/shim').default; const shim: typeof ShimType = require('@joplin/lib/shim').default;
import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils'; import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils';
import { BrowserWindow, Tray, WebContents, screen, App, Event, dialog, ipcMain } from 'electron';
import { BrowserWindow, Tray, WebContents, screen } from 'electron';
import bridge from './bridge'; import bridge from './bridge';
const url = require('url'); const url = require('url');
const path = require('path'); const path = require('path');
const { dirname } = require('@joplin/lib/path-utils'); const { dirname } = require('@joplin/lib/path-utils');
const fs = require('fs-extra'); const fs = require('fs-extra');
import { dialog, ipcMain } from 'electron';
import { _ } from '@joplin/lib/locale'; import { _ } from '@joplin/lib/locale';
import restartInSafeModeFromMain from './utils/restartInSafeModeFromMain'; import restartInSafeModeFromMain from './utils/restartInSafeModeFromMain';
import handleCustomProtocols, { CustomProtocolHandler } from './utils/customProtocols/handleCustomProtocols'; import handleCustomProtocols, { CustomProtocolHandler } from './utils/customProtocols/handleCustomProtocols';
@@ -36,8 +33,7 @@ interface SecondaryWindowData {
export default class ElectronAppWrapper { export default class ElectronAppWrapper {
private logger_: Logger = null; private logger_: Logger = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied private electronApp_: App;
private electronApp_: any;
private env_: string; private env_: string;
private isDebugMode_: boolean; private isDebugMode_: boolean;
private profilePath_: string; private profilePath_: string;
@@ -48,8 +44,7 @@ export default class ElectronAppWrapper {
private secondaryWindows_: Map<SecondaryWindowId, SecondaryWindowData> = new Map(); private secondaryWindows_: Map<SecondaryWindowId, SecondaryWindowData> = new Map();
private willQuitApp_ = false; private willQuitApp_ = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied private tray_: Tray = null;
private tray_: any = null;
private buildDir_: string = null; private buildDir_: string = null;
private rendererProcessQuitReply_: RendererProcessQuitReply = null; private rendererProcessQuitReply_: RendererProcessQuitReply = null;
@@ -57,14 +52,15 @@ export default class ElectronAppWrapper {
private updaterService_: AutoUpdaterService = null; private updaterService_: AutoUpdaterService = null;
private customProtocolHandler_: CustomProtocolHandler = null; private customProtocolHandler_: CustomProtocolHandler = null;
private updatePollInterval_: ReturnType<typeof setTimeout>|null = null; private updatePollInterval_: ReturnType<typeof setTimeout>|null = null;
private isAltInstance_: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied public constructor(electronApp: App, env: string, profilePath: string|null, isDebugMode: boolean, initialCallbackUrl: string, isAltInstance: boolean) {
public constructor(electronApp: any, env: string, profilePath: string|null, isDebugMode: boolean, initialCallbackUrl: string) {
this.electronApp_ = electronApp; this.electronApp_ = electronApp;
this.env_ = env; this.env_ = env;
this.isDebugMode_ = isDebugMode; this.isDebugMode_ = isDebugMode;
this.profilePath_ = profilePath; this.profilePath_ = profilePath;
this.initialCallbackUrl_ = initialCallbackUrl; this.initialCallbackUrl_ = initialCallbackUrl;
this.isAltInstance_ = isAltInstance;
} }
public electronApp() { public electronApp() {
@@ -87,6 +83,10 @@ export default class ElectronAppWrapper {
return BrowserWindow.getFocusedWindow() ?? this.win_; return BrowserWindow.getFocusedWindow() ?? this.win_;
} }
public isAltInstance() {
return this.isAltInstance_;
}
public windowById(joplinId: string) { public windowById(joplinId: string) {
if (joplinId === defaultWindowId) { if (joplinId === defaultWindowId) {
return this.mainWindow(); return this.mainWindow();
@@ -538,6 +538,7 @@ export default class ElectronAppWrapper {
public ensureSingleInstance() { public ensureSingleInstance() {
if (this.env_ === 'dev') return false; if (this.env_ === 'dev') return false;
if (this.isAltInstance_) return false;
const gotTheLock = this.electronApp_.requestSingleInstanceLock(); const gotTheLock = this.electronApp_.requestSingleInstanceLock();
@@ -548,8 +549,7 @@ export default class ElectronAppWrapper {
} }
// Someone tried to open a second instance - focus our window instead // Someone tried to open a second instance - focus our window instead
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied this.electronApp_.on('second-instance', (_event: Event, argv: string[], _workingDirectory: string) => {
this.electronApp_.on('second-instance', (_e: any, argv: string[]) => {
const win = this.mainWindow(); const win = this.mainWindow();
if (!win) return; if (!win) return;
if (win.isMinimized()) win.restore(); if (win.isMinimized()) win.restore();

View File

@@ -617,10 +617,11 @@ class Application extends BaseApplication {
clipperLogger.addTarget(TargetType.Console); clipperLogger.addTarget(TargetType.Console);
ClipperServer.instance().initialize(actionApi); ClipperServer.instance().initialize(actionApi);
ClipperServer.instance().setEnabled(!Setting.value('isAltInstance'));
ClipperServer.instance().setLogger(clipperLogger); ClipperServer.instance().setLogger(clipperLogger);
ClipperServer.instance().setDispatch(this.store().dispatch); ClipperServer.instance().setDispatch(this.store().dispatch);
if (Setting.value('clipperServer.autoStart')) { if (ClipperServer.instance().enabled() && Setting.value('clipperServer.autoStart')) {
void ClipperServer.instance().start(); void ClipperServer.instance().start();
} }

View File

@@ -24,6 +24,7 @@ class ClipperConfigScreenComponent extends React.Component {
} }
private enableClipperServer_click() { private enableClipperServer_click() {
if (!ClipperServer.instance().enabled()) return;
Setting.setValue('clipperServer.autoStart', true); Setting.setValue('clipperServer.autoStart', true);
void ClipperServer.instance().start(); void ClipperServer.instance().start();
} }
@@ -70,6 +71,8 @@ class ClipperConfigScreenComponent extends React.Component {
const webClipperStatusComps = []; const webClipperStatusComps = [];
const clipperEnabled = ClipperServer.instance().enabled();
if (this.props.clipperServerAutoStart) { if (this.props.clipperServerAutoStart) {
webClipperStatusComps.push( webClipperStatusComps.push(
<p key="text_1" style={theme.textStyle}> <p key="text_1" style={theme.textStyle}>
@@ -95,13 +98,22 @@ class ClipperConfigScreenComponent extends React.Component {
</button>, </button>,
); );
} else { } else {
if (!clipperEnabled) {
webClipperStatusComps.push(
<p key="text_4" style={theme.textStyle}>
{_('The web clipper service cannot be enabled in this instance of Joplin.')}
</p>,
);
} else {
webClipperStatusComps.push(
<p key="text_4" style={theme.textStyle}>
{_('The web clipper service is not enabled.')}
</p>,
);
}
webClipperStatusComps.push( webClipperStatusComps.push(
<p key="text_4" style={theme.textStyle}> <button key="enable_button" style={buttonStyle} onClick={this.enableClipperServer_click} disabled={!clipperEnabled}>
{_('The web clipper service is not enabled.')}
</p>,
);
webClipperStatusComps.push(
<button key="enable_button" style={buttonStyle} onClick={this.enableClipperServer_click}>
{_('Enable Web Clipper Service')} {_('Enable Web Clipper Service')}
</button>, </button>,
); );

View File

@@ -789,6 +789,7 @@ function useMenu(props: Props) {
shim.isMac() ? noItem : menuItemDic.toggleMenuBar, shim.isMac() ? noItem : menuItemDic.toggleMenuBar,
menuItemDic.toggleNoteList, menuItemDic.toggleNoteList,
menuItemDic.toggleVisiblePanes, menuItemDic.toggleVisiblePanes,
menuItemDic.toggleEditorPlugin,
{ {
label: _('Layout button sequence'), label: _('Layout button sequence'),
submenu: layoutButtonSequenceMenuItems, submenu: layoutButtonSequenceMenuItems,

View File

@@ -22,13 +22,14 @@ interface CollapseExpandAllButtonProps {
} }
const CollapseExpandAllButton = (props: CollapseExpandAllButtonProps) => { const CollapseExpandAllButton = (props: CollapseExpandAllButtonProps) => {
// To allow it to be accessed by accessibility tools, the new folder button // To allow it to be accessed by accessibility tools, the toggle button
// is not included in the portion of the list with role='tree'. // is not included in the portion of the list with role='tree'.
const icon = props.allFoldersCollapsed ? 'far fa-caret-square-right' : 'far fa-caret-square-down'; const icon = props.allFoldersCollapsed ? 'far fa-caret-square-right' : 'far fa-caret-square-down';
const label = props.allFoldersCollapsed ? _('Expand all notebooks') : _('Collapse all notebooks');
return <button onClick={() => onToggleAllFolders(props.allFoldersCollapsed)} className='sidebar-header-button -collapseall'> return <button onClick={() => onToggleAllFolders(props.allFoldersCollapsed)} className='sidebar-header-button -collapseall'>
<i <i
aria-label={_('Collapse / Expand all notebooks')} aria-label={label}
role='img' role='img'
className={icon} className={icon}
/> />

View File

@@ -43,6 +43,7 @@ export default function() {
'togglePerFolderSortOrder', 'togglePerFolderSortOrder',
'toggleSideBar', 'toggleSideBar',
'toggleVisiblePanes', 'toggleVisiblePanes',
'toggleEditorPlugin',
'toggleTabMovesFocus', 'toggleTabMovesFocus',
'editor.deleteLine', 'editor.deleteLine',
'editor.duplicateLine', 'editor.duplicateLine',

View File

@@ -29,7 +29,6 @@ const EncryptionService = require('@joplin/lib/services/e2ee/EncryptionService')
const FileApiDriverLocal = require('@joplin/lib/file-api-driver-local').default; const FileApiDriverLocal = require('@joplin/lib/file-api-driver-local').default;
const React = require('react'); const React = require('react');
const nodeSqlite = require('sqlite3'); const nodeSqlite = require('sqlite3');
const nodeSqliteCipher = require('@journeyapps/sqlcipher');
const initLib = require('@joplin/lib/initLib').default; const initLib = require('@joplin/lib/initLib').default;
const pdfJs = require('pdfjs-dist'); const pdfJs = require('pdfjs-dist');
require('@sentry/electron/renderer'); require('@sentry/electron/renderer');
@@ -110,7 +109,6 @@ const main = async () => {
appVersion, appVersion,
electronBridge: bridge(), electronBridge: bridge(),
nodeSqlite, nodeSqlite,
nodeSqliteCipher,
pdfJs, pdfJs,
}); });

View File

@@ -40,6 +40,7 @@ Logger.fsDriver_ = new FsDriverNode();
const env = envFromArgs(process.argv); const env = envFromArgs(process.argv);
const profileFromArgs = getProfileFromArgs(process.argv); const profileFromArgs = getProfileFromArgs(process.argv);
const isDebugMode = !!process.argv && process.argv.indexOf('--debug') >= 0; const isDebugMode = !!process.argv && process.argv.indexOf('--debug') >= 0;
const isAltInstance = !!process.argv && process.argv.indexOf('--is-alt-instance') >= 0;
// We initialize all these variables here because they are needed from the main process. They are // We initialize all these variables here because they are needed from the main process. They are
// then passed to the renderer process via the bridge. // then passed to the renderer process via the bridge.
@@ -65,7 +66,7 @@ void registerCustomProtocols();
const initialCallbackUrl = process.argv.find((arg) => isCallbackUrl(arg)); const initialCallbackUrl = process.argv.find((arg) => isCallbackUrl(arg));
const wrapper = new ElectronAppWrapper(electronApp, env, rootProfileDir, isDebugMode, initialCallbackUrl); const wrapper = new ElectronAppWrapper(electronApp, env, rootProfileDir, isDebugMode, initialCallbackUrl, isAltInstance);
initBridge(wrapper, appId, appName, rootProfileDir, autoUploadCrashDumps); initBridge(wrapper, appId, appName, rootProfileDir, autoUploadCrashDumps);

View File

@@ -166,7 +166,6 @@
"@joplin/lib": "~3.3", "@joplin/lib": "~3.3",
"@joplin/renderer": "~3.3", "@joplin/renderer": "~3.3",
"@joplin/utils": "~3.3", "@joplin/utils": "~3.3",
"@journeyapps/sqlcipher": "5.3.1",
"@sentry/electron": "4.24.0", "@sentry/electron": "4.24.0",
"@types/mustache": "4.2.5", "@types/mustache": "4.2.5",
"async-mutex": "0.5.0", "async-mutex": "0.5.0",

View File

@@ -21,7 +21,7 @@ const restartInSafeModeFromMain = async () => {
shimInit({}); shimInit({});
const startFlags = await processStartFlags(bridge().processArgv()); const startFlags = await processStartFlags(bridge().processArgv());
const { rootProfileDir } = determineBaseAppDirs(startFlags.matched.profileDir, appName); const { rootProfileDir } = determineBaseAppDirs(startFlags.matched.profileDir, appName, Setting.value('isAltInstance'));
const { profileDir } = await initProfile(rootProfileDir); const { profileDir } = await initProfile(rootProfileDir);
// We can't access the database, so write to a file instead. // We can't access the database, so write to a file instead.

View File

@@ -86,8 +86,8 @@ android {
applicationId "net.cozic.joplin" applicationId "net.cozic.joplin"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2097764 versionCode 2097765
versionName "3.3.1" versionName "3.3.2"
ndk { ndk {
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64" abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
} }

View File

@@ -15,6 +15,7 @@ const baseStyle = {
fontSizeSmaller: 14, fontSizeSmaller: 14,
disabledOpacity: 0.2, disabledOpacity: 0.2,
lineHeight: '1.6em', lineHeight: '1.6em',
listTabSize: '1.7em',
// The default, may be overridden in settings: // The default, may be overridden in settings:
noteViewerFontSize: 16, noteViewerFontSize: 16,
}; };

View File

@@ -268,8 +268,6 @@ const createEditor = (
}, },
}), }),
EditorState.tabSize.of(4),
// Apply styles to entire lines (block-display decorations) // Apply styles to entire lines (block-display decorations)
decoratorExtension, decoratorExtension,
dropCursor(), dropCursor(),

View File

@@ -106,6 +106,14 @@ const createTheme = (theme: EditorTheme): Extension[] => {
marginLeft: `${theme.marginLeft}px`, marginLeft: `${theme.marginLeft}px`,
marginRight: `${theme.marginRight}px`, marginRight: `${theme.marginRight}px`,
}, },
'& .cm-listItem': {
// Needs to be !important because the tab-size is directly set on the element style
// attribute by CodeMirror. And the `EditorState.tabSize` function only accepts a
// number, while we need a "em" value to make it match the viewer tab size.
tabSize: `${theme.listTabSize} !important`,
},
'&.cm-focused .cm-cursor': baseCursorStyle, '&.cm-focused .cm-cursor': baseCursorStyle,
// The desktop app sets the font for these elements to a specific font. // The desktop app sets the font for these elements to a specific font.

View File

@@ -146,6 +146,7 @@ export interface EditorTheme extends Theme {
contentMaxWidth?: number; contentMaxWidth?: number;
marginLeft?: number; marginLeft?: number;
marginRight?: number; marginRight?: number;
listTabSize?: string;
} }
export interface EditorSettings { export interface EditorSettings {

View File

@@ -14,7 +14,7 @@ import { createStore, applyMiddleware, Store } from 'redux';
import { defaultState, stateUtils } from './reducer'; import { defaultState, stateUtils } from './reducer';
import JoplinDatabase from './JoplinDatabase'; import JoplinDatabase from './JoplinDatabase';
import { cancelTimers as folderScreenUtilsCancelTimers, refreshFolders, scheduleRefreshFolders } from './folders-screen-utils'; import { cancelTimers as folderScreenUtilsCancelTimers, refreshFolders, scheduleRefreshFolders } from './folders-screen-utils';
const { DatabaseDriverNode } = require('./database-driver-node-sqlcipher.js'); const { DatabaseDriverNode } = require('./database-driver-node.js');
import BaseModel from './BaseModel'; import BaseModel from './BaseModel';
import Folder from './models/Folder'; import Folder from './models/Folder';
import BaseItem from './models/BaseItem'; import BaseItem from './models/BaseItem';
@@ -687,7 +687,7 @@ export default class BaseApplication {
// https://immerjs.github.io/immer/docs/freezing // https://immerjs.github.io/immer/docs/freezing
setAutoFreeze(initArgs.env === 'dev'); setAutoFreeze(initArgs.env === 'dev');
const { rootProfileDir, homeDir } = determineProfileAndBaseDir(options.rootProfileDir ?? initArgs.profileDir, appName); const { rootProfileDir, homeDir } = determineProfileAndBaseDir(options.rootProfileDir ?? initArgs.profileDir, appName, initArgs.isAltInstance);
const { profileDir, profileConfig, isSubProfile } = await initProfile(rootProfileDir); const { profileDir, profileConfig, isSubProfile } = await initProfile(rootProfileDir);
this.profileConfig_ = profileConfig; this.profileConfig_ = profileConfig;
@@ -806,6 +806,8 @@ export default class BaseApplication {
Setting.setValue('sync.interval', 3600); Setting.setValue('sync.interval', 3600);
} }
Setting.setValue('isAltInstance', initArgs.isAltInstance);
Setting.setValue('firstStart', false); Setting.setValue('firstStart', false);
} else { } else {
Setting.applyDefaultMigrations(); Setting.applyDefaultMigrations();

View File

@@ -23,6 +23,7 @@ export default class ClipperServer {
private api_: Api = null; private api_: Api = null;
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
private dispatch_: Function; private dispatch_: Function;
private enabled_ = true;
private static instance_: ClipperServer = null; private static instance_: ClipperServer = null;
@@ -40,6 +41,18 @@ export default class ClipperServer {
return this.api_; return this.api_;
} }
public enabled() {
return this.enabled_;
}
public setEnabled(v: boolean) {
this.enabled_ = v;
if (!this.enabled_ && this.isRunning()) {
void this.stop();
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public initialize(actionApi: any = null) { public initialize(actionApi: any = null) {
this.api_ = new Api(() => { this.api_ = new Api(() => {
@@ -106,6 +119,8 @@ export default class ClipperServer {
} }
public async start() { public async start() {
if (!this.enabled()) throw new Error('Cannot start clipper server because it is disabled');
this.setPort(null); this.setPort(null);
this.setStartState(StartState.Starting); this.setStartState(StartState.Starting);
@@ -251,8 +266,10 @@ export default class ClipperServer {
} }
public async stop() { public async stop() {
this.server_.destroy(); if (this.server_) {
this.server_ = null; this.server_.destroy();
this.server_ = null;
}
this.setStartState(StartState.Idle); this.setStartState(StartState.Idle);
this.setPort(null); this.setPort(null);
} }

View File

@@ -0,0 +1,36 @@
import { setupDatabase, switchClient } from '../testing/test-utils';
import { runtime } from './toggleAllFolders';
import Setting from '../models/Setting';
import { CommandContext } from '../services/CommandService';
import { defaultState } from '../reducer';
const command = runtime();
const makeContext = (): CommandContext => {
return {
state: defaultState,
dispatch: ()=>{},
};
};
describe('toggleAllFolders', () => {
beforeEach(async () => {
await setupDatabase(0);
await switchClient(0);
});
test('expanding all should expand the folders header, if previously collapsed', async () => {
Setting.setValue('folderHeaderIsExpanded', false);
// Collapsing all should leave the folder header as-is
const context = makeContext();
await command.execute(context, true);
expect(Setting.value('folderHeaderIsExpanded')).toBe(false);
// Expanding all should also expand the folder header
await command.execute(context, false);
expect(Setting.value('folderHeaderIsExpanded')).toBe(true);
});
});

View File

@@ -1,6 +1,7 @@
import { CommandRuntime, CommandDeclaration, CommandContext } from '../services/CommandService'; import { CommandRuntime, CommandDeclaration, CommandContext } from '../services/CommandService';
import { _ } from '../locale'; import { _ } from '../locale';
import getCanBeCollapsedFolderIds from '../models/utils/getCanBeCollapsedFolderIds'; import getCanBeCollapsedFolderIds from '../models/utils/getCanBeCollapsedFolderIds';
import Setting from '../models/Setting';
export const declaration: CommandDeclaration = { export const declaration: CommandDeclaration = {
name: 'toggleAllFolders', name: 'toggleAllFolders',
@@ -10,6 +11,10 @@ export const declaration: CommandDeclaration = {
export const runtime = (): CommandRuntime => { export const runtime = (): CommandRuntime => {
return { return {
execute: async (context: CommandContext, collapseAll: boolean) => { execute: async (context: CommandContext, collapseAll: boolean) => {
if (!collapseAll && !Setting.value('folderHeaderIsExpanded')) {
Setting.setValue('folderHeaderIsExpanded', true);
}
context.dispatch({ context.dispatch({
type: 'FOLDER_SET_COLLAPSED', type: 'FOLDER_SET_COLLAPSED',
ids: collapseAll ? getCanBeCollapsedFolderIds(context.state.folders) : [], ids: collapseAll ? getCanBeCollapsedFolderIds(context.state.folders) : [],

View File

@@ -45,5 +45,7 @@ export const runtime = (): CommandRuntime => {
}); });
} }
}, },
enabledCondition: 'hasActivePluginEditor',
}; };
}; };

View File

@@ -1,90 +0,0 @@
const shim = require('./shim').default;
const Promise = require('promise');
class DatabaseDriverNode {
async open(options) {
await this.open_(options);
await this.exec('PRAGMA key = \'mysecret\'');
}
open_(options) {
return new Promise((resolve, reject) => {
const sqlite3 = shim.nodeSqliteCipher().verbose();
this.db_ = new sqlite3.Database(options.name, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, error => {
if (error) {
reject(error);
return;
}
resolve();
});
});
}
sqliteErrorToJsError(error, sql = null, params = null) {
const msg = [error.toString()];
if (sql) msg.push(sql);
if (params) msg.push(params);
const output = new Error(msg.join(': '));
if (error.code) output.code = error.code;
return output;
}
selectOne(sql, params = null) {
if (!params) params = {};
return new Promise((resolve, reject) => {
this.db_.get(sql, params, (error, row) => {
if (error) {
reject(error);
return;
}
resolve(row);
});
});
}
loadExtension(path) {
return new Promise((resolve, reject) => {
this.db_.loadExtension(path, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
selectAll(sql, params = null) {
if (!params) params = {};
return new Promise((resolve, reject) => {
this.db_.all(sql, params, (error, row) => {
if (error) {
reject(error);
return;
}
resolve(row);
});
});
}
exec(sql, params = null) {
if (!params) params = {};
return new Promise((resolve, reject) => {
this.db_.run(sql, params, error => {
if (error) {
reject(error);
return;
}
resolve();
});
});
}
lastInsertId() {
throw new Error('NOT IMPLEMENTED');
}
}
module.exports = { DatabaseDriverNode };

View File

@@ -1,7 +1,7 @@
import { homedir } from 'os'; import { homedir } from 'os';
import { toSystemSlashes } from './path-utils'; import { toSystemSlashes } from './path-utils';
export default (profileFromArgs: string, appName: string) => { export default (profileFromArgs: string, appName: string, isAltInstance: boolean) => {
let profileDir = ''; let profileDir = '';
let homeDir = ''; let homeDir = '';
@@ -12,7 +12,8 @@ export default (profileFromArgs: string, appName: string) => {
profileDir = `${process.env.PORTABLE_EXECUTABLE_DIR}/JoplinProfile`; profileDir = `${process.env.PORTABLE_EXECUTABLE_DIR}/JoplinProfile`;
homeDir = process.env.PORTABLE_EXECUTABLE_DIR; homeDir = process.env.PORTABLE_EXECUTABLE_DIR;
} else { } else {
profileDir = `${homedir()}/.config/${appName}`; const suffix = isAltInstance ? '-alt' : '';
profileDir = `${homedir()}/.config/${appName}${suffix}`;
homeDir = homedir(); homeDir = homedir();
} }

View File

@@ -2,7 +2,6 @@ const { afterEachCleanUp } = require('./testing/test-utils.js');
const { shimInit } = require('./shim-init-node.js'); const { shimInit } = require('./shim-init-node.js');
const sharp = require('sharp'); const sharp = require('sharp');
const nodeSqlite = require('sqlite3'); const nodeSqlite = require('sqlite3');
const nodeSqliteCipher = require('@journeyapps/sqlcipher');
const pdfJs = require('pdfjs-dist'); const pdfJs = require('pdfjs-dist');
const packageInfo = require('./package.json'); const packageInfo = require('./package.json');
@@ -11,7 +10,7 @@ const React = require('react');
require('../../jest.base-setup.js')(); require('../../jest.base-setup.js')();
shimInit({ sharp, nodeSqlite, nodeSqliteCipher, pdfJs, React, appVersion: () => packageInfo.version }); shimInit({ sharp, nodeSqlite, pdfJs, React, appVersion: () => packageInfo.version });
global.afterEach(async () => { global.afterEach(async () => {
await afterEachCleanUp(); await afterEachCleanUp();

View File

@@ -1,5 +1,5 @@
const time = require('../time').default; const time = require('../time').default;
const { setupDatabaseAndSynchronizer, switchClient } = require('../testing/test-utils.js'); const { setupDatabaseAndSynchronizer, switchClient, msleep } = require('../testing/test-utils.js');
const Folder = require('../models/Folder').default; const Folder = require('../models/Folder').default;
const Note = require('../models/Note').default; const Note = require('../models/Note').default;
@@ -95,6 +95,8 @@ describe('models/Note_CustomSortOrder', () => {
const timeBefore = time.unixMs(); const timeBefore = time.unixMs();
await msleep(10);
await Note.insertNotesAt(folder1.id, [note2.id], 0); await Note.insertNotesAt(folder1.id, [note2.id], 0);
await Note.insertNotesAt(folder1.id, [note1.id], 1); await Note.insertNotesAt(folder1.id, [note1.id], 1);

View File

@@ -91,8 +91,7 @@ interface SettingSections {
interface DefaultMigration { interface DefaultMigration {
name: string; name: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied previousDefault: string | boolean | number;
previousDefault: any;
} }
// To create a default migration: // To create a default migration:
@@ -117,6 +116,10 @@ const defaultMigrations: DefaultMigration[] = [
name: 'themeAutoDetect', name: 'themeAutoDetect',
previousDefault: false, previousDefault: false,
}, },
{
name: 'ocr.enabled',
previousDefault: false,
},
]; ];
// "UserSettingMigration" are used to migrate existing user setting to a new setting. With a way // "UserSettingMigration" are used to migrate existing user setting to a new setting. With a way

View File

@@ -62,6 +62,16 @@ const builtInMetadata = (Setting: typeof SettingType) => {
type: SettingItemType.String, type: SettingItemType.String,
public: false, public: false,
}, },
'isAltInstance': {
value: false,
type: SettingItemType.Bool,
public: false,
appTypes: [AppType.Desktop],
storage: SettingStorage.File,
isGlobal: true,
},
'editor.codeView': { 'editor.codeView': {
value: true, value: true,
type: SettingItemType.Bool, type: SettingItemType.Bool,

View File

@@ -52,7 +52,6 @@
"@joplin/turndown": "^4.0.79", "@joplin/turndown": "^4.0.79",
"@joplin/turndown-plugin-gfm": "^1.0.61", "@joplin/turndown-plugin-gfm": "^1.0.61",
"@joplin/utils": "~3.3", "@joplin/utils": "~3.3",
"@journeyapps/sqlcipher": "5.3.1",
"@types/nanoid": "3.0.0", "@types/nanoid": "3.0.0",
"adm-zip": "0.5.16", "adm-zip": "0.5.16",
"async-mutex": "0.5.0", "async-mutex": "0.5.0",

View File

@@ -42,6 +42,7 @@ const defaultKeymapItems = {
{ accelerator: 'Option+Cmd+S', command: 'toggleSideBar' }, { accelerator: 'Option+Cmd+S', command: 'toggleSideBar' },
{ accelerator: 'Option+Cmd+L', command: 'toggleNoteList' }, { accelerator: 'Option+Cmd+L', command: 'toggleNoteList' },
{ accelerator: 'Cmd+L', command: 'toggleVisiblePanes' }, { accelerator: 'Cmd+L', command: 'toggleVisiblePanes' },
{ accelerator: 'Option+Cmd+V', command: 'toggleEditorPlugin' },
{ accelerator: 'Cmd+0', command: 'zoomActualSize' }, { accelerator: 'Cmd+0', command: 'zoomActualSize' },
{ accelerator: 'Cmd+E', command: 'toggleExternalEditing' }, { accelerator: 'Cmd+E', command: 'toggleExternalEditing' },
{ accelerator: 'Option+Cmd+T', command: 'setTags' }, { accelerator: 'Option+Cmd+T', command: 'setTags' },
@@ -93,6 +94,7 @@ const defaultKeymapItems = {
{ accelerator: 'Ctrl+Shift+M', command: 'toggleMenuBar' }, { accelerator: 'Ctrl+Shift+M', command: 'toggleMenuBar' },
{ accelerator: 'F11', command: 'toggleNoteList' }, { accelerator: 'F11', command: 'toggleNoteList' },
{ accelerator: 'Ctrl+L', command: 'toggleVisiblePanes' }, { accelerator: 'Ctrl+L', command: 'toggleVisiblePanes' },
{ accelerator: 'Alt+Ctrl+V', command: 'toggleEditorPlugin' },
{ accelerator: 'Ctrl+0', command: 'zoomActualSize' }, { accelerator: 'Ctrl+0', command: 'zoomActualSize' },
{ accelerator: 'Ctrl+E', command: 'toggleExternalEditing' }, { accelerator: 'Ctrl+E', command: 'toggleExternalEditing' },
{ accelerator: 'Ctrl+Alt+T', command: 'setTags' }, { accelerator: 'Ctrl+Alt+T', command: 'setTags' },

View File

@@ -7,6 +7,7 @@ import { FolderEntity, NoteEntity } from '../database/types';
import { itemIsReadOnlySync, ItemSlice } from '../../models/utils/readOnly'; import { itemIsReadOnlySync, ItemSlice } from '../../models/utils/readOnly';
import ItemChange from '../../models/ItemChange'; import ItemChange from '../../models/ItemChange';
import { getTrashFolderId } from '../trash'; import { getTrashFolderId } from '../trash';
import getActivePluginEditorView from '../plugins/utils/getActivePluginEditorView';
export interface WhenClauseContextOptions { export interface WhenClauseContextOptions {
commandFolderId?: string; commandFolderId?: string;
@@ -43,6 +44,7 @@ export interface WhenClauseContext {
oneNoteSelected: boolean; oneNoteSelected: boolean;
someNotesSelected: boolean; someNotesSelected: boolean;
syncStarted: boolean; syncStarted: boolean;
hasActivePluginEditor: boolean;
} }
export default function stateToWhenClauseContext(state: State, options: WhenClauseContextOptions = null): WhenClauseContext { export default function stateToWhenClauseContext(state: State, options: WhenClauseContextOptions = null): WhenClauseContext {
@@ -61,6 +63,8 @@ export default function stateToWhenClauseContext(state: State, options: WhenClau
const commandFolderId = options.commandFolderId || windowState.selectedFolderId; const commandFolderId = options.commandFolderId || windowState.selectedFolderId;
const commandFolder: FolderEntity = commandFolderId ? BaseModel.byId(state.folders, commandFolderId) : null; const commandFolder: FolderEntity = commandFolderId ? BaseModel.byId(state.folders, commandFolderId) : null;
const { editorPlugin } = state.pluginService ? getActivePluginEditorView(state.pluginService.plugins) : { editorPlugin: null };
const settings = state.settings || {}; const settings = state.settings || {};
return { return {
@@ -108,5 +112,7 @@ export default function stateToWhenClauseContext(state: State, options: WhenClau
joplinServerConnected: [9, 10].includes(settings['sync.target']), joplinServerConnected: [9, 10].includes(settings['sync.target']),
joplinCloudAccountType: settings['sync.target'] === 10 ? settings['sync.10.accountType'] : 0, joplinCloudAccountType: settings['sync.target'] === 10 ? settings['sync.10.accountType'] : 0,
hasMultiProfiles: state.profileConfig && state.profileConfig.profiles.length > 1, hasMultiProfiles: state.profileConfig && state.profileConfig.profiles.length > 1,
hasActivePluginEditor: !!editorPlugin,
}; };
} }

View File

@@ -329,6 +329,7 @@ export default class ShareService {
let recipientMasterKey: MasterKeyEntity = null; let recipientMasterKey: MasterKeyEntity = null;
if (getEncryptionEnabled()) { if (getEncryptionEnabled()) {
if (!recipientEmail) throw new Error(_('Please provide the recipient email'));
const syncInfo = localSyncInfo(); const syncInfo = localSyncInfo();
const masterKey = syncInfo.masterKeys.find(m => m.id === masterKeyId); const masterKey = syncInfo.masterKeys.find(m => m.id === masterKeyId);
if (!masterKey) throw new Error(`Cannot find master key with ID "${masterKeyId}"`); if (!masterKey) throw new Error(`Cannot find master key with ID "${masterKeyId}"`);

View File

@@ -1,7 +1,7 @@
const { shimInit } = require('./shim-init-node'); const { shimInit } = require('./shim-init-node');
import shim from './shim'; import shim from './shim';
import { setupDatabaseAndSynchronizer, supportDir } from './testing/test-utils'; import { createTempDir, setupDatabaseAndSynchronizer, supportDir } from './testing/test-utils';
import { copyFile } from 'fs-extra'; import { copyFile } from 'fs-extra';
describe('shim-init-node', () => { describe('shim-init-node', () => {
@@ -19,8 +19,11 @@ describe('shim-init-node', () => {
}); });
test('should preserve the file extension if one is provided regardless of the mime type', async () => { test('should preserve the file extension if one is provided regardless of the mime type', async () => {
const tempDir = await createTempDir();
const originalFilePath = `${supportDir}/valid_pdf_without_ext`; const originalFilePath = `${supportDir}/valid_pdf_without_ext`;
const fileWithDifferentExtension = `${originalFilePath}.mscz`; const fileWithDifferentExtension = `${tempDir}/valid_pdf.mscz`;
await copyFile(originalFilePath, fileWithDifferentExtension); await copyFile(originalFilePath, fileWithDifferentExtension);
const resource = await shim.createResourceFromPath(fileWithDifferentExtension); const resource = await shim.createResourceFromPath(fileWithDifferentExtension);

View File

@@ -110,8 +110,6 @@ interface ShimInitOptions {
electronBridge: any; electronBridge: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
nodeSqlite: any; nodeSqlite: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
nodeSqliteCipher: any;
pdfJs: typeof pdfJsNamespace; pdfJs: typeof pdfJsNamespace;
} }
@@ -124,7 +122,6 @@ function shimInit(options: ShimInitOptions = null) {
electronBridge: null, electronBridge: null,
nodeSqlite: null, nodeSqlite: null,
pdfJs: null, pdfJs: null,
nodeSqliteCipher: null,
...options, ...options,
}; };
@@ -134,7 +131,6 @@ function shimInit(options: ShimInitOptions = null) {
const pdfJs = options.pdfJs; const pdfJs = options.pdfJs;
shim.setNodeSqlite(options.nodeSqlite); shim.setNodeSqlite(options.nodeSqlite);
shim.setNodeSqliteCipher(options.nodeSqliteCipher);
shim.fsDriver = () => { shim.fsDriver = () => {
throw new Error('Not implemented'); throw new Error('Not implemented');

View File

@@ -76,8 +76,6 @@ let isTestingEnv_ = false;
let react_: typeof React = null; let react_: typeof React = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
let nodeSqlite_: any = null; let nodeSqlite_: any = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
let nodeSqliteCipher_: any = null;
const shim = { const shim = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
@@ -482,21 +480,11 @@ const shim = {
nodeSqlite_ = nodeSqlite; nodeSqlite_ = nodeSqlite;
}, },
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
setNodeSqliteCipher: (nodeSqlite: any) => {
nodeSqliteCipher_ = nodeSqlite;
},
nodeSqlite: () => { nodeSqlite: () => {
if (!nodeSqlite_) throw new Error('Trying to access nodeSqlite before it has been set!!!'); if (!nodeSqlite_) throw new Error('Trying to access nodeSqlite before it has been set!!!');
return nodeSqlite_; return nodeSqlite_;
}, },
nodeSqliteCipher: () => {
if (!nodeSqliteCipher_) throw new Error('Trying to access nodeSqliteCipher before it has been set!!!');
return nodeSqliteCipher_;
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
setReact: (react: any) => { setReact: (react: any) => {
react_ = react; react_ = react;

View File

@@ -18,7 +18,7 @@ import OneDriveApi from '../onedrive-api';
import SyncTargetOneDrive from '../SyncTargetOneDrive'; import SyncTargetOneDrive from '../SyncTargetOneDrive';
import JoplinDatabase from '../JoplinDatabase'; import JoplinDatabase from '../JoplinDatabase';
import * as fs from 'fs-extra'; import * as fs from 'fs-extra';
const { DatabaseDriverNode } = require('../database-driver-node-sqlcipher.js'); const { DatabaseDriverNode } = require('../database-driver-node.js');
import Folder from '../models/Folder'; import Folder from '../models/Folder';
import Note from '../models/Note'; import Note from '../models/Note';
import ItemChange from '../models/ItemChange'; import ItemChange from '../models/ItemChange';

View File

@@ -52,6 +52,7 @@ const globalStyle = (() => {
mainPadding: 12, mainPadding: 12,
topRowHeight: 50, topRowHeight: 50,
editorPaddingLeft: 8, editorPaddingLeft: 8,
listTabSize: '1.7em',
margin: margin, margin: margin,
marginRight: margin, marginRight: margin,

View File

@@ -13,6 +13,7 @@ export interface MatchedStartFlags {
logLevel?: LogLevel; logLevel?: LogLevel;
allowOverridingDnsResultOrder?: boolean; allowOverridingDnsResultOrder?: boolean;
devPlugins?: string[]; devPlugins?: string[];
isAltInstance?: boolean;
} }
// Handles the initial flags passed to main script and // Handles the initial flags passed to main script and
@@ -181,6 +182,12 @@ const processStartFlags = async (argv: string[], setDefaults = true) => {
continue; continue;
} }
if (arg === '--is-alt-instance') {
matched.isAltInstance = true;
argv.splice(0, 1);
continue;
}
if (arg.length && arg[0] === '-') { if (arg.length && arg[0] === '-') {
throw new JoplinError(_('Unknown flag: %s', arg), 'flagError'); throw new JoplinError(_('Unknown flag: %s', arg), 'flagError');
} else { } else {

View File

@@ -89,6 +89,7 @@ export default function versionInfo(packageInfo: PackageInfo, plugins: Plugins)
_('Sync Version: %s', Setting.value('syncVersion')), _('Sync Version: %s', Setting.value('syncVersion')),
_('Profile Version: %s', reg.db().version()), _('Profile Version: %s', reg.db().version()),
_('Keychain Supported: %s', keychainSupported ? _('Yes') : _('No')), _('Keychain Supported: %s', keychainSupported ? _('Yes') : _('No')),
_('Is alternative instance: %s', Setting.value('isAltInstance') ? _('Yes') : _('No')),
]; ];
if (gitInfo) { if (gitInfo) {

View File

@@ -216,7 +216,7 @@ export default function(theme: any, options: Options = null) {
} }
ul, ol { ul, ol {
padding-left: 0; padding-left: 0;
margin-left: 1.7em; margin-left: ${theme.listTabSize};
} }
li { li {
margin-bottom: .4em; margin-bottom: .4em;

View File

@@ -1,6 +1,6 @@
{ {
"name": "@joplin/server", "name": "@joplin/server",
"version": "3.3.3", "version": "3.3.4",
"private": true, "private": true,
"scripts": { "scripts": {
"start-dev": "yarn build && JOPLIN_IS_TESTING=1 nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev", "start-dev": "yarn build && JOPLIN_IS_TESTING=1 nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev",

View File

@@ -1,5 +1,6 @@
import { basename } from '@joplin/utils/path';
import { Item } from '../services/database/types'; import { Item } from '../services/database/types';
import { itemIsEncrypted } from './joplinUtils'; import { itemIsEncrypted, localFileFromUrl } from './joplinUtils';
import { expectThrow } from './testing/testUtils'; import { expectThrow } from './testing/testUtils';
describe('joplinUtils', () => { describe('joplinUtils', () => {
@@ -21,4 +22,21 @@ describe('joplinUtils', () => {
await expectThrow(async () => itemIsEncrypted({ name: 'missing props' })); await expectThrow(async () => itemIsEncrypted({ name: 'missing props' }));
}); });
it.each([
'css/pluginAssets/../../../test',
'css/pluginAssets/../../test',
'js/pluginAssets/./../../test',
])('localFileFromUrl should prevent access to paths outside the assets directory', async (url) => {
await expect(localFileFromUrl(url)).rejects.toThrow('Disallowed access:');
});
it.each([
'css/pluginAssets/test.css',
'js/pluginAssets/subfolder/test.js',
'css/pluginAssets/testing/this-is-a-test.css',
])('localFileFromUrl should allow access to paths inside the assets directory', async (url) => {
const resolvedPath = await localFileFromUrl(url);
// Should resolve to the same file
expect(basename(resolvedPath)).toBe(basename(url));
});
}); });

View File

@@ -26,6 +26,7 @@ import MustacheService from '../services/MustacheService';
import Logger from '@joplin/utils/Logger'; import Logger from '@joplin/utils/Logger';
import config from '../config'; import config from '../config';
import { TreeItem } from '../models/ItemResourceModel'; import { TreeItem } from '../models/ItemResourceModel';
import resolvePathWithinDir from '@joplin/lib/utils/resolvePathWithinDir';
const { substrWithEllipsis } = require('@joplin/lib/string-utils'); const { substrWithEllipsis } = require('@joplin/lib/string-utils');
const logger = Logger.create('JoplinUtils'); const logger = Logger.create('JoplinUtils');
@@ -116,11 +117,26 @@ export function isJoplinResourceBlobPath(path: string): boolean {
return path.indexOf(resourceDirName) === 0; return path.indexOf(resourceDirName) === 0;
} }
export async function localFileFromUrl(url: string): Promise<string> { const resolveUnsafeAssetPath = (relativeAssetPath: string) => {
const resolvedPath = resolvePathWithinDir(pluginAssetRootDir_, relativeAssetPath);
if (resolvedPath === null) {
throw new ErrorForbidden('Disallowed access: Item is not in the plugin asset directory');
}
return resolvedPath;
};
export async function localFileFromUrl(urlPath: string): Promise<string> {
const cssPluginAssets = 'css/pluginAssets/'; const cssPluginAssets = 'css/pluginAssets/';
const jsPluginAssets = 'js/pluginAssets/'; const jsPluginAssets = 'js/pluginAssets/';
if (url.indexOf(cssPluginAssets) === 0) return `${pluginAssetRootDir_}/${url.substr(cssPluginAssets.length)}`; const baseUrls = [cssPluginAssets, jsPluginAssets];
if (url.indexOf(jsPluginAssets) === 0) return `${pluginAssetRootDir_}/${url.substr(jsPluginAssets.length)}`;
for (const baseUrl of baseUrls) {
if (urlPath.startsWith(baseUrl)) {
const pluginAssetPath = urlPath.substring(baseUrl.length);
return resolveUnsafeAssetPath(pluginAssetPath);
}
}
return null; return null;
} }

View File

@@ -172,5 +172,4 @@ sideloading
ggml ggml
Minidump Minidump
collapseall collapseall
newfolder newfolder
sqlcipher

File diff suppressed because it is too large Load Diff

View File

@@ -6,9 +6,11 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Joplin-CLI 1.0.0\n" "Project-Id-Version: Joplin-CLI 3.2.13\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"Last-Translator: Dmitriy Q <atsip-help@yandex.ru>\n" "POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: Dmitriy Q <krotesk@yandex.ru>\n"
"Language-Team: Sergey Segeda <thesermanarm@gmail.com>\n" "Language-Team: Sergey Segeda <thesermanarm@gmail.com>\n"
"Language: ru_RU\n" "Language: ru_RU\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -16,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 3.4.2\n" "X-Generator: Poedit 3.5\n"
#: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:593 #: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:593
msgid "- Camera: to allow taking a picture and attaching it to a note." msgid "- Camera: to allow taking a picture and attaching it to a note."
@@ -50,7 +52,7 @@ msgstr "(В плагине: %s)"
#: packages/app-mobile/components/side-menu-content.tsx:265 #: packages/app-mobile/components/side-menu-content.tsx:265
msgid "(level %d)" msgid "(level %d)"
msgstr "" msgstr "(уровень %d)"
#: packages/lib/SyncTargetNone.ts:16 #: packages/lib/SyncTargetNone.ts:16
msgid "(None)" msgid "(None)"
@@ -264,9 +266,8 @@ msgstr ""
"\"clear\" преобразует выбранную задачу в обычную заметку." "\"clear\" преобразует выбранную задачу в обычную заметку."
#: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:62 #: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:62
#, fuzzy
msgid "A new update (%s) is available" msgid "A new update (%s) is available"
msgstr "Доступно обновление" msgstr "Доступно новое (%s) обновление"
#: packages/lib/models/settings/builtInMetadata.ts:1253 #: packages/lib/models/settings/builtInMetadata.ts:1253
msgid "A3" msgid "A3"
@@ -375,7 +376,7 @@ msgstr "Добавить получателя:"
#: packages/app-mobile/components/screens/NoteTagsDialog.tsx:94 #: packages/app-mobile/components/screens/NoteTagsDialog.tsx:94
msgid "Add tag %s to note" msgid "Add tag %s to note"
msgstr "" msgstr "Добавить тег %s к заметке"
#: packages/app-mobile/components/screens/Note/Note.tsx:1574 #: packages/app-mobile/components/screens/Note/Note.tsx:1574
msgid "Add title" msgid "Add title"
@@ -386,9 +387,9 @@ msgid "Add to dictionary"
msgstr "Добавить в словарь" msgstr "Добавить в словарь"
#: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:98 #: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:98
#, fuzzy
msgid "Add to note" msgid "Add to note"
msgstr "Добавить заголовок" msgstr "Добавить к заметке"
#: packages/server/src/services/MustacheService.ts:162 #: packages/server/src/services/MustacheService.ts:162
#: packages/server/src/services/MustacheService.ts:286 #: packages/server/src/services/MustacheService.ts:286
@@ -412,9 +413,8 @@ msgid "Advanced tools"
msgstr "Расширенные инструменты" msgstr "Расширенные инструменты"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:18 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:18
#, fuzzy
msgid "all" msgid "all"
msgstr "Установить" msgstr "все"
#: packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx:109 #: packages/app-mobile/components/ProfileSwitcher/ProfileSwitcher.tsx:109
msgid "" msgid ""
@@ -521,13 +521,13 @@ msgid "Apply"
msgstr "Применить" msgstr "Применить"
#: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:146 #: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:146
#, fuzzy
msgid "" msgid ""
"Are you sure that you want to restore the default toolbar layout?\n" "Are you sure that you want to restore the default toolbar layout?\n"
"This cannot be undone." "This cannot be undone."
msgstr "" msgstr ""
"Вы уверены, что хотите вернуться к макету по умолчанию? Текущая конфигурация " "Вы уверены, что хотите восстановить расположение панели инструментов по "
"макета будет потеряна." "умолчанию?\n"
"Это нельзя отменить."
#: packages/app-desktop/gui/ClipperConfigScreen.tsx:38 #: packages/app-desktop/gui/ClipperConfigScreen.tsx:38
msgid "Are you sure you want to renew the authorisation token?" msgid "Are you sure you want to renew the authorisation token?"
@@ -554,6 +554,8 @@ msgid ""
"At present, Joplin Web can only be open in one tab at a time. Please close " "At present, Joplin Web can only be open in one tab at a time. Please close "
"the other instance of Joplin." "the other instance of Joplin."
msgstr "" msgstr ""
"В настоящее время Joplin Web может быть одновременно открыт только в одной "
"вкладке. Пожалуйста, закройте другую вкладку Joplin."
#: packages/app-mobile/components/NoteEditor/ImageEditor/promptRestoreAutosave.ts:25 #: packages/app-mobile/components/NoteEditor/ImageEditor/promptRestoreAutosave.ts:25
msgid "Attach" msgid "Attach"
@@ -640,7 +642,7 @@ msgstr "Автоматическое закрытие скобок, кавыче
#: packages/lib/models/settings/builtInMetadata.ts:656 #: packages/lib/models/settings/builtInMetadata.ts:656
msgid "Autocomplete Markdown and HTML" msgid "Autocomplete Markdown and HTML"
msgstr "" msgstr "Автозавершение Markdown и HTML"
#: packages/lib/models/settings/builtInMetadata.ts:1198 #: packages/lib/models/settings/builtInMetadata.ts:1198
msgid "Automatically check for updates" msgid "Automatically check for updates"
@@ -704,7 +706,7 @@ msgstr "к %s"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:20 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:20
msgid "by word" msgid "by word"
msgstr "" msgstr "словом"
#: packages/server/src/routes/admin/users.ts:160 #: packages/server/src/routes/admin/users.ts:160
msgid "Can Share" msgid "Can Share"
@@ -877,13 +879,12 @@ msgid "Change language"
msgstr "Изменить язык" msgstr "Изменить язык"
#: packages/app-mobile/components/CameraView/ActionButtons.tsx:124 #: packages/app-mobile/components/CameraView/ActionButtons.tsx:124
#, fuzzy
msgid "Change ratio" msgid "Change ratio"
msgstr "Конфигурация" msgstr "Коэффициент изменений"
#: packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx:98 #: packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx:98
msgid "Change shortcut for \"%s\"" msgid "Change shortcut for \"%s\""
msgstr "" msgstr "Изменить ярлык для \"%s\""
#: packages/app-desktop/gui/NoteContentPropertiesDialog.tsx:106 #: packages/app-desktop/gui/NoteContentPropertiesDialog.tsx:106
msgid "Characters" msgid "Characters"
@@ -895,7 +896,7 @@ msgstr "Символы за исключением пробелов"
#: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:168 #: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:168
msgid "Check elements to display in the toolbar" msgid "Check elements to display in the toolbar"
msgstr "" msgstr "Отметьте элементы для отображения на панели инструментов"
#: packages/app-desktop/gui/MenuBar.tsx:634 #: packages/app-desktop/gui/MenuBar.tsx:634
#: packages/app-desktop/gui/MenuBar.tsx:929 #: packages/app-desktop/gui/MenuBar.tsx:929
@@ -960,9 +961,8 @@ msgid "Client ID: %s"
msgstr "Идентификатор клиента: %s" msgstr "Идентификатор клиента: %s"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:23 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:23
#, fuzzy
msgid "close" msgid "close"
msgstr "Закрыть" msgstr "закрыть"
#: packages/app-desktop/gui/MenuBar.tsx:359 #: packages/app-desktop/gui/MenuBar.tsx:359
#: packages/app-desktop/gui/NoteContentPropertiesDialog.tsx:175 #: packages/app-desktop/gui/NoteContentPropertiesDialog.tsx:175
@@ -982,13 +982,12 @@ msgid "Close dropdown"
msgstr "Закрыть выпадающий список" msgstr "Закрыть выпадающий список"
#: packages/app-mobile/components/accessibility/AccessibleModalMenu.tsx:46 #: packages/app-mobile/components/accessibility/AccessibleModalMenu.tsx:46
#, fuzzy
msgid "Close menu" msgid "Close menu"
msgstr "Закрыть" msgstr "Закрыть меню"
#: packages/app-mobile/components/SideMenu.tsx:300 #: packages/app-mobile/components/SideMenu.tsx:300
msgid "Close side menu" msgid "Close side menu"
msgstr "" msgstr "Закрыть боковое меню"
#: packages/lib/models/settings/settingValidations.ts:33 #: packages/lib/models/settings/settingValidations.ts:33
msgid "" msgid ""
@@ -1036,7 +1035,7 @@ msgstr "Совместная работа над блокнотами с дру
#: packages/app-desktop/gui/Sidebar/listItemComponents/ExpandIcon.tsx:28 #: packages/app-desktop/gui/Sidebar/listItemComponents/ExpandIcon.tsx:28
msgid "Collapsed, press space to expand." msgid "Collapsed, press space to expand."
msgstr "" msgstr "Свернуто, нажмите пробел чтобы развернуть."
#: packages/lib/services/ReportService.ts:351 #: packages/lib/services/ReportService.ts:351
msgid "Coming alarms" msgid "Coming alarms"
@@ -1076,14 +1075,12 @@ msgid "Compact"
msgstr "Компактный" msgstr "Компактный"
#: packages/app-desktop/gui/NoteList/utils/useOnKeyDown.ts:153 #: packages/app-desktop/gui/NoteList/utils/useOnKeyDown.ts:153
#, fuzzy
msgid "Complete" msgid "Complete"
msgstr "Завершено" msgstr "Завершенные"
#: packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.ts:40 #: packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.ts:40
#, fuzzy
msgid "Complete to-do" msgid "Complete to-do"
msgstr "Завершено" msgstr "Завершенные дела"
#: packages/app-desktop/gui/NoteListHeader/utils/getColumnTitle.ts:12 #: packages/app-desktop/gui/NoteListHeader/utils/getColumnTitle.ts:12
#: packages/app-desktop/gui/NotePropertiesDialog.tsx:70 #: packages/app-desktop/gui/NotePropertiesDialog.tsx:70
@@ -1156,12 +1153,11 @@ msgid "Consolidated billing"
msgstr "Консолидированный биллинг" msgstr "Консолидированный биллинг"
#: packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.tsx:11 #: packages/app-desktop/gui/Sidebar/listItemComponents/NoteCount.tsx:11
#, fuzzy
msgid "Contains %d note" msgid "Contains %d note"
msgid_plural "Contains %d notes" msgid_plural "Contains %d notes"
msgstr[0] "Преобразовать в заметку" msgstr[0] "Содержит %d заметку"
msgstr[1] "Преобразовать в заметку" msgstr[1] "Содержит %d заметки"
msgstr[2] "Преобразовать в заметку" msgstr[2] "Содержит %d заметок"
#: packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.tsx:106 #: packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.tsx:106
msgid "Content provided by %s" msgid "Content provided by %s"
@@ -1176,9 +1172,8 @@ msgid "Continue"
msgstr "Продолжить" msgstr "Продолжить"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:6 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:6
#, fuzzy
msgid "Control character" msgid "Control character"
msgstr "Символы" msgstr "Управляющий символ"
#: packages/app-mobile/components/screens/Note/Note.tsx:1221 #: packages/app-mobile/components/screens/Note/Note.tsx:1221
msgid "Convert to note" msgid "Convert to note"
@@ -1415,14 +1410,12 @@ msgid "Ctrl-click to open: %s"
msgstr "Нажмите Ctrl для открытия: %s" msgstr "Нажмите Ctrl для открытия: %s"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:24 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:24
#, fuzzy
msgid "current match" msgid "current match"
msgstr "Следующее совпадение" msgstr "текущее совпадение"
#: packages/app-desktop/gui/MasterPasswordDialog/Dialog.tsx:153 #: packages/app-desktop/gui/MasterPasswordDialog/Dialog.tsx:153
#, fuzzy
msgid "Current password" msgid "Current password"
msgstr "Введите пароль" msgstr "Текущий пароль"
#: packages/app-desktop/checkForUpdates.ts:90 #: packages/app-desktop/checkForUpdates.ts:90
msgid "Current version is up-to-date." msgid "Current version is up-to-date."
@@ -1544,6 +1537,8 @@ msgid ""
"Delete model and re-download?\n" "Delete model and re-download?\n"
"This cannot be undone." "This cannot be undone."
msgstr "" msgstr ""
"Удалить модель и перезагрузить?\n"
"Это невозможно отменить."
#: packages/lib/commands/deleteNote.ts:7 #: packages/lib/commands/deleteNote.ts:7
msgid "Delete note" msgid "Delete note"
@@ -1624,14 +1619,12 @@ msgid "Deletes the notes without asking for confirmation."
msgstr "Удаляет заметки без запроса подтверждения." msgstr "Удаляет заметки без запроса подтверждения."
#: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:551 #: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:551
#, fuzzy
msgid "Deletion log" msgid "Deletion log"
msgstr "Удалить строку" msgstr "Журнал удаления"
#: packages/app-mobile/components/NoteItem.tsx:144 #: packages/app-mobile/components/NoteItem.tsx:144
#, fuzzy
msgid "Deselect" msgid "Deselect"
msgstr "Выбрать" msgstr "Отменить выбор"
#: packages/app-cli/app/command-export.ts:24 #: packages/app-cli/app/command-export.ts:24
msgid "Destination format: %s" msgid "Destination format: %s"
@@ -1643,9 +1636,8 @@ msgid "Detailed"
msgstr "Подробный" msgstr "Подробный"
#: packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginChips.tsx:99 #: packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/PluginChips.tsx:99
#, fuzzy
msgid "Dev" msgid "Dev"
msgstr "Due" msgstr "Разр"
#: packages/lib/services/interop/Module.ts:62 #: packages/lib/services/interop/Module.ts:62
msgid "Directory" msgid "Directory"
@@ -1682,9 +1674,8 @@ msgid "Disabled"
msgstr "Отключено" msgstr "Отключено"
#: packages/app-mobile/components/screens/encryption-config.tsx:323 #: packages/app-mobile/components/screens/encryption-config.tsx:323
#, fuzzy
msgid "Disabled keys" msgid "Disabled keys"
msgstr "Скрыть отключенные ключи" msgstr "Отключенные клавиши"
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:200 #: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:200
#: packages/app-mobile/components/screens/encryption-config.tsx:251 #: packages/app-mobile/components/screens/encryption-config.tsx:251
@@ -1795,9 +1786,8 @@ msgid "Download and install the relevant extension for your browser:"
msgstr "Скачайте и установите расширение для вашего браузера:" msgstr "Скачайте и установите расширение для вашего браузера:"
#: packages/app-mobile/components/voiceTyping/VoiceTypingDialog.tsx:206 #: packages/app-mobile/components/voiceTyping/VoiceTypingDialog.tsx:206
#, fuzzy
msgid "Download updated model" msgid "Download updated model"
msgstr "Загружено" msgstr "Скачать обновленную модель"
#: packages/lib/models/Resource.ts:409 #: packages/lib/models/Resource.ts:409
msgid "Downloaded" msgid "Downloaded"
@@ -1894,12 +1884,11 @@ msgstr "Редактировать во внешнем редакторе"
#: packages/app-desktop/commands/openNoteInNewWindow.ts:10 #: packages/app-desktop/commands/openNoteInNewWindow.ts:10
msgid "Edit in new window" msgid "Edit in new window"
msgstr "" msgstr "Редактировать в новом окне"
#: packages/app-desktop/gui/utils/NoteListUtils.ts:70 #: packages/app-desktop/gui/utils/NoteListUtils.ts:70
#, fuzzy
msgid "Edit in..." msgid "Edit in..."
msgstr "Редактирование ссылки" msgstr "Редактировать в..."
#: packages/app-mobile/components/NoteEditor/EditLinkDialog.tsx:143 #: packages/app-mobile/components/NoteEditor/EditLinkDialog.tsx:143
msgid "Edit link" msgid "Edit link"
@@ -1930,9 +1919,8 @@ msgid "Editor"
msgstr "Редактор" msgstr "Редактор"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.tsx:38 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/Toolbar.tsx:38
#, fuzzy
msgid "Editor actions" msgid "Editor actions"
msgstr "Шрифт редактора" msgstr "Действия редактора"
#: packages/lib/models/settings/builtInMetadata.ts:1074 #: packages/lib/models/settings/builtInMetadata.ts:1074
msgid "Editor font" msgid "Editor font"
@@ -2048,7 +2036,7 @@ msgstr "Включить шифрование"
#: packages/lib/models/settings/builtInMetadata.ts:994 #: packages/lib/models/settings/builtInMetadata.ts:994
msgid "Enable file:// URLs for images and videos" msgid "Enable file:// URLs for images and videos"
msgstr "" msgstr "Включить URL-адреса file:// для изображений и видео"
#: packages/lib/models/settings/builtInMetadata.ts:975 #: packages/lib/models/settings/builtInMetadata.ts:975
msgid "Enable footnotes" msgid "Enable footnotes"
@@ -2104,9 +2092,8 @@ msgid "Enable soft breaks"
msgstr "Включить мягкие отступы" msgstr "Включить мягкие отступы"
#: packages/lib/models/settings/builtInMetadata.ts:1303 #: packages/lib/models/settings/builtInMetadata.ts:1303
#, fuzzy
msgid "Enable spell checking in Markdown editor" msgid "Enable spell checking in Markdown editor"
msgstr "Включить проверку орфографии в текстовом редакторе" msgstr "Включить проверку орфографии в редакторе Markdown"
#: packages/lib/models/settings/builtInMetadata.ts:789 #: packages/lib/models/settings/builtInMetadata.ts:789
msgid "Enable spellcheck in the text editor" msgid "Enable spellcheck in the text editor"
@@ -2145,6 +2132,8 @@ msgid ""
"Enables Markdown list continuation, auto-closing HTML tags, and other markup " "Enables Markdown list continuation, auto-closing HTML tags, and other markup "
"autocompletions." "autocompletions."
msgstr "" msgstr ""
"Включает продолжение списка Markdown, автозакрытие HTML-тегов и другие "
"автодополнения разметки."
#: packages/lib/components/EncryptionConfigScreen/utils.ts:50 #: packages/lib/components/EncryptionConfigScreen/utils.ts:50
msgid "" msgid ""
@@ -2191,9 +2180,8 @@ msgid "End-to-end encryption"
msgstr "Сквозное шифрование" msgstr "Сквозное шифрование"
#: packages/app-mobile/components/voiceTyping/VoiceTypingDialog.tsx:244 #: packages/app-mobile/components/voiceTyping/VoiceTypingDialog.tsx:244
#, fuzzy
msgid "Ends voice typing" msgid "Ends voice typing"
msgstr "Голосовой набор" msgstr "Завершение голосового набора"
#: packages/app-mobile/components/screens/dropbox-login.tsx:70 #: packages/app-mobile/components/screens/dropbox-login.tsx:70
msgid "Enter code here" msgid "Enter code here"
@@ -2213,9 +2201,8 @@ msgid "Enter password"
msgstr "Введите пароль" msgstr "Введите пароль"
#: packages/app-mobile/components/NoteItem.tsx:120 #: packages/app-mobile/components/NoteItem.tsx:120
#, fuzzy
msgid "Entering selection mode" msgid "Entering selection mode"
msgstr "Открытие раздела %s" msgstr "Вход в режим выбора"
#: packages/app-cli/app/help-utils.js:56 #: packages/app-cli/app/help-utils.js:56
msgid "Enum" msgid "Enum"
@@ -2282,7 +2269,7 @@ msgstr "Расширить %s"
#: packages/app-desktop/gui/Sidebar/listItemComponents/ExpandIcon.tsx:26 #: packages/app-desktop/gui/Sidebar/listItemComponents/ExpandIcon.tsx:26
msgid "Expanded, press space to collapse." msgid "Expanded, press space to collapse."
msgstr "" msgstr "Развернуто, нажмите пробел чтобы свернуть."
#: packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx:182 #: packages/app-desktop/gui/KeymapConfig/KeymapConfigScreen.tsx:182
#: packages/app-desktop/gui/Sidebar/hooks/useOnRenderItem.tsx:213 #: packages/app-desktop/gui/Sidebar/hooks/useOnRenderItem.tsx:213
@@ -2308,9 +2295,8 @@ msgid "Export Debug Report"
msgstr "Экспортировать отладочный отчет" msgstr "Экспортировать отладочный отчет"
#: packages/app-desktop/commands/exportDeletionLog.ts:11 #: packages/app-desktop/commands/exportDeletionLog.ts:11
#, fuzzy
msgid "Export deletion log" msgid "Export deletion log"
msgstr "Экспортировать все" msgstr "Экспорт журнала удаления"
#: packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.tsx:16 #: packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.tsx:16
msgid "Export profile" msgid "Export profile"
@@ -2396,9 +2382,8 @@ msgid "Filter tags"
msgstr "Фильтр тегов" msgstr "Фильтр тегов"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:14 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:14
#, fuzzy
msgid "Find" msgid "Find"
msgstr "Найти: " msgstr "Поиск"
#: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:253 #: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:253
msgid "Find: " msgid "Find: "
@@ -2436,7 +2421,7 @@ msgstr "Фокус на названии"
#: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:97 #: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:97
msgid "Follow link" msgid "Follow link"
msgstr "" msgstr "Перейти по ссылке"
#: packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.tsx:38 #: packages/app-mobile/components/screens/ConfigScreen/NoteExportSection/ExportProfileButton.tsx:38
msgid "For debugging purpose only: export your profile to an external SD card." msgid "For debugging purpose only: export your profile to an external SD card."
@@ -2532,11 +2517,11 @@ msgstr ""
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:13 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:13
msgid "go" msgid "go"
msgstr "" msgstr "перейти"
#: packages/app-mobile/components/CameraView/CameraView.tsx:165 #: packages/app-mobile/components/CameraView/CameraView.tsx:165
msgid "Go back" msgid "Go back"
msgstr "" msgstr "Вернуться"
#: packages/app-desktop/gui/JoplinCloudConfigScreen.tsx:44 #: packages/app-desktop/gui/JoplinCloudConfigScreen.tsx:44
#: packages/app-mobile/components/screens/ConfigScreen/JoplinCloudConfig.tsx:59 #: packages/app-mobile/components/screens/ConfigScreen/JoplinCloudConfig.tsx:59
@@ -2545,7 +2530,7 @@ msgstr "Перейти в профиль Joplin Cloud"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:12 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:12
msgid "Go to line" msgid "Go to line"
msgstr "" msgstr "Перейти к строке"
#: packages/app-mobile/components/screens/Note/Note.tsx:1051 #: packages/app-mobile/components/screens/Note/Note.tsx:1051
msgid "Go to source URL" msgid "Go to source URL"
@@ -2612,9 +2597,8 @@ msgid "Hide keyboard"
msgstr "Скрыть клавиатуру" msgstr "Скрыть клавиатуру"
#: packages/app-desktop/gui/PasswordInput/PasswordInput.tsx:21 #: packages/app-desktop/gui/PasswordInput/PasswordInput.tsx:21
#, fuzzy
msgid "Hide password" msgid "Hide password"
msgstr "Неверный пароль" msgstr "Скрыть пароль"
#: packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupToolbarButtons.ts:14 #: packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/utils/setupToolbarButtons.ts:14
msgid "Highlight" msgid "Highlight"
@@ -2833,14 +2817,12 @@ msgid "Incompatible"
msgstr "Несовместимые" msgstr "Несовместимые"
#: packages/app-desktop/gui/NoteList/utils/useOnKeyDown.ts:153 #: packages/app-desktop/gui/NoteList/utils/useOnKeyDown.ts:153
#, fuzzy
msgid "Incomplete" msgid "Incomplete"
msgstr "Завершено" msgstr "Незавершенный"
#: packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.ts:40 #: packages/app-desktop/gui/NoteListItem/utils/prepareViewProps.ts:40
#, fuzzy
msgid "Incomplete to-do" msgid "Incomplete to-do"
msgstr "Показать завершенные задачи" msgstr "Незавершенные задачи"
#: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:97 #: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:97
msgid "Increase indent level" msgid "Increase indent level"
@@ -2856,7 +2838,7 @@ msgstr "Увеличить отступ"
#: packages/app-mobile/components/DialogManager/hooks/useDialogControl.ts:21 #: packages/app-mobile/components/DialogManager/hooks/useDialogControl.ts:21
msgid "Info" msgid "Info"
msgstr "" msgstr "Информация"
#: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:223 #: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:223
msgid "Information" msgid "Information"
@@ -2958,9 +2940,8 @@ msgid "Items that cannot be synchronised"
msgstr "Элементы, которые не могут быть синхронизированы" msgstr "Элементы, которые не могут быть синхронизированы"
#: packages/app-desktop/gui/MenuBar.tsx:923 #: packages/app-desktop/gui/MenuBar.tsx:923
#, fuzzy
msgid "Join us on %s" msgid "Join us on %s"
msgstr "Присоединяйтесь к нам в Twitter" msgstr "Присоединяйтесь к нам в %s"
#: packages/app-desktop/gui/SyncWizard/Dialog.tsx:267 #: packages/app-desktop/gui/SyncWizard/Dialog.tsx:267
msgid "" msgid ""
@@ -3016,9 +2997,8 @@ msgid "Joplin Forum"
msgstr "Форум Joplin" msgstr "Форум Joplin"
#: packages/app-mobile/utils/lockToSingleInstance.ts:16 #: packages/app-mobile/utils/lockToSingleInstance.ts:16
#, fuzzy
msgid "Joplin is already running." msgid "Joplin is already running."
msgstr "Сервер уже запущен. Порт: %d" msgstr "Сервер уже запущен."
#: packages/lib/services/plugins/PluginService.ts:523 #: packages/lib/services/plugins/PluginService.ts:523
msgid "Joplin Mobile" msgid "Joplin Mobile"
@@ -3272,9 +3252,8 @@ msgid "Manage shared notebooks"
msgstr "Управление общими блокнотами" msgstr "Управление общими блокнотами"
#: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:165 #: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:165
#, fuzzy
msgid "Manage toolbar options" msgid "Manage toolbar options"
msgstr "Управлять плагинами" msgstr "Управление параметрами панели инструментов"
#: packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx:331 #: packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx:331
msgid "Manage your plugins" msgid "Manage your plugins"
@@ -3307,9 +3286,8 @@ msgstr "Markdown + Front Matter"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx:375 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx:375
#: packages/app-mobile/components/NoteEditor/NoteEditor.tsx:352 #: packages/app-mobile/components/NoteEditor/NoteEditor.tsx:352
#, fuzzy
msgid "Markdown editor" msgid "Markdown editor"
msgstr "Markdown" msgstr "Редактор Markdown"
#: packages/app-cli/app/command-done.ts:15 #: packages/app-cli/app/command-done.ts:15
msgid "Marks a to-do as done." msgid "Marks a to-do as done."
@@ -3340,11 +3318,11 @@ msgstr "Главный пароль:"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:19 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:19
msgid "match case" msgid "match case"
msgstr "" msgstr "подходящий вариант"
#: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:72 #: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:72
msgid "Math" msgid "Math"
msgstr "" msgstr "Математика"
#: packages/lib/models/settings/builtInMetadata.ts:421 #: packages/lib/models/settings/builtInMetadata.ts:421
msgid "Max concurrent connections" msgid "Max concurrent connections"
@@ -3371,9 +3349,8 @@ msgid "Minimise"
msgstr "Минимизировать" msgstr "Минимизировать"
#: packages/app-mobile/components/CameraView/CameraView.tsx:163 #: packages/app-mobile/components/CameraView/CameraView.tsx:163
#, fuzzy
msgid "Missing camera permission" msgid "Missing camera permission"
msgstr "Недостающие мастер-ключи" msgstr "Отсутствует разрешение для камеры"
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:320 #: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:320
msgid "Missing keys" msgid "Missing keys"
@@ -3463,14 +3440,12 @@ msgid "Never resize"
msgstr "Никогда не изменять размер" msgstr "Никогда не изменять размер"
#: packages/app-mobile/setupQuickActions.ts:33 #: packages/app-mobile/setupQuickActions.ts:33
#, fuzzy
msgid "New attachment" msgid "New attachment"
msgstr "Вложения заметки" msgstr "Новое вложение"
#: packages/app-mobile/setupQuickActions.ts:34 #: packages/app-mobile/setupQuickActions.ts:34
#, fuzzy
msgid "New drawing" msgid "New drawing"
msgstr "Рисунок" msgstr "Новый рисунок"
#: packages/app-mobile/components/screens/ShareManager/index.tsx:120 #: packages/app-mobile/components/screens/ShareManager/index.tsx:120
msgid "New invitations" msgid "New invitations"
@@ -3500,9 +3475,8 @@ msgstr ""
"Будет создан новый блокнот \"%s\" и файл \"%s\" будет импортирован в него" "Будет создан новый блокнот \"%s\" и файл \"%s\" будет импортирован в него"
#: packages/app-mobile/setupQuickActions.ts:32 #: packages/app-mobile/setupQuickActions.ts:32
#, fuzzy
msgid "New photo" msgid "New photo"
msgstr "Сделать фото" msgstr "Новое фото"
#: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newSubFolder.ts:6 #: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/newSubFolder.ts:6
msgid "New sub-notebook" msgid "New sub-notebook"
@@ -3526,7 +3500,7 @@ msgstr "Новая версия: %s"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:16 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:16
msgid "next" msgid "next"
msgstr "" msgstr "далее"
#: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:271 #: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:271
msgid "Next match" msgid "Next match"
@@ -3610,14 +3584,12 @@ msgstr ""
"path>`" "path>`"
#: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:93 #: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:93
#, fuzzy
msgid "No updates available" msgid "No updates available"
msgstr "Доступно обновление" msgstr "Нет доступных обновлений"
#: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.ts:44 #: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.ts:44
#, fuzzy
msgid "None" msgid "None"
msgstr "(Нет)" msgstr "Нет"
#: packages/lib/models/settings/builtInMetadata.ts:47 #: packages/lib/models/settings/builtInMetadata.ts:47
msgid "Nord" msgid "Nord"
@@ -3780,12 +3752,11 @@ msgstr "Нумерованный список"
#: packages/lib/models/settings/builtInMetadata.ts:531 #: packages/lib/models/settings/builtInMetadata.ts:531
msgid "OCR: Clear cache and re-download language data files" msgid "OCR: Clear cache and re-download language data files"
msgstr "" msgstr "OCR: очистите кэш и заново загрузите языковые файлы"
#: packages/lib/models/settings/builtInMetadata.ts:512 #: packages/lib/models/settings/builtInMetadata.ts:512
#, fuzzy
msgid "OCR: Language data URL or path" msgid "OCR: Language data URL or path"
msgstr "Язык, формат даты" msgstr "OCR: URL-адрес или путь к языковым данным"
#: packages/app-desktop/bridge.ts:360 packages/app-desktop/bridge.ts:373 #: packages/app-desktop/bridge.ts:360 packages/app-desktop/bridge.ts:373
#: packages/app-desktop/bridge.ts:387 packages/app-desktop/bridge.ts:403 #: packages/app-desktop/bridge.ts:387 packages/app-desktop/bridge.ts:403
@@ -3821,7 +3792,7 @@ msgstr "В %s: %s"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:27 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:27
msgid "on line" msgid "on line"
msgstr "" msgstr "он-лайн"
#: packages/app-desktop/gui/MainScreen.tsx:525 #: packages/app-desktop/gui/MainScreen.tsx:525
msgid "One of your master keys use an obsolete encryption method." msgid "One of your master keys use an obsolete encryption method."
@@ -3852,9 +3823,8 @@ msgid "OneDrive Login"
msgstr "Вход в OneDrive" msgstr "Вход в OneDrive"
#: packages/lib/services/interop/InteropService.ts:144 #: packages/lib/services/interop/InteropService.ts:144
#, fuzzy
msgid "OneNote Notebook" msgid "OneNote Notebook"
msgstr "Новый блокнот" msgstr "Блокнот OneNote"
#: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/print.ts:18 #: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/print.ts:18
msgid "Only one note can be printed at a time." msgid "Only one note can be printed at a time."
@@ -3881,9 +3851,8 @@ msgid "Open profile directory"
msgstr "Открыть директорию с настройками" msgstr "Открыть директорию с настройками"
#: packages/app-mobile/components/CameraView/CameraView.tsx:164 #: packages/app-mobile/components/CameraView/CameraView.tsx:164
#, fuzzy
msgid "Open settings" msgid "Open settings"
msgstr "Открытие раздела %s" msgstr "Открыть настройки"
#: packages/app-mobile/components/screens/ConfigScreen/plugins/EnablePluginSupportPage.tsx:115 #: packages/app-mobile/components/screens/ConfigScreen/plugins/EnablePluginSupportPage.tsx:115
msgid "Open Source" msgid "Open Source"
@@ -3902,19 +3871,16 @@ msgid "Opening section %s"
msgstr "Открытие раздела %s" msgstr "Открытие раздела %s"
#: packages/app-mobile/components/Dropdown.tsx:215 #: packages/app-mobile/components/Dropdown.tsx:215
#, fuzzy
msgid "Opens dropdown" msgid "Opens dropdown"
msgstr "Закрыть выпадающий список" msgstr "Открыть выпадающий список"
#: packages/app-mobile/components/NoteItem.tsx:162 #: packages/app-mobile/components/NoteItem.tsx:162
#, fuzzy
msgid "Opens note" msgid "Opens note"
msgstr "Откройте" msgstr "Открыть заметку"
#: packages/app-mobile/components/side-menu-content.tsx:273 #: packages/app-mobile/components/side-menu-content.tsx:273
#, fuzzy
msgid "Opens notebook" msgid "Opens notebook"
msgstr "Новый блокнот" msgstr "Открыть блокнот"
#: packages/app-cli/app/command-e2ee.ts:41 #: packages/app-cli/app/command-e2ee.ts:41
#: packages/app-cli/app/command-e2ee.ts:87 #: packages/app-cli/app/command-e2ee.ts:87
@@ -4183,11 +4149,11 @@ msgstr "Предпочитаемая светлая тема"
#: packages/lib/models/settings/builtInMetadata.ts:1704 #: packages/lib/models/settings/builtInMetadata.ts:1704
msgid "Preferred voice typing provider" msgid "Preferred voice typing provider"
msgstr "" msgstr "Предпочитаемый провайдер голосового ввода текста"
#: packages/lib/models/settings/builtInMetadata.ts:667 #: packages/lib/models/settings/builtInMetadata.ts:667
msgid "Preserve colours when pasting text in Rich Text Editor" msgid "Preserve colours when pasting text in Rich Text Editor"
msgstr "" msgstr "Сохранение цветов при вставке текста в редактор свободного текста"
#: packages/app-cli/app/app-gui.js:758 #: packages/app-cli/app/app-gui.js:758
msgid "Press Ctrl+D or type \"exit\" to exit the application" msgid "Press Ctrl+D or type \"exit\" to exit the application"
@@ -4210,9 +4176,8 @@ msgid "Press to set the decryption password."
msgstr "Нажмите, чтобы установить пароль для расшифровки." msgstr "Нажмите, чтобы установить пароль для расшифровки."
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:17 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:17
#, fuzzy
msgid "previous" msgid "previous"
msgstr "Предыдущее совпадение" msgstr "предыдущее"
#: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:281 #: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:281
msgid "Previous match" msgid "Previous match"
@@ -4255,9 +4220,8 @@ msgid "Processing"
msgstr "Обработка" msgstr "Обработка"
#: packages/app-mobile/components/CameraView/ActionButtons.tsx:111 #: packages/app-mobile/components/CameraView/ActionButtons.tsx:111
#, fuzzy
msgid "Processing photo..." msgid "Processing photo..."
msgstr "Обработка" msgstr "Обработка фото..."
#: packages/server/src/routes/admin/users.ts:254 #: packages/server/src/routes/admin/users.ts:254
msgid "Profile" msgid "Profile"
@@ -4313,9 +4277,8 @@ msgid "Publish notes to the internet"
msgstr "Опубликовать заметки в Интернет" msgstr "Опубликовать заметки в Интернет"
#: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:78 #: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:78
#, fuzzy
msgid "QR Code" msgid "QR Code"
msgstr "Код" msgstr "QR код"
#: packages/app-desktop/app.ts:219 #: packages/app-desktop/app.ts:219
#: packages/app-desktop/ElectronAppWrapper.ts:123 #: packages/app-desktop/ElectronAppWrapper.ts:123
@@ -4326,7 +4289,7 @@ msgstr "Выход"
#: packages/app-mobile/components/voiceTyping/VoiceTypingDialog.tsx:206 #: packages/app-mobile/components/voiceTyping/VoiceTypingDialog.tsx:206
msgid "Re-download model" msgid "Re-download model"
msgstr "" msgstr "Скачать модель заново"
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:342 #: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:342
msgid "Re-encrypt data" msgid "Re-encrypt data"
@@ -4337,9 +4300,8 @@ msgid "Re-encryption"
msgstr "Зашифровать заново" msgstr "Зашифровать заново"
#: packages/app-desktop/gui/MasterPasswordDialog/Dialog.tsx:181 #: packages/app-desktop/gui/MasterPasswordDialog/Dialog.tsx:181
#, fuzzy
msgid "Re-enter password" msgid "Re-enter password"
msgstr "Введите пароль" msgstr "Введите пароль повторно"
#: packages/lib/models/settings/builtInMetadata.ts:1180 #: packages/lib/models/settings/builtInMetadata.ts:1180
msgid "Re-upload local data to sync target" msgid "Re-upload local data to sync target"
@@ -4405,9 +4367,8 @@ msgid "Remove"
msgstr "Удалить" msgstr "Удалить"
#: packages/app-desktop/gui/ShareFolderDialog/ShareFolderDialog.tsx:330 #: packages/app-desktop/gui/ShareFolderDialog/ShareFolderDialog.tsx:330
#, fuzzy
msgid "Remove %s from share" msgid "Remove %s from share"
msgstr "Удалить метку “%s из всех заметок?" msgstr "Удалить %s из общего ресурса"
#: packages/app-desktop/gui/Sidebar/hooks/useOnRenderItem.tsx:111 #: packages/app-desktop/gui/Sidebar/hooks/useOnRenderItem.tsx:111
msgid "Remove tag \"%s\" from all notes?" msgid "Remove tag \"%s\" from all notes?"
@@ -4439,9 +4400,8 @@ msgid "Renew token"
msgstr "Обновить токен" msgstr "Обновить токен"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:21 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:21
#, fuzzy
msgid "replace" msgid "replace"
msgstr "Замена" msgstr "заменить"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:15 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:15
#: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:291 #: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:291
@@ -4449,9 +4409,8 @@ msgid "Replace"
msgstr "Замена" msgstr "Замена"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:22 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:22
#, fuzzy
msgid "replace all" msgid "replace all"
msgstr "Заменить все" msgstr "заменить все"
#: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:301 #: packages/app-mobile/components/NoteEditor/SearchPanel.tsx:301
msgid "Replace all" msgid "Replace all"
@@ -4467,11 +4426,11 @@ msgstr "Замена: "
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:25 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:25
msgid "replaced $ matches" msgid "replaced $ matches"
msgstr "" msgstr "заменено $ совпадений"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:26 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:26
msgid "replaced match on line $" msgid "replaced match on line $"
msgstr "" msgstr "заменено совпадение в строке $"
#: packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.tsx:162 #: packages/app-mobile/components/screens/ConfigScreen/plugins/PluginInfoModal.tsx:162
msgid "Report an issue" msgid "Report an issue"
@@ -4534,9 +4493,8 @@ msgid "Restore"
msgstr "Восстановить" msgstr "Восстановить"
#: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:156 #: packages/app-mobile/components/EditorToolbar/ToolbarEditorDialog.tsx:156
#, fuzzy
msgid "Restore defaults" msgid "Restore defaults"
msgstr "Восстановить объекты" msgstr "Восстановить настройки по умолчанию"
#: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreNote.ts:10 #: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreNote.ts:10
msgid "Restore note" msgid "Restore note"
@@ -4594,11 +4552,12 @@ msgstr "Изменения: %s (%s)"
#: packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.tsx:28 #: packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.tsx:28
msgid "Rich Text" msgid "Rich Text"
msgstr "" msgstr "Свободный текст"
#: packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx:686 #: packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx:686
msgid "Rich Text editor. Press Escape then Tab to escape focus." msgid "Rich Text editor. Press Escape then Tab to escape focus."
msgstr "" msgstr ""
"Редактор свободного текста. Нажмите Escape, затем Tab, чтобы выйти из фокуса."
#: packages/app-cli/app/command-batch.js:10 #: packages/app-cli/app/command-batch.js:10
msgid "" msgid ""
@@ -4679,7 +4638,7 @@ msgstr "Сохранять информацию о географическом
#: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:89 #: packages/app-mobile/components/CameraView/ScannedBarcodes.tsx:89
msgid "Scanned code" msgid "Scanned code"
msgstr "" msgstr "Сканировать код"
#: packages/app-desktop/gui/lib/SearchInput/SearchInput.tsx:62 #: packages/app-desktop/gui/lib/SearchInput/SearchInput.tsx:62
#: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:102 #: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:102
@@ -4712,9 +4671,8 @@ msgid "Search in current note"
msgstr "Поиск в текущей заметке" msgstr "Поиск в текущей заметке"
#: packages/app-desktop/plugins/GotoAnything.tsx:665 #: packages/app-desktop/plugins/GotoAnything.tsx:665
#, fuzzy
msgid "Search results" msgid "Search results"
msgstr "Нет данных" msgstr "Результаты поиска"
#: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:170 #: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:170
msgid "Search shown" msgid "Search shown"
@@ -4737,9 +4695,8 @@ msgid "Searches for the given <pattern> in all the notes."
msgstr "Осуществляет поиск по шаблону <pattern> во всех заметках." msgstr "Осуществляет поиск по шаблону <pattern> во всех заметках."
#: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:63 #: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:63
#, fuzzy
msgid "See changelog" msgid "See changelog"
msgstr "Полный список изменений" msgstr "Посмотреть список изменений"
#: packages/lib/models/settings/builtInMetadata.ts:1199 #: packages/lib/models/settings/builtInMetadata.ts:1199
msgid "See the pre-release page for more details: %s" msgid "See the pre-release page for more details: %s"
@@ -4770,14 +4727,12 @@ msgid "Select parent notebook"
msgstr "Выбрать родительский блокнот" msgstr "Выбрать родительский блокнот"
#: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:9 #: packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.ts:9
#, fuzzy
msgid "Selection deleted" msgid "Selection deleted"
msgstr "дата завершения" msgstr "Выбранное удалено"
#: packages/app-mobile/components/FolderPicker.tsx:68 #: packages/app-mobile/components/FolderPicker.tsx:68
#, fuzzy
msgid "Selects a notebook" msgid "Selects a notebook"
msgstr "Выбрать родительский блокнот" msgstr "Выбор блокнота"
#: packages/app-desktop/gui/MenuBar.tsx:359 #: packages/app-desktop/gui/MenuBar.tsx:359
msgid "Send bug report" msgid "Send bug report"
@@ -4833,7 +4788,7 @@ msgstr ""
#: packages/app-mobile/components/EditorToolbar/EditorToolbar.tsx:47 #: packages/app-mobile/components/EditorToolbar/EditorToolbar.tsx:47
msgid "Settings" msgid "Settings"
msgstr "" msgstr "Настройки"
#: packages/app-desktop/gui/ShareFolderDialog/ShareFolderDialog.tsx:281 #: packages/app-desktop/gui/ShareFolderDialog/ShareFolderDialog.tsx:281
#: packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.ts:44 #: packages/app-mobile/components/NoteBodyViewer/hooks/useOnResourceLongPress.ts:44
@@ -4872,7 +4827,6 @@ msgid "Share permissions"
msgstr "Разрешения для общего доступа" msgstr "Разрешения для общего доступа"
#: packages/app-desktop/gui/Sidebar/listItemComponents/FolderItem.tsx:56 #: packages/app-desktop/gui/Sidebar/listItemComponents/FolderItem.tsx:56
#, fuzzy
msgid "Shared" msgid "Shared"
msgstr "Поделиться" msgstr "Поделиться"
@@ -4921,14 +4875,12 @@ msgid "Show note counts"
msgstr "Показывать число заметок" msgstr "Показывать число заметок"
#: packages/app-mobile/components/side-menu-content.tsx:258 #: packages/app-mobile/components/side-menu-content.tsx:258
#, fuzzy
msgid "Show notebook options" msgid "Show notebook options"
msgstr "Показывать число заметок" msgstr "Показать параметры блокнота"
#: packages/app-desktop/gui/PasswordInput/PasswordInput.tsx:21 #: packages/app-desktop/gui/PasswordInput/PasswordInput.tsx:21
#, fuzzy
msgid "Show password" msgid "Show password"
msgstr "Установить пароль" msgstr "Показать пароль"
#: packages/lib/models/settings/builtInMetadata.ts:698 #: packages/lib/models/settings/builtInMetadata.ts:698
msgid "Show sort order buttons" msgid "Show sort order buttons"
@@ -4943,9 +4895,8 @@ msgid "Show/hide the sidebar"
msgstr "Показать/скрыть боковую панель" msgstr "Показать/скрыть боковую панель"
#: packages/app-mobile/components/screens/tags.tsx:76 #: packages/app-mobile/components/screens/tags.tsx:76
#, fuzzy
msgid "Shows notes for tag" msgid "Shows notes for tag"
msgstr "Показывать число заметок" msgstr "Показать заметки для тега"
#: packages/lib/models/settings/builtInMetadata.ts:863 #: packages/lib/models/settings/builtInMetadata.ts:863
msgid "Shrink large images before adding them to notes." msgid "Shrink large images before adding them to notes."
@@ -5031,11 +4982,11 @@ msgstr ""
#: packages/app-desktop/gui/ResourceScreen.tsx:92 #: packages/app-desktop/gui/ResourceScreen.tsx:92
msgid "Sort \"%s\" in ascending order" msgid "Sort \"%s\" in ascending order"
msgstr "" msgstr "Сортировка \"%s\" в порядке возрастания"
#: packages/app-desktop/gui/ResourceScreen.tsx:92 #: packages/app-desktop/gui/ResourceScreen.tsx:92
msgid "Sort \"%s\" in descending order" msgid "Sort \"%s\" in descending order"
msgstr "" msgstr "Сортировка \"%s\" в порядке убывания"
#: packages/lib/models/settings/builtInMetadata.ts:754 #: packages/lib/models/settings/builtInMetadata.ts:754
msgid "Sort notebooks by" msgid "Sort notebooks by"
@@ -5219,12 +5170,11 @@ msgstr "Переключение профиля"
#: packages/app-mobile/components/CameraView/ActionButtons.tsx:101 #: packages/app-mobile/components/CameraView/ActionButtons.tsx:101
msgid "Switch to back-facing camera" msgid "Switch to back-facing camera"
msgstr "" msgstr "Переключение на основную камеру"
#: packages/app-mobile/components/CameraView/ActionButtons.tsx:101 #: packages/app-mobile/components/CameraView/ActionButtons.tsx:101
#, fuzzy
msgid "Switch to front-facing camera" msgid "Switch to front-facing camera"
msgstr "Переключение на профиль %d" msgstr "Переключение на фронтальную камеру"
#: packages/app-desktop/gui/utils/NoteListUtils.ts:93 #: packages/app-desktop/gui/utils/NoteListUtils.ts:93
msgid "Switch to note type" msgid "Switch to note type"
@@ -5237,14 +5187,12 @@ msgid "Switch to profile %d"
msgstr "Переключение на профиль %d" msgstr "Переключение на профиль %d"
#: packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.tsx:28 #: packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.tsx:28
#, fuzzy
msgid "Switch to the %s Editor" msgid "Switch to the %s Editor"
msgstr "Конвертировать в заметку" msgstr "Переключение на редактор %s"
#: packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.tsx:78 #: packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.tsx:78
#, fuzzy
msgid "Switch to the legacy editor" msgid "Switch to the legacy editor"
msgstr "Конвертировать в заметку" msgstr "Переключение на старый редактор"
#: packages/app-desktop/gui/utils/NoteListUtils.ts:102 #: packages/app-desktop/gui/utils/NoteListUtils.ts:102
msgid "Switch to to-do type" msgid "Switch to to-do type"
@@ -5355,7 +5303,7 @@ msgstr "тег1, тег2, ..."
#: packages/app-cli/app/command-import.ts:55 #: packages/app-cli/app/command-import.ts:55
#: packages/app-desktop/gui/ImportScreen.tsx:94 #: packages/app-desktop/gui/ImportScreen.tsx:94
msgid "Tagged: %d." msgid "Tagged: %d."
msgstr "С метками: %d." msgstr "Тегировано: %d."
#: packages/app-desktop/gui/NoteListHeader/utils/getColumnTitle.ts:10 #: packages/app-desktop/gui/NoteListHeader/utils/getColumnTitle.ts:10
#: packages/app-desktop/gui/Sidebar/hooks/useSidebarListData.ts:69 #: packages/app-desktop/gui/Sidebar/hooks/useSidebarListData.ts:69
@@ -5527,7 +5475,7 @@ msgstr ""
#: packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.tsx:83 #: packages/app-desktop/gui/NoteEditor/WarningBanner/WarningBanner.tsx:83
msgid "The following plugins may not support the current markdown editor:" msgid "The following plugins may not support the current markdown editor:"
msgstr "" msgstr "Следующие плагины могут не поддерживать текущий редактор markdown:"
#: packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx:257 #: packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx:257
#: packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/RecommendedBadge.tsx:49 #: packages/app-mobile/components/screens/ConfigScreen/plugins/PluginBox/RecommendedBadge.tsx:49
@@ -5655,6 +5603,11 @@ msgid ""
"\n" "\n"
"Error: \"%s\"" "Error: \"%s\""
msgstr "" msgstr ""
"Веб-клиент не поддерживает прием зашифрованных общих блокнотов. Пожалуйста, "
"переключитесь на ПК или мобильное приложение, прежде чем принимать общий "
"доступ.\n"
"\n"
"Ошибка: \"%s\""
#: packages/app-desktop/gui/Root.tsx:150 #: packages/app-desktop/gui/Root.tsx:150
msgid "The Web Clipper needs your authorisation to access your data." msgid "The Web Clipper needs your authorisation to access your data."
@@ -6013,9 +5966,8 @@ msgid "Toggle editor layout"
msgstr "Переключить вид редактора" msgstr "Переключить вид редактора"
#: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditorPlugin.ts:11 #: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditorPlugin.ts:11
#, fuzzy
msgid "Toggle editor plugin" msgid "Toggle editor plugin"
msgstr "Переключить вид редактора" msgstr "Переключить плагин редактора"
#: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditors.ts:8 #: packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditors.ts:8
msgid "Toggle editors" msgid "Toggle editors"
@@ -6162,9 +6114,8 @@ msgstr ""
"версии" "версии"
#: packages/app-mobile/utils/getVersionInfoText.ts:28 #: packages/app-mobile/utils/getVersionInfoText.ts:28
#, fuzzy
msgid "Unknown platform" msgid "Unknown platform"
msgstr "Неизвестный флаг: %s" msgstr "Неизвестная платформа"
#: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:82 #: packages/app-mobile/components/NoteEditor/commandDeclarations.ts:82
msgid "Unordered list" msgid "Unordered list"
@@ -6196,11 +6147,12 @@ msgid "Unsupported link or message: %s"
msgstr "Неподдерживаемая ссылка или сообщение: %s" msgstr "Неподдерживаемая ссылка или сообщение: %s"
#: packages/app-mobile/commands/openItem.ts:60 #: packages/app-mobile/commands/openItem.ts:60
#, fuzzy
msgid "" msgid ""
"Unsupported link or message: %s.\n" "Unsupported link or message: %s.\n"
"Error: %s" "Error: %s"
msgstr "Неподдерживаемая ссылка или сообщение: %s" msgstr ""
"Неподдерживаемая ссылка или сообщение: %s\n"
"Ошибка: %s"
#: packages/app-desktop/gui/ResourceScreen.tsx:123 #: packages/app-desktop/gui/ResourceScreen.tsx:123
#: packages/lib/models/BaseItem.ts:921 packages/lib/path-utils.ts:27 #: packages/lib/models/BaseItem.ts:921 packages/lib/path-utils.ts:27
@@ -6218,9 +6170,8 @@ msgid "Update available"
msgstr "Доступно обновление" msgstr "Доступно обновление"
#: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:65 #: packages/app-desktop/gui/UpdateNotification/UpdateNotification.tsx:65
#, fuzzy
msgid "Update later" msgid "Update later"
msgstr "дата обновления" msgstr "Обновить позже"
#: packages/server/src/routes/admin/users.ts:257 #: packages/server/src/routes/admin/users.ts:257
#: packages/server/src/routes/index/users.ts:91 #: packages/server/src/routes/index/users.ts:91
@@ -6320,9 +6271,8 @@ msgstr ""
"выхода." "выхода."
#: packages/lib/models/settings/builtInMetadata.ts:1347 #: packages/lib/models/settings/builtInMetadata.ts:1347
#, fuzzy
msgid "Use the legacy Markdown editor" msgid "Use the legacy Markdown editor"
msgstr "Включить панель инструментов Markdown" msgstr "Использовать старый редактор Markdown"
#: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:552 #: packages/app-mobile/components/screens/ConfigScreen/ConfigScreen.tsx:552
msgid "" msgid ""
@@ -6418,7 +6368,7 @@ msgstr "Голосовой набор..."
#: packages/lib/models/settings/builtInMetadata.ts:1712 #: packages/lib/models/settings/builtInMetadata.ts:1712
msgid "Vosk" msgid "Vosk"
msgstr "" msgstr "Vosk"
#: packages/lib/services/joplinCloudUtils.ts:27 #: packages/lib/services/joplinCloudUtils.ts:27
msgid "Waiting for authorisation..." msgid "Waiting for authorisation..."
@@ -6523,7 +6473,7 @@ msgstr ""
#: packages/lib/models/settings/builtInMetadata.ts:1713 #: packages/lib/models/settings/builtInMetadata.ts:1713
msgid "Whisper" msgid "Whisper"
msgstr "" msgstr "Шепот"
#: packages/app-desktop/ElectronAppWrapper.ts:222 #: packages/app-desktop/ElectronAppWrapper.ts:222
msgid "Window unresponsive." msgid "Window unresponsive."

File diff suppressed because it is too large Load Diff

View File

@@ -134,6 +134,7 @@
"v3.3.2": true, "v3.3.2": true,
"android-v3.3.1": true, "android-v3.3.1": true,
"ios-v13.3.1": true, "ios-v13.3.1": true,
"v3.2.13": true "v3.2.13": true,
"android-v3.3.2": true
} }
} }

View File

@@ -36,7 +36,7 @@ const path = require('path');
const md5File = require('md5-file'); const md5File = require('md5-file');
const docDir = `${dirname(dirname(dirname(dirname(__dirname))))}/joplin-website/docs`; const docDir = `${dirname(dirname(dirname(dirname(__dirname))))}/joplin-website/docs`;
if (!pathExistsSync(docDir)) throw new Error(`"docs" directory does not exist: ${docDir}`); if (!pathExistsSync(docDir)) throw new Error(`"docs" directory does not exist - create it first. At: ${docDir}`);
const websiteAssetDir = `${rootDir}/Assets/WebsiteAssets`; const websiteAssetDir = `${rootDir}/Assets/WebsiteAssets`;
const readmeDir = `${rootDir}/readme`; const readmeDir = `${rootDir}/readme`;

View File

@@ -1,5 +1,14 @@
# Joplin Android Changelog # Joplin Android Changelog
## [android-v3.3.2](https://github.com/laurent22/joplin/releases/tag/android-v3.3.2) (Pre-release) - 2025-03-03T22:35:08Z
- Improved: Improve encryption config screen accessibility (#11874) (#11846 by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
- Improved: Switch default library used for Whisper voice typing (#11881 by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
- Improved: Updated packages @bam.tech/react-native-image-resizer (v3.0.11)
- Fixed: Accessibility: Fix "new note" and "new to-do" buttons are focusable even while invisible (#11899 by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
- Fixed: Fix disabled encryption keys list showing enabled keys (#11861) (#11858 by [@pedr](https://github.com/pedr))
- Fixed: Fix voice recorder crash (#11876) (#11864 by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
## [android-v3.3.1](https://github.com/laurent22/joplin/releases/tag/android-v3.3.1) (Pre-release) - 2025-02-19T16:01:54Z ## [android-v3.3.1](https://github.com/laurent22/joplin/releases/tag/android-v3.3.1) (Pre-release) - 2025-02-19T16:01:54Z
- New: Add support for plugin editor views (#11831) - New: Add support for plugin editor views (#11831)

View File

@@ -1,5 +1,9 @@
# Joplin Server Changelog # Joplin Server Changelog
## [server-v3.3.4](https://github.com/laurent22/joplin/releases/tag/server-v3.3.4) - 2025-03-03T22:29:29Z
- Security: Improve request validation in default route (#11916 by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
## [server-v3.3.3](https://github.com/laurent22/joplin/releases/tag/server-v3.3.3) - 2025-02-23T19:06:59Z ## [server-v3.3.3](https://github.com/laurent22/joplin/releases/tag/server-v3.3.3) - 2025-02-23T19:06:59Z
- Security: Fixed patching user properties (12baa98) - Security: Fixed patching user properties (12baa98)

View File

@@ -25,3 +25,17 @@ To remove a member from your team click on the Profile icon (👤) for that user
The team admin account is only for managing users and billing. To collaborate with the other members of your team, add yourself as a member using a different email address. The team admin account is only for managing users and billing. To collaborate with the other members of your team, add yourself as a member using a different email address.
## Migrating to a Team account
If you already have a Basic or Pro account, it is not currently possible to migrate your data to a Team account, as they work very differently.
You can however follow these steps to manually migrate your data to a Team account:
- Open the Joplin desktop app
- Click Synchronise and wait for it to complete
- Export all your notes as JEX (File => Export => JEX)
- Create a new profile (File => Switch profile)
- Import your JEX file
- Cancel your current Joplin Cloud subscription
- Open a new Joplin Cloud Team subscription
- Synchronise your new profile with this new subscription

View File

@@ -8279,7 +8279,6 @@ __metadata:
"@joplin/renderer": ~3.3 "@joplin/renderer": ~3.3
"@joplin/tools": ~3.3 "@joplin/tools": ~3.3
"@joplin/utils": ~3.3 "@joplin/utils": ~3.3
"@journeyapps/sqlcipher": 5.3.1
"@playwright/test": 1.45.3 "@playwright/test": 1.45.3
"@sentry/electron": 4.24.0 "@sentry/electron": 4.24.0
"@testing-library/react-hooks": 8.0.1 "@testing-library/react-hooks": 8.0.1
@@ -8605,7 +8604,6 @@ __metadata:
"@joplin/turndown": ^4.0.79 "@joplin/turndown": ^4.0.79
"@joplin/turndown-plugin-gfm": ^1.0.61 "@joplin/turndown-plugin-gfm": ^1.0.61
"@joplin/utils": ~3.3 "@joplin/utils": ~3.3
"@journeyapps/sqlcipher": 5.3.1
"@testing-library/react-hooks": 8.0.1 "@testing-library/react-hooks": 8.0.1
"@types/adm-zip": 0.5.7 "@types/adm-zip": 0.5.7
"@types/fs-extra": 11.0.4 "@types/fs-extra": 11.0.4
@@ -9000,16 +8998,6 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"@journeyapps/sqlcipher@npm:5.3.1":
version: 5.3.1
resolution: "@journeyapps/sqlcipher@npm:5.3.1"
dependencies:
"@mapbox/node-pre-gyp": ^1.0.0
node-addon-api: ^3.0.0
checksum: 3e3dfeb85dffd1bab20f41cb6b38df1dc57baa33266293e55ad883d7d181294e45e8496cd888457689fa9e440d5629712c72124e05ae9ce00fe5175129e2c9db
languageName: node
linkType: hard
"@jridgewell/gen-mapping@npm:^0.3.0": "@jridgewell/gen-mapping@npm:^0.3.0":
version: 0.3.3 version: 0.3.3
resolution: "@jridgewell/gen-mapping@npm:0.3.3" resolution: "@jridgewell/gen-mapping@npm:0.3.3"
@@ -35390,15 +35378,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"node-addon-api@npm:^3.0.0":
version: 3.2.1
resolution: "node-addon-api@npm:3.2.1"
dependencies:
node-gyp: latest
checksum: 2369986bb0881ccd9ef6bacdf39550e07e089a9c8ede1cbc5fc7712d8e2faa4d50da0e487e333d4125f8c7a616c730131d1091676c9d499af1d74560756b4a18
languageName: node
linkType: hard
"node-addon-api@npm:^4.2.0, node-addon-api@npm:^4.3.0": "node-addon-api@npm:^4.2.0, node-addon-api@npm:^4.3.0":
version: 4.3.0 version: 4.3.0
resolution: "node-addon-api@npm:4.3.0" resolution: "node-addon-api@npm:4.3.0"