You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2026-01-14 00:29:38 +02:00
Compare commits
3 Commits
v2.6.5
...
server_ci_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b611b441c5 | ||
|
|
1962f03adf | ||
|
|
66fa23cdd8 |
@@ -6,7 +6,7 @@ version: '3'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:13
|
||||
image: postgres:13.1
|
||||
command: postgres -c work_mem=100000
|
||||
ports:
|
||||
- "5432:5432"
|
||||
@@ -14,7 +14,7 @@ services:
|
||||
- POSTGRES_PASSWORD=joplin
|
||||
- POSTGRES_USER=joplin
|
||||
- POSTGRES_DB=joplin
|
||||
|
||||
|
||||
# Use this to specify additional Postgres
|
||||
# config parameters:
|
||||
#
|
||||
|
||||
@@ -18,7 +18,7 @@ services:
|
||||
- POSTGRES_PORT=5432
|
||||
- POSTGRES_HOST=localhost
|
||||
db:
|
||||
image: postgres:13
|
||||
image: postgres:13.1
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
|
||||
@@ -8,7 +8,7 @@ version: '3'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:13
|
||||
image: postgres:13.1
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
|
||||
@@ -5,7 +5,6 @@ import MigrationHandler from '@joplin/lib/services/synchronizer/MigrationHandler
|
||||
import ResourceFetcher from '@joplin/lib/services/ResourceFetcher';
|
||||
import Synchronizer from '@joplin/lib/Synchronizer';
|
||||
import { masterKeysWithoutPassword } from '@joplin/lib/services/e2ee/utils';
|
||||
import { appTypeToLockType } from '@joplin/lib/services/synchronizer/LockHandler';
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { OneDriveApiNodeUtils } = require('@joplin/lib/onedrive-api-node-utils.js');
|
||||
@@ -189,7 +188,7 @@ class Command extends BaseCommand {
|
||||
sync.api(),
|
||||
reg.db(),
|
||||
sync.lockHandler(),
|
||||
appTypeToLockType(Setting.value('appType')),
|
||||
Setting.value('appType'),
|
||||
Setting.value('clientId')
|
||||
);
|
||||
|
||||
|
||||
@@ -356,6 +356,8 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editorReady) return () => {};
|
||||
|
||||
const theme = themeStyle(props.themeId);
|
||||
|
||||
const element = document.createElement('style');
|
||||
@@ -489,28 +491,11 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
|
||||
padding-top: ${theme.toolbarPadding}px;
|
||||
padding-bottom: ${theme.toolbarPadding}px;
|
||||
}
|
||||
|
||||
.joplin-tinymce .tox .tox-edit-area__iframe {
|
||||
background-color: ${theme.backgroundColor} !important;
|
||||
}
|
||||
|
||||
.joplin-tinymce .tox .tox-toolbar__primary {
|
||||
/* This component sets an empty svg with a white background as the background
|
||||
* which needs to be cleared to prevent it from flashing white in dark themes */
|
||||
background: none;
|
||||
background-color: ${theme.backgroundColor3} !important;
|
||||
}
|
||||
`));
|
||||
|
||||
return () => {
|
||||
document.head.removeChild(element);
|
||||
};
|
||||
// editorReady is here because TinyMCE starts by initializing a blank iframe, which needs to be
|
||||
// styled by us, otherwise users in dark mode get a bright white flash. During initialization
|
||||
// our styling is overwritten which causes some elements to have the wrong styling. Removing the
|
||||
// style and re-applying it on editorReady gives our styles precedence and prevents any flashing
|
||||
//
|
||||
// tl;dr: editorReady is used here because the css needs to be re-applied after TinyMCE init
|
||||
}, [editorReady, props.themeId]);
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
4
packages/app-desktop/package-lock.json
generated
4
packages/app-desktop/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.6.5",
|
||||
"version": "2.6.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.6.5",
|
||||
"version": "2.6.2",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.0.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "2.6.5",
|
||||
"version": "2.6.2",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"private": true,
|
||||
|
||||
@@ -146,8 +146,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097660
|
||||
versionName "2.6.4"
|
||||
versionCode 2097659
|
||||
versionName "2.6.3"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
@@ -215,16 +215,6 @@ android {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// To fix this error:
|
||||
//
|
||||
// > Execution failed for task ':app:lintVitalRelease'
|
||||
//
|
||||
// https://stackoverflow.com/a/62603296/561309
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -27,10 +27,3 @@ android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.99.0
|
||||
|
||||
# To fix this error:
|
||||
#
|
||||
# > Failed to transform bcprov-jdk15on-1.68.jar
|
||||
#
|
||||
# https://github.com/robolectric/robolectric/issues/6521
|
||||
android.jetifier.ignorelist=bcprov
|
||||
|
||||
@@ -258,20 +258,6 @@ export default class BaseApplication {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--enable-features=') === 0) {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to run the app on native wayland
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.indexOf('--ozone-platform=') === 0) {
|
||||
// Electron-specific flag - ignore it
|
||||
// Allows users to run the app on native wayland
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.length && arg[0] == '-') {
|
||||
throw new JoplinError(_('Unknown flag: %s', arg), 'flagError');
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Logger from './Logger';
|
||||
import LockHandler, { appTypeToLockType, hasActiveLock, LockClientType, LockType } from './services/synchronizer/LockHandler';
|
||||
import LockHandler, { hasActiveLock, LockClientType, LockType } from './services/synchronizer/LockHandler';
|
||||
import Setting, { AppType } from './models/Setting';
|
||||
import shim from './shim';
|
||||
import MigrationHandler from './services/synchronizer/MigrationHandler';
|
||||
@@ -53,7 +53,7 @@ export default class Synchronizer {
|
||||
|
||||
private db_: JoplinDatabase;
|
||||
private api_: FileApi;
|
||||
private appType_: AppType;
|
||||
private appType_: string;
|
||||
private logger_: Logger = new Logger();
|
||||
private state_: string = 'idle';
|
||||
private cancelling_: boolean = false;
|
||||
@@ -77,7 +77,7 @@ export default class Synchronizer {
|
||||
|
||||
public dispatch: Function;
|
||||
|
||||
public constructor(db: JoplinDatabase, api: FileApi, appType: AppType) {
|
||||
public constructor(db: JoplinDatabase, api: FileApi, appType: string) {
|
||||
this.db_ = db;
|
||||
this.api_ = api;
|
||||
this.appType_ = appType;
|
||||
@@ -123,7 +123,13 @@ export default class Synchronizer {
|
||||
|
||||
private lockClientType(): LockClientType {
|
||||
if (this.lockClientType_) return this.lockClientType_;
|
||||
this.lockClientType_ = appTypeToLockType(this.appType_);
|
||||
|
||||
if (this.appType_ === AppType.Desktop) this.lockClientType_ = LockClientType.Desktop;
|
||||
if (this.appType_ === AppType.Mobile) this.lockClientType_ = LockClientType.Mobile;
|
||||
if (this.appType_ === AppType.Cli) this.lockClientType_ = LockClientType.Cli;
|
||||
|
||||
if (!this.lockClientType_) throw new Error(`Invalid client type: ${this.appType_}`);
|
||||
|
||||
return this.lockClientType_;
|
||||
}
|
||||
|
||||
@@ -135,7 +141,7 @@ export default class Synchronizer {
|
||||
|
||||
maxResourceSize() {
|
||||
if (this.maxResourceSize_ !== null) return this.maxResourceSize_;
|
||||
return this.appType_ === AppType.Mobile ? 100 * 1000 * 1000 : Infinity;
|
||||
return this.appType_ === 'mobile' ? 100 * 1000 * 1000 : Infinity;
|
||||
}
|
||||
|
||||
public setShareService(v: ShareService) {
|
||||
|
||||
@@ -3,7 +3,6 @@ import shim from '../../shim';
|
||||
import JoplinError from '../../JoplinError';
|
||||
import time from '../../time';
|
||||
import { FileApi } from '../../file-api';
|
||||
import { AppType } from '../../models/Setting';
|
||||
const { fileExtension, filename } = require('../../path-utils');
|
||||
|
||||
export enum LockType {
|
||||
@@ -47,13 +46,6 @@ export function lockNameToObject(name: string, updatedTime: number = null): Lock
|
||||
return lock;
|
||||
}
|
||||
|
||||
export function appTypeToLockType(appType: AppType): LockClientType {
|
||||
if (appType === AppType.Desktop) return LockClientType.Desktop;
|
||||
if (appType === AppType.Mobile) return LockClientType.Mobile;
|
||||
if (appType === AppType.Cli) return LockClientType.Cli;
|
||||
throw new Error(`Invalid app type: ${appType}`);
|
||||
}
|
||||
|
||||
export function hasActiveLock(locks: Lock[], currentDate: Date, lockTtl: number, lockType: LockType, clientType: LockClientType = null, clientId: string = null) {
|
||||
const lock = activeLock(locks, currentDate, lockTtl, lockType, clientType, clientId);
|
||||
return !!lock;
|
||||
|
||||
@@ -2,7 +2,6 @@ import shim from '../../../shim';
|
||||
import MigrationHandler from '../MigrationHandler';
|
||||
import Setting from '../../../models/Setting';
|
||||
import { reg } from '../../../registry';
|
||||
import { appTypeToLockType } from '../LockHandler';
|
||||
const { useEffect, useState } = shim.react();
|
||||
|
||||
export interface SyncTargetUpgradeResult {
|
||||
@@ -29,7 +28,7 @@ export default function useSyncTargetUpgrade(): SyncTargetUpgradeResult {
|
||||
synchronizer.api(),
|
||||
reg.db(),
|
||||
synchronizer.lockHandler(),
|
||||
appTypeToLockType(Setting.value('appType')),
|
||||
Setting.value('appType'),
|
||||
Setting.value('clientId')
|
||||
);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ module.exports = {
|
||||
|
||||
testEnvironment: 'node',
|
||||
|
||||
slowTestThreshold: 60,
|
||||
slowTestThreshold: 40,
|
||||
|
||||
setupFilesAfterEnv: [`${__dirname}/jest.setup.js`],
|
||||
};
|
||||
|
||||
4
packages/server/package-lock.json
generated
4
packages/server/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@joplin/server",
|
||||
"version": "2.6.14",
|
||||
"version": "2.6.13",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@joplin/server",
|
||||
"version": "2.6.14",
|
||||
"version": "2.6.13",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.40.0",
|
||||
"@fortawesome/fontawesome-free": "^5.15.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/server",
|
||||
"version": "2.6.14",
|
||||
"version": "2.6.13",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start-dev": "npm run build && JOPLIN_IS_TESTING=1 nodemon --config nodemon.json --ext ts,js,mustache,css,tsx dist/app.js --env dev",
|
||||
|
||||
@@ -14,10 +14,9 @@ enum ArgvCommand {
|
||||
|
||||
interface Argv {
|
||||
command: ArgvCommand;
|
||||
connection?: string;
|
||||
connection: string;
|
||||
batchSize?: number;
|
||||
maxContentSize?: number;
|
||||
maxProcessedItems?: number;
|
||||
}
|
||||
|
||||
export default class StorageCommand extends BaseCommand {
|
||||
@@ -53,10 +52,6 @@ export default class StorageCommand extends BaseCommand {
|
||||
type: 'number',
|
||||
description: 'Max content size',
|
||||
},
|
||||
'max-processed-items': {
|
||||
type: 'number',
|
||||
description: 'Max number of items to process before stopping',
|
||||
},
|
||||
'connection': {
|
||||
description: 'storage connection string',
|
||||
type: 'string',
|
||||
@@ -90,14 +85,11 @@ export default class StorageCommand extends BaseCommand {
|
||||
},
|
||||
|
||||
[ArgvCommand.DeleteDatabaseContentColumn]: async () => {
|
||||
const maxProcessedItems = argv.maxProcessedItems;
|
||||
|
||||
logger.info(`Batch size: ${batchSize}`);
|
||||
|
||||
await runContext.models.item().deleteDatabaseContentColumn({
|
||||
batchSize,
|
||||
logger,
|
||||
maxProcessedItems,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ const defaultEnvValues: EnvVariables = {
|
||||
// result in clients generating many conflicts. Set to 0 to disable the
|
||||
// check. https://github.com/laurent22/joplin/issues/5738
|
||||
|
||||
MAX_TIME_DRIFT: 2000,
|
||||
MAX_TIME_DRIFT: 100,
|
||||
|
||||
// ==================================================
|
||||
// URL config
|
||||
|
||||
@@ -462,41 +462,6 @@ describe('ItemModel', function() {
|
||||
expect(await models().item().dbContent(note1.id)).toEqual(Buffer.from(''));
|
||||
});
|
||||
|
||||
test('should delete the database item content - maxProcessedItems handling', async function() {
|
||||
if (isSqlite(db())) {
|
||||
expect(1).toBe(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const { user: user1 } = await createUserAndSession(1);
|
||||
|
||||
await createItemTree3(user1.id, '', '', [
|
||||
{
|
||||
id: '000000000000000000000000000000F1',
|
||||
children: [
|
||||
{ id: '00000000000000000000000000000001' },
|
||||
{ id: '00000000000000000000000000000002' },
|
||||
{ id: '00000000000000000000000000000003' },
|
||||
{ id: '00000000000000000000000000000004' },
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
await models().item().deleteDatabaseContentColumn({ batchSize: 2, maxProcessedItems: 4 });
|
||||
|
||||
const itemIds = (await models().item().all()).map(it => it.id);
|
||||
const contents = await Promise.all([
|
||||
models().item().dbContent(itemIds[0]),
|
||||
models().item().dbContent(itemIds[1]),
|
||||
models().item().dbContent(itemIds[2]),
|
||||
models().item().dbContent(itemIds[3]),
|
||||
models().item().dbContent(itemIds[4]),
|
||||
]);
|
||||
|
||||
const emptyOnes = contents.filter(c => c.toString() === '');
|
||||
expect(emptyOnes.length).toBe(4);
|
||||
});
|
||||
|
||||
// test('should stop importing item if it has been deleted', async function() {
|
||||
// const { user: user1 } = await createUserAndSession(1);
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ export interface ImportContentToStorageOptions {
|
||||
export interface DeleteDatabaseContentOptions {
|
||||
batchSize?: number;
|
||||
logger?: Logger | LoggerWrapper;
|
||||
maxProcessedItems?: number;
|
||||
}
|
||||
|
||||
export interface SaveFromRawContentItem {
|
||||
@@ -410,21 +409,20 @@ export default class ItemModel extends BaseModel<Item> {
|
||||
options = {
|
||||
batchSize: 1000,
|
||||
logger: new Logger(),
|
||||
maxProcessedItems: 0,
|
||||
...options,
|
||||
};
|
||||
|
||||
// const itemCount = (await this.db(this.tableName)
|
||||
// .count('id', { as: 'total' })
|
||||
// .where('content', '!=', Buffer.from(''))
|
||||
// .first())['total'];
|
||||
const itemCount = (await this.db(this.tableName)
|
||||
.count('id', { as: 'total' })
|
||||
.where('content', '!=', Buffer.from(''))
|
||||
.first())['total'];
|
||||
|
||||
let totalDone = 0;
|
||||
|
||||
// UPDATE items SET content = '\x' WHERE id IN (SELECT id FROM items WHERE content != '\x' LIMIT 5000);
|
||||
|
||||
while (true) {
|
||||
options.logger.info(`Processing items ${totalDone}`);
|
||||
options.logger.info(`Processing items ${totalDone} / ${itemCount}`);
|
||||
|
||||
const updatedRows = await this
|
||||
.db(this.tableName)
|
||||
@@ -442,11 +440,6 @@ export default class ItemModel extends BaseModel<Item> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.maxProcessedItems && totalDone + options.batchSize > options.maxProcessedItems) {
|
||||
options.logger.info(`Processed ${totalDone} items out of requested ${options.maxProcessedItems}`);
|
||||
return;
|
||||
}
|
||||
|
||||
await msleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
#: packages/app-mobile/components/screens/ConfigScreen.tsx:565
|
||||
msgid "- Camera: to allow taking a picture and attaching it to a note."
|
||||
@@ -585,9 +583,6 @@ msgid ""
|
||||
"enabled end-to-end encryption. They may do so from the screen Configuration "
|
||||
"> Encryption."
|
||||
msgstr ""
|
||||
"Das verschlüsselte Notizbuch kann nicht mit %s geteilt werden, da die Person "
|
||||
"die Ende-zu-Ende Verschlüsselung nicht aktiviert hat. Dies ist unter "
|
||||
"Optionen > Verschlüsselung möglich."
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/toggleLayoutMoveMode.ts:7
|
||||
msgid "Change application layout"
|
||||
@@ -766,8 +761,9 @@ msgid "Conflicts (attachments)"
|
||||
msgstr "Konflikte (Anhänge)"
|
||||
|
||||
#: packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.tsx:108
|
||||
#, fuzzy
|
||||
msgid "Content provided by %s"
|
||||
msgstr "Von %s bereitgestellte Inhalte"
|
||||
msgstr "Inhaltseigenschaften"
|
||||
|
||||
#: packages/app-mobile/components/screens/Note.tsx:933
|
||||
msgid "Convert to note"
|
||||
@@ -791,8 +787,9 @@ msgstr "Entwicklermodus-Befehl in Zwischenablage kopieren"
|
||||
#: packages/app-desktop/gui/Sidebar/Sidebar.tsx:340
|
||||
#: packages/app-desktop/gui/Sidebar/Sidebar.tsx:354
|
||||
#: packages/app-desktop/gui/utils/NoteListUtils.ts:139
|
||||
#, fuzzy
|
||||
msgid "Copy external link"
|
||||
msgstr "Externen Link kopieren"
|
||||
msgstr "Externe Bearbeitung stoppen"
|
||||
|
||||
#: packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts:164
|
||||
msgid "Copy Link Address"
|
||||
@@ -864,10 +861,6 @@ msgid ""
|
||||
"\n"
|
||||
"The error was: \"%s\""
|
||||
msgstr ""
|
||||
"Die Einladung konnte nicht beantwortet werden. Bitte versuche es erneut, "
|
||||
"oder prüfe, ob der Notizbuch-Besitzer dieses noch freigibt.\n"
|
||||
"\n"
|
||||
"Der Fehler war: \"%s\""
|
||||
|
||||
#: packages/lib/components/EncryptionConfigScreen/utils.ts:214
|
||||
msgid "Could not upgrade master key: %s"
|
||||
@@ -1212,11 +1205,14 @@ msgid "Do not ask for confirmation."
|
||||
msgstr "Nicht nach einer Bestätigung fragen."
|
||||
|
||||
#: packages/lib/components/EncryptionConfigScreen/utils.ts:56
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Do not lose the password as, for security purposes, this will be the *only* "
|
||||
"way to decrypt the data! To enable encryption, please enter your password "
|
||||
"below."
|
||||
msgstr ""
|
||||
"Durch das Aktivieren der Verschlüsselung werden *alle* Notizen und Anhänge "
|
||||
"neu synchronisiert und verschlüsselt an das Synchronisationsziel gesendet. "
|
||||
"Achte darauf, dass du das Passwort nicht verlierst, da dies aus "
|
||||
"Sicherheitsgründen die *einzige* Möglichkeit ist, deine Daten zu "
|
||||
"entschlüsseln! Um die Verschlüsselung zu aktivieren, gib bitte unten dein "
|
||||
@@ -1444,12 +1440,14 @@ msgid "Enabled"
|
||||
msgstr "Aktiviert"
|
||||
|
||||
#: packages/lib/components/EncryptionConfigScreen/utils.ts:51
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Enabling encryption means *all* your notes and attachments are going to be "
|
||||
"re-synchronised and sent encrypted to the sync target."
|
||||
msgstr ""
|
||||
"Durch die Aktivierung der Verschlüsselung werden *alle* Notizen und Anhänge "
|
||||
"neu synchronisiert und verschlüsselt an das Synchronisationsziel gesendet."
|
||||
"Durch die Deaktivierung der Verschlüsselung werden *alle* Notizen und "
|
||||
"Anhänge neu synchronisiert und unverschlüsselt an das Synchronisationsziel "
|
||||
"gesendet. Möchtest du fortfahren?"
|
||||
|
||||
#: packages/lib/models/BaseItem.ts:808
|
||||
msgid "Encrypted"
|
||||
@@ -1478,16 +1476,19 @@ msgid "Encryption is: %s"
|
||||
msgstr "Verschlüsselung ist: %s"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:170
|
||||
#, fuzzy
|
||||
msgid "Encryption keys"
|
||||
msgstr "Verschlüsselungsschlüssel"
|
||||
msgstr "Die Verschlüsselung ist:"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:247
|
||||
#, fuzzy
|
||||
msgid "Encryption:"
|
||||
msgstr "Verschlüsselung:"
|
||||
msgstr "Verschlüsselung"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:245
|
||||
#, fuzzy
|
||||
msgid "End-to-end encryption"
|
||||
msgstr "Ende-zu-Ende Verschlüsselung"
|
||||
msgstr "Verschlüsselung aktivieren"
|
||||
|
||||
#: packages/app-mobile/components/screens/dropbox-login.js:66
|
||||
msgid "Enter code here"
|
||||
@@ -1709,8 +1710,9 @@ msgid "General"
|
||||
msgstr "Allgemeines"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:250
|
||||
#, fuzzy
|
||||
msgid "Generated"
|
||||
msgstr "Erzeugt"
|
||||
msgstr "Allgemeines"
|
||||
|
||||
#: packages/app-desktop/gui/ShareNoteDialog.tsx:207
|
||||
msgid "Generating link..."
|
||||
@@ -1758,8 +1760,9 @@ msgid "Hide %s"
|
||||
msgstr "%s ausblenden"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:170
|
||||
#, fuzzy
|
||||
msgid "Hide disabled keys"
|
||||
msgstr "Deaktivierte Schlüssel ausblenden"
|
||||
msgstr "Deaktivierte Hauptschlüssel ausblenden"
|
||||
|
||||
#: packages/app-desktop/gui/KeymapConfig/utils/getLabel.ts:22
|
||||
msgid "Hide Joplin"
|
||||
@@ -2095,6 +2098,7 @@ msgid "Keychain Supported: %s"
|
||||
msgstr "Unterstützter Schlüsselbund: %s"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:69
|
||||
#, fuzzy
|
||||
msgid "Keys that need upgrading"
|
||||
msgstr "Hauptschlüssel, die aktualisiert werden müssen"
|
||||
|
||||
@@ -2123,8 +2127,9 @@ msgid "Layout button sequence"
|
||||
msgstr "Layout-Reihenfolge"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/leaveSharedFolder.ts:7
|
||||
#, fuzzy
|
||||
msgid "Leave notebook..."
|
||||
msgstr "Verlasse Notizbuch..."
|
||||
msgstr "Notizbuch teilen..."
|
||||
|
||||
#: packages/lib/models/Setting.ts:1150
|
||||
msgid "Legal"
|
||||
@@ -2204,12 +2209,14 @@ msgid "Make a donation"
|
||||
msgstr "Spenden"
|
||||
|
||||
#: packages/app-desktop/gui/MasterPasswordDialog/Dialog.tsx:204
|
||||
#, fuzzy
|
||||
msgid "Manage master password"
|
||||
msgstr "Master-Passwort verwalten"
|
||||
msgstr "Master-Passwort eingeben:"
|
||||
|
||||
#: packages/lib/commands/openMasterPasswordDialog.ts:6
|
||||
#, fuzzy
|
||||
msgid "Manage master password..."
|
||||
msgstr "Master-Passwort verwalten..."
|
||||
msgstr "Master-Passwort eingeben:"
|
||||
|
||||
#: packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx:314
|
||||
msgid "Manage your plugins"
|
||||
@@ -2217,6 +2224,7 @@ msgstr "Erweiterungen verwalten"
|
||||
|
||||
#. `generate-ppk`
|
||||
#: packages/app-cli/app/command-e2ee.ts:20
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, "
|
||||
"`status`, `decrypt-file`, and `target-status`."
|
||||
@@ -2237,7 +2245,7 @@ msgstr "Markdown"
|
||||
#: packages/lib/services/interop/InteropService.ts:120
|
||||
#: packages/lib/services/interop/InteropService.ts:67
|
||||
msgid "Markdown + Front Matter"
|
||||
msgstr "Markdown + Front Matter"
|
||||
msgstr ""
|
||||
|
||||
#: packages/app-cli/app/command-done.js:14
|
||||
msgid "Marks a to-do as done."
|
||||
@@ -2271,8 +2279,9 @@ msgid "Max concurrent connections"
|
||||
msgstr "Maximale Anzahl an gleichzeitigen Verbindungen"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:322
|
||||
#, fuzzy
|
||||
msgid "Missing keys"
|
||||
msgstr "Fehlende Schlüssel"
|
||||
msgstr "Fehlende Hauptschlüssel"
|
||||
|
||||
#: packages/app-mobile/components/screens/encryption-config.tsx:271
|
||||
msgid "Missing Master Keys"
|
||||
@@ -2449,10 +2458,9 @@ msgstr ""
|
||||
msgid "Not downloaded"
|
||||
msgstr "Nicht heruntergeladen"
|
||||
|
||||
# I don't really know which one fits better: "erzeugt", "erstellt" or "generiert"...
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:250
|
||||
msgid "Not generated"
|
||||
msgstr "Nicht erzeugt"
|
||||
msgstr ""
|
||||
|
||||
#: packages/app-desktop/gui/NoteEditor/NoteTitle/NoteTitleBar.tsx:110
|
||||
#: packages/server/src/models/UserModel.ts:202
|
||||
@@ -2712,7 +2720,7 @@ msgstr "Berechtigung zur Verwendung der Kamera"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:269
|
||||
msgid "Please click on \"%s\" to proceed"
|
||||
msgstr "Klicke bitte auf \"%s\" um fortzufahren"
|
||||
msgstr ""
|
||||
|
||||
#: packages/lib/components/EncryptionConfigScreen/utils.ts:65
|
||||
msgid ""
|
||||
@@ -2733,8 +2741,6 @@ msgid ""
|
||||
"Please note that if it is a large notebook, it may take a few minutes for "
|
||||
"all the notes to show up on the recipient's device."
|
||||
msgstr ""
|
||||
"Wenn das Notizbuch sehr groß ist, kann es ein paar Minuten dauern, bis alle "
|
||||
"Notizen auf dem Empfängergerät erscheinen."
|
||||
|
||||
#: packages/lib/onedrive-api-node-utils.js:116
|
||||
msgid ""
|
||||
@@ -2877,7 +2883,7 @@ msgstr "Eigenschaften"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:250
|
||||
msgid "Public-private key pair:"
|
||||
msgstr "Öffentlich-Privates Schlüsselpaar:"
|
||||
msgstr ""
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/showShareNoteDialog.ts:6
|
||||
msgid "Publish note..."
|
||||
@@ -2985,8 +2991,9 @@ msgstr "Token erneuern"
|
||||
|
||||
#: packages/app-desktop/gui/MasterPasswordDialog/Dialog.tsx:204
|
||||
#: packages/app-desktop/gui/MasterPasswordDialog/Dialog.tsx:205
|
||||
#, fuzzy
|
||||
msgid "Reset master password"
|
||||
msgstr "Master-Passwort zurücksetzen"
|
||||
msgstr "Master-Passwort eingeben:"
|
||||
|
||||
#: packages/app-cli/app/command-import.js:51
|
||||
#: packages/app-desktop/gui/ImportScreen.min.js:72
|
||||
@@ -3142,12 +3149,11 @@ msgid "Set alarm:"
|
||||
msgstr "Alarm erstellen:"
|
||||
|
||||
#: packages/lib/models/Setting.ts:1039
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Set it to 0 to make it take the complete available space. Recommended width "
|
||||
"is 600."
|
||||
msgstr ""
|
||||
"Setze sie auf 0, um den gesamten verfügbaren Platz zu verwenden. Die "
|
||||
"empfohlene Breite ist 600."
|
||||
msgstr "Setze ihn auf 0, damit er den gesamten verfügbaren Platz einnimmt."
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/MainScreen.tsx:627
|
||||
msgid "Set the password"
|
||||
@@ -3200,8 +3206,9 @@ msgid "Show completed to-dos"
|
||||
msgstr "Abgeschlossene Aufgaben anzeigen"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:170
|
||||
#, fuzzy
|
||||
msgid "Show disabled keys"
|
||||
msgstr "Deaktivierte Schlüssel anzeigen"
|
||||
msgstr "Deaktivierte Hauptschlüssel anzeigen"
|
||||
|
||||
#: packages/lib/models/Setting.ts:781
|
||||
msgid "Show note counts"
|
||||
@@ -3581,7 +3588,7 @@ msgid ""
|
||||
"The attachments will no longer be watched when you switch to a different "
|
||||
"note."
|
||||
msgstr ""
|
||||
"Die Anhänge werden nicht mehr überwacht, wenn du zu einer anderen Notiz "
|
||||
"Die Anhänge werden nicht mehr überwacht, wenn Sie zu einer anderen Notiz "
|
||||
"wechseln."
|
||||
|
||||
#: packages/app-cli/app/app.js:304
|
||||
@@ -3632,23 +3639,24 @@ msgstr ""
|
||||
"Die Faktor-Eigenschaft legt fest, wie der Artikel wächst oder schrumpft, um "
|
||||
"dem verfügbaren Platz in seinem Container in Bezug auf die anderen Artikel "
|
||||
"zu entsprechen. Ein Element mit dem Faktor 2 benötigt also doppelt so viel "
|
||||
"Platz wie ein Element mit dem Faktor 1. Starte die App neu, um Änderungen zu "
|
||||
"sehen."
|
||||
"Platz wie ein Element mit dem Faktor 1. Starten Sie die App neu, um "
|
||||
"Änderungen zu sehen."
|
||||
|
||||
#: packages/app-desktop/gui/NoteEditor/NoteEditor.tsx:507
|
||||
msgid "The following attachments are being watched for changes:"
|
||||
msgstr "Die folgenden Anhänge werden auf Änderungen überwacht:"
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:70
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The following keys use an out-dated encryption algorithm and it is "
|
||||
"recommended to upgrade them. The upgraded key will still be able to decrypt "
|
||||
"and encrypt your data as usual."
|
||||
msgstr ""
|
||||
"Die folgenden Schlüssel verwenden einen veralteten "
|
||||
"Die folgenden Hauptschlüssel verwenden einen veralteten "
|
||||
"Verschlüsselungsalgorithmus und es wird empfohlen, sie zu aktualisieren. Der "
|
||||
"aktualisierte Schlüssel wird deine Daten weiterhin wie gewohnt entschlüsseln "
|
||||
"und verschlüsseln können."
|
||||
"aktualisierte Hauptschlüssel wird deine Daten weiterhin wie gewohnt "
|
||||
"entschlüsseln und verschlüsseln können."
|
||||
|
||||
#: packages/app-mobile/components/screens/Note.tsx:191
|
||||
msgid "The Joplin mobile app does not currently support this type of link: %s"
|
||||
@@ -3663,12 +3671,13 @@ msgstr ""
|
||||
"Leistung überprüft."
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:323
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"The keys with these IDs are used to encrypt some of your items, however the "
|
||||
"application does not currently have access to them. It is likely they will "
|
||||
"eventually be downloaded via synchronisation."
|
||||
msgstr ""
|
||||
"Die Schlüssel mit diesen IDs werden zur Verschlüsselung einiger deiner "
|
||||
"Die Hauptschlüssel mit diesen IDs werden zur Verschlüsselung einiger deiner "
|
||||
"Objekte verwendet, die Anwendung hat jedoch derzeit keinen Zugriff darauf. "
|
||||
"Es ist wahrscheinlich, dass sie irgendwann über die Synchronisation "
|
||||
"heruntergeladen werden."
|
||||
@@ -3711,10 +3720,6 @@ msgid ""
|
||||
"\n"
|
||||
"The error was: \"%s\""
|
||||
msgstr ""
|
||||
"Der Empfänger konnte nicht von der Liste entfernt werden. Bitte versuche es "
|
||||
"erneut.\n"
|
||||
"\n"
|
||||
"Der Fehler war: \"%s\""
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/MainScreen.tsx:585
|
||||
msgid ""
|
||||
@@ -3726,12 +3731,12 @@ msgstr ""
|
||||
"synchronisiert werden kann. Der Vorgang kann einige Minuten dauern, und die "
|
||||
"App muss neu gestartet werden. Um fortzufahren, klicke bitte auf den Link."
|
||||
|
||||
# "Klicke" or "Tippe"? Is it on mobile or desktop?
|
||||
#: packages/app-mobile/components/screen-header.js:459
|
||||
#, fuzzy
|
||||
msgid "The sync target needs to be upgraded. Press this banner to proceed."
|
||||
msgstr ""
|
||||
"Das Synchronisationsziel muss aktualisiert werden! Klicke auf diesen Banner, "
|
||||
"um fortzufahren."
|
||||
"Das Synchronisationsziel muss aktualisiert werden! Führe `%s` aus, um "
|
||||
"fortzufahren."
|
||||
|
||||
#: packages/lib/models/Tag.ts:204
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
@@ -3922,12 +3927,13 @@ msgstr ""
|
||||
"Diese Aktion wird ein neues Fenster öffnen. Aktuelle Änderungen speichern?"
|
||||
|
||||
#: packages/app-desktop/gui/MainScreen/commands/leaveSharedFolder.ts:13
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"This will remove the notebook from your collection and you will no longer "
|
||||
"have access to its content. Do you wish to continue?"
|
||||
msgstr ""
|
||||
"Das Notizbuch wird aus deiner Sammlung gelöscht und du wirst keinen Zugriff "
|
||||
"mehr darauf haben. Möchtest du fortfahren?"
|
||||
"Teilen des Notizbuch beenden? Der Empfänger wird keinen Zugriff mehr auf den "
|
||||
"Inhalt haben."
|
||||
|
||||
#: packages/lib/models/Setting.ts:709
|
||||
msgid "Time format"
|
||||
@@ -3951,8 +3957,9 @@ msgstr ""
|
||||
"folgenden Schritten:"
|
||||
|
||||
#: packages/lib/components/EncryptionConfigScreen/utils.ts:54
|
||||
#, fuzzy
|
||||
msgid "To continue, please enter your master password below."
|
||||
msgstr "Gib bitte das Master-Passwort unten ein um forzufahren."
|
||||
msgstr "Master-Passwort eingeben"
|
||||
|
||||
#: packages/app-cli/app/app-gui.js:452
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
@@ -4217,8 +4224,8 @@ msgstr ""
|
||||
#: packages/app-desktop/gui/MainScreen/MainScreen.tsx:825
|
||||
msgid "Use the arrows to move the layout items. Press \"Escape\" to exit."
|
||||
msgstr ""
|
||||
"Verwende die Pfeile, um die Layoutelemente zu verschieben. Drücke zum "
|
||||
"Beenden „Escape“."
|
||||
"Verwenden Sie die Pfeile, um die Layoutelemente zu verschieben. Drücken Sie "
|
||||
"zum Beenden „Escape“."
|
||||
|
||||
#: packages/app-mobile/components/screens/ConfigScreen.tsx:525
|
||||
msgid ""
|
||||
@@ -4364,7 +4371,7 @@ msgid ""
|
||||
"You are about to attach a large image (%dx%d pixels). Would you like to "
|
||||
"resize it down to %d pixels before attaching it?"
|
||||
msgstr ""
|
||||
"Du bist dabei, ein großes Bild (%dx%d Pixel) anzuhängen. Möchtest du es vor "
|
||||
"Sie sind dabei, ein großes Bild (%dx%d Pixel) anzuhängen. Möchten Sie es vor "
|
||||
"dem Anhängen auf %d Pixel verkleinern?"
|
||||
|
||||
#: packages/app-mobile/components/note-list.js:97
|
||||
@@ -4399,7 +4406,7 @@ msgstr "Deine Daten werden neu verschlüsselt und erneut synchronisiert."
|
||||
|
||||
#: packages/app-desktop/gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx:269
|
||||
msgid "Your master password is needed to decrypt some of your data."
|
||||
msgstr "Das Master-Passwort ist nötig um einige deiner Daten zu entschlüsseln."
|
||||
msgstr ""
|
||||
|
||||
#: packages/app-mobile/components/CameraView.tsx:189
|
||||
msgid "Your permission to use your camera is required."
|
||||
|
||||
@@ -6,20 +6,6 @@ const execa = require('execa');
|
||||
const { splitCommandString } = require('@joplin/lib/string-utils');
|
||||
const moment = require('moment');
|
||||
|
||||
export interface GitHubReleaseAsset {
|
||||
name: string;
|
||||
browser_download_url: string;
|
||||
}
|
||||
|
||||
export interface GitHubRelease {
|
||||
assets: GitHubReleaseAsset[];
|
||||
tag_name: string;
|
||||
upload_url: string;
|
||||
html_url: string;
|
||||
prerelease: boolean;
|
||||
draft: boolean;
|
||||
}
|
||||
|
||||
function quotePath(path: string) {
|
||||
if (!path) return '';
|
||||
if (path.indexOf('"') < 0 && path.indexOf(' ') < 0) return path;
|
||||
@@ -378,39 +364,7 @@ export function githubOauthToken() {
|
||||
return readCredentialFile('github_oauth_token.txt');
|
||||
}
|
||||
|
||||
// Note that the GitHub API releases/latest is broken on the joplin-android repo
|
||||
// as of Nov 2021 (last working on 3 November 2021, first broken on 19
|
||||
// November). It used to return the latest **published** release but now it
|
||||
// retuns... some release, always the same one, but not the latest one. GitHub
|
||||
// says that nothing has changed on the API, although it used to work. So since
|
||||
// we can't use /latest anymore, we need to fetch all the releases to find the
|
||||
// latest published one.
|
||||
export async function gitHubLatestRelease(repoName: string): Promise<GitHubRelease> {
|
||||
let pageNum = 1;
|
||||
|
||||
while (true) {
|
||||
const response: any = await fetch(`https://api.github.com/repos/laurent22/${repoName}/releases?page=${pageNum}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'Joplin Readme Updater',
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error(`Cannot fetch releases: ${response.statusText}`);
|
||||
|
||||
const releases = await response.json();
|
||||
if (!releases.length) throw new Error('Cannot find latest release');
|
||||
|
||||
for (const release of releases) {
|
||||
if (release.prerelease || release.draft) continue;
|
||||
return release;
|
||||
}
|
||||
|
||||
pageNum++;
|
||||
}
|
||||
}
|
||||
|
||||
export async function githubRelease(project: string, tagName: string, options: any = null): Promise<GitHubRelease> {
|
||||
export async function githubRelease(project: string, tagName: string, options: any = null) {
|
||||
options = Object.assign({}, {
|
||||
isDraft: false,
|
||||
isPreRelease: false,
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
import * as fs from 'fs-extra';
|
||||
import { fileExtension } from '@joplin/lib/path-utils';
|
||||
import { gitHubLatestRelease, GitHubRelease } from './tool-utils';
|
||||
const request = require('request');
|
||||
const readmePath = `${__dirname}/../../README.md`;
|
||||
|
||||
interface GitHubReleaseAsset {
|
||||
name: string;
|
||||
browser_download_url: string;
|
||||
}
|
||||
|
||||
interface GitHubRelease {
|
||||
assets: GitHubReleaseAsset[];
|
||||
tag_name: string;
|
||||
}
|
||||
|
||||
async function msleep(ms: number) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
@@ -11,6 +21,25 @@ async function msleep(ms: number) {
|
||||
});
|
||||
}
|
||||
|
||||
async function gitHubLatestRelease(repoName: string): Promise<GitHubRelease> {
|
||||
return new Promise((resolve, reject) => {
|
||||
request.get({
|
||||
url: `https://api.github.com/repos/laurent22/${repoName}/releases/latest`,
|
||||
json: true,
|
||||
headers: { 'User-Agent': 'Joplin Readme Updater' },
|
||||
}, (error: any, response: any, data: any) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else if (response.statusCode !== 200) {
|
||||
console.warn(data);
|
||||
reject(new Error(`Error HTTP ${response.statusCode}`));
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function downloadUrl(release: GitHubRelease, os: string, portable = false) {
|
||||
if (!release || !release.assets || !release.assets.length) return null;
|
||||
|
||||
@@ -93,8 +122,8 @@ async function main(argv: any) {
|
||||
// Disable for now due to broken /latest API end point, which returns a
|
||||
// version from 6 months ago.
|
||||
|
||||
if (androidUrl) content = content.replace(/(https:\/\/github.com\/laurent22\/joplin-android\/releases\/download\/android-v\d+\.\d+\.\d+\/joplin-v\d+\.\d+\.\d+\.apk)/, androidUrl);
|
||||
if (android32Url) content = content.replace(/(https:\/\/github.com\/laurent22\/joplin-android\/releases\/download\/android-v\d+\.\d+\.\d+\/joplin-v\d+\.\d+\.\d+-32bit\.apk)/, android32Url);
|
||||
// if (androidUrl) content = content.replace(/(https:\/\/github.com\/laurent22\/joplin-android\/releases\/download\/android-v\d+\.\d+\.\d+\/joplin-v\d+\.\d+\.\d+\.apk)/, androidUrl);
|
||||
// if (android32Url) content = content.replace(/(https:\/\/github.com\/laurent22\/joplin-android\/releases\/download\/android-v\d+\.\d+\.\d+\/joplin-v\d+\.\d+\.\d+-32bit\.apk)/, android32Url);
|
||||
|
||||
setReadmeContent(content);
|
||||
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
# Joplin Android app changelog
|
||||
|
||||
## [android-v2.6.4](https://github.com/laurent22/joplin/releases/tag/android-v2.6.4) (Pre-release) - 2021-12-01T11:38:49Z
|
||||
|
||||
- Improved: Also duplicate resources when duplicating a note (c0a8c33)
|
||||
- Improved: Improved S3 sync error handling and reliability, and upgraded S3 SDK (#5312 by Lee Matos)
|
||||
- Fixed: Alarm setting buttons were no longer visible (#5777)
|
||||
- Fixed: Alarms were not being triggered in some cases (#5798) (#5216 by Roman Musin)
|
||||
- Fixed: Fixed opening attachments (6950c40)
|
||||
- Fixed: Handle duplicate attachments when the parent notebook is shared (#5796)
|
||||
|
||||
## [android-v2.6.3](https://github.com/laurent22/joplin/releases/tag/android-v2.6.3) (Pre-release) - 2021-11-21T16:59:46Z
|
||||
|
||||
- New: Add date format YYYY/MM/DD (#5759 by Helmut K. C. Tessarek)
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
# Joplin Server Changelog
|
||||
|
||||
## [server-v2.6.14](https://github.com/laurent22/joplin/releases/tag/server-v2.6.14) - 2021-12-02T16:29:54Z
|
||||
|
||||
- Improved: Improved storage command (122afd6)
|
||||
|
||||
## [server-v2.6.13](https://github.com/laurent22/joplin/releases/tag/server-v2.6.13) - 2021-11-29T18:41:28Z
|
||||
|
||||
- New: Added command to delete database item content (01048f5)
|
||||
|
||||
@@ -62,25 +62,6 @@ Difficulty Level: High
|
||||
|
||||
Skills Required: TypeScript, JavaScript, knowledge of Electron and GitHub Actions.
|
||||
|
||||
## 5. Implement a toolbar for the mobile beta code editor
|
||||
|
||||
We would like the Beta code editor to eventually become the main editor, and for that a number of changes need to be made. The main one would be the addition of a toolbar to it, to set the various styles, such as Bold, Bullet list, Header, etc. Additionally there are number of bugs that will have to be fixed to get the editor ready for production - you will find them in the list of issues (under the "high" and "mobile" label).
|
||||
|
||||
Difficulty Level: High
|
||||
|
||||
Skills Required: TypeScript, JavaScript, React Native, React Hooks. You'll also need to learn about CodeMirror 6 if you're not already familiar with it.
|
||||
|
||||
## 6. Improve integration of the richtext/WYSIWYG editor
|
||||
|
||||
Joplin offers a richtext/WYSIWYG typing experience alongside the Markdown editor but there are a number of areas that could do with improvement when it comes to integration with Joplin as a whole.
|
||||
|
||||
Areas for consideration include increasing compatibility with Joplin-wide keybindings (many are currently static), limiting features of the editor not compatible with markdown formatting, reducing the impact of data changes caused by swapping between editors.
|
||||
Also read the document about limitations of the editor: [https://joplinapp.org/rich_text_editor/](https://joplinapp.org/rich_text_editor/)
|
||||
|
||||
Difficulty level: High
|
||||
|
||||
Skills Required: Typescript, Javascript, CSS, HTML, Markdown rendering. You will also need to learn about TinyMCE if you're not already familiar with it.
|
||||
|
||||
# More info
|
||||
|
||||
- Make sure you read the [Joplin Google Summer of Code Introduction](https://joplinapp.org/gsoc2022/index/)
|
||||
|
||||
Reference in New Issue
Block a user