diff --git a/packages/lib/WelcomeUtils.test.ts b/packages/lib/WelcomeUtils.test.ts index 8f1394cfd4..5c8ae88a7b 100644 --- a/packages/lib/WelcomeUtils.test.ts +++ b/packages/lib/WelcomeUtils.test.ts @@ -1,7 +1,8 @@ import { setupDatabaseAndSynchronizer, switchClient } from './testing/test-utils'; -import WelcomeUtils from './WelcomeUtils'; +import WelcomeUtils, { WelcomeAssetPlatform } from './WelcomeUtils'; import Folder from './models/Folder'; import { FolderIconType } from './services/database/types'; +import Note from './models/Note'; describe('WelcomeUtils', () => { @@ -11,7 +12,7 @@ describe('WelcomeUtils', () => { }); it('should create welcome items with waving hand emoji icon for the folder', async () => { - const result = await WelcomeUtils.createWelcomeItems('en_GB'); + const result = await WelcomeUtils.createWelcomeItems('en_GB', WelcomeAssetPlatform.Desktop); expect(result.defaultFolderId).toBeTruthy(); @@ -23,4 +24,21 @@ describe('WelcomeUtils', () => { expect(icon.emoji).toBe('👋'); }); + + it.each([ + WelcomeAssetPlatform.Web, WelcomeAssetPlatform.Desktop, + ])('should create web welcome notes only on web (testing platform: %s)', async (platform) => { + const result = await WelcomeUtils.createWelcomeItems('en_GB', platform); + + const notes = await Note.previews(result.defaultFolderId); + + const webAppNoteTitle = '0. About the web app'; + const noteTitles = notes.map(note => note.title); + + if (platform === WelcomeAssetPlatform.Web) { + expect(noteTitles).toContain(webAppNoteTitle); + } else { + expect(noteTitles).not.toContain(webAppNoteTitle); + } + }); }); diff --git a/packages/lib/WelcomeUtils.ts b/packages/lib/WelcomeUtils.ts index 85d109d0d2..c886689c38 100644 --- a/packages/lib/WelcomeUtils.ts +++ b/packages/lib/WelcomeUtils.ts @@ -2,15 +2,23 @@ const welcomeAssetsAny = require('./welcomeAssets'); import Note from './models/Note'; import Setting from './models/Setting'; import Folder from './models/Folder'; -import shim from './shim'; +import shim, { MobilePlatform } from './shim'; import uuid from './uuid'; import { fileExtension, basename } from './path-utils'; import { _ } from './locale'; const { pregQuote } = require('./string-utils'); import { FolderIconType } from './services/database/types'; +export enum WelcomeAssetPlatform { + Desktop = 'desktop', + Cli = 'cli', + Mobile = 'mobile', + Web = 'web', +} + export interface ItemMetadatum { id: string; + platform?: WelcomeAssetPlatform; } export type ItemMetadata = Record; @@ -30,6 +38,7 @@ export interface WelcomeAssetNote { title: string; body: string; resources: Record; + platform?: WelcomeAssetPlatform; } export interface WelcomeAssetFolder { @@ -47,7 +56,7 @@ export type WelcomeAssets = Record; class WelcomeUtils { - public static async createWelcomeItems(locale: string): Promise { + public static async createWelcomeItems(locale: string, platform: WelcomeAssetPlatform): Promise { const output: CreateWelcomeItemsResult = { defaultFolderId: null, }; @@ -80,6 +89,10 @@ class WelcomeUtils { const noteAsset = noteAssets[i]; const enGbNoteAsset = enGbWelcomeAssets.notes[i]; + if (noteAsset.platform && noteAsset.platform !== platform) { + continue; + } + let noteBody = noteAsset.body; for (const resourceUrl in enGbNoteAsset.resources) { @@ -109,6 +122,18 @@ class WelcomeUtils { return output; } + private static detectPlatform_() { + if (shim.mobilePlatform() === MobilePlatform.Web) { + return WelcomeAssetPlatform.Web; + } else if (shim.mobilePlatform()) { + return WelcomeAssetPlatform.Mobile; + } else if (shim.isElectron()) { + return WelcomeAssetPlatform.Desktop; + } else { + return WelcomeAssetPlatform.Cli; + } + } + // eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied public static async install(locale: string, dispatch: Function) { if (!Setting.value('welcome.enabled')) { @@ -117,7 +142,7 @@ class WelcomeUtils { } if (!Setting.value('welcome.wasBuilt')) { - const result = await WelcomeUtils.createWelcomeItems(locale); + const result = await WelcomeUtils.createWelcomeItems(locale, this.detectPlatform_()); Setting.setValue('welcome.wasBuilt', true); dispatch({ diff --git a/packages/lib/services/synchronizer/Synchronizer.basics.test.ts b/packages/lib/services/synchronizer/Synchronizer.basics.test.ts index 044649dfb4..f3b54202a8 100644 --- a/packages/lib/services/synchronizer/Synchronizer.basics.test.ts +++ b/packages/lib/services/synchronizer/Synchronizer.basics.test.ts @@ -4,7 +4,7 @@ import { syncTargetName, afterAllCleanUp, synchronizerStart, setupDatabaseAndSyn import Folder from '../../models/Folder'; import Note from '../../models/Note'; import BaseItem from '../../models/BaseItem'; -import WelcomeUtils from '../../WelcomeUtils'; +import WelcomeUtils, { WelcomeAssetPlatform } from '../../WelcomeUtils'; import { NoteEntity } from '../database/types'; import { fetchSyncInfo, setAppMinVersion, uploadSyncInfo } from './syncInfoUtils'; import { ErrorCode } from '../../errors'; @@ -355,12 +355,12 @@ describe('Synchronizer.basics', () => { it('should create a new Welcome notebook on each client', (async () => { // Create the Welcome items on two separate clients - await WelcomeUtils.createWelcomeItems('en_GB'); + await WelcomeUtils.createWelcomeItems('en_GB', WelcomeAssetPlatform.Cli); await synchronizerStart(); await switchClient(2); - await WelcomeUtils.createWelcomeItems('en_GB'); + await WelcomeUtils.createWelcomeItems('en_GB', WelcomeAssetPlatform.Cli); const beforeFolderCount = (await Folder.all()).length; const beforeNoteCount = (await Note.all()).length; expect(beforeFolderCount === 1).toBe(true); diff --git a/packages/lib/welcomeAssets.js b/packages/lib/welcomeAssets.js index bfbb010bdc..b43de3d809 100644 --- a/packages/lib/welcomeAssets.js +++ b/packages/lib/welcomeAssets.js @@ -1,6 +1,14 @@ module.exports = { "en_GB": { "notes": [ + { + "id": "4ec2e7505fc2e7505ec2e7505ec2a751", + "platform": "web", + "title": "0. About the web app", + "body": "# About the web app\n\nThe web app provides access to Joplin from a web browser.\n\nLike the desktop and mobile apps, the web app is local-first. Notes and attachments are stored locally on your computer, but can optionally be synced to the cloud.\n", + "resources": {}, + "parent_id": "9bb5d498aba74cc6a047cfdc841e82a1" + }, { "id": "8a1556e382704160808e9a7bef7135d3", "title": "1. Welcome to Joplin!", diff --git a/packages/tools/build-welcome.ts b/packages/tools/build-welcome.ts index 42b3ae3340..550c5b77cb 100644 --- a/packages/tools/build-welcome.ts +++ b/packages/tools/build-welcome.ts @@ -2,7 +2,7 @@ import { readFileSync, readdirSync, writeFileSync } from 'fs-extra'; import { dirname } from 'path'; import { fileExtension, basename } from '@joplin/lib/path-utils'; import markdownUtils from '@joplin/lib/markdownUtils'; -import { AssetContent, ItemMetadata, WelcomeAssetNote, WelcomeAssetResource, WelcomeAssets } from '@joplin/lib/WelcomeUtils'; +import { AssetContent, ItemMetadata, WelcomeAssetNote, WelcomeAssetPlatform, WelcomeAssetResource, WelcomeAssets } from '@joplin/lib/WelcomeUtils'; const rootDir = dirname(dirname(__dirname)); const enWelcomeDir = `${rootDir}/readme/welcome`; @@ -10,6 +10,10 @@ const enWelcomeDir = `${rootDir}/readme/welcome`; const createdDate = new Date('2018-06-22T12:00:00Z'); const itemMetadata_: ItemMetadata = { + '0_web.md': { + id: '4ec2e7505fc2e7505ec2e7505ec2a751', + platform: WelcomeAssetPlatform.Web, + }, '1_welcome_to_joplin.md': { id: '8a1556e382704160808e9a7bef7135d3', }, @@ -81,6 +85,10 @@ function itemIdFromPath(metadata: ItemMetadata, path: string) { return md.id; } +function itemPlatformFromPath(metadata: ItemMetadata, path: string) { + return itemMetadata(metadata, path).platform; +} + function fileToBase64(filePath: string) { const content = readFileSync(filePath); return Buffer.from(content).toString('base64'); @@ -110,6 +118,7 @@ function parseNoteFile(metadata: ItemMetadata, locale: string, filePath: string) return { id: itemIdFromPath(metadata, filePath), + platform: itemPlatformFromPath(metadata, filePath), title: title, body: body, resources: resources, diff --git a/readme/welcome/0_web.md b/readme/welcome/0_web.md new file mode 100644 index 0000000000..f7b3bdde72 --- /dev/null +++ b/readme/welcome/0_web.md @@ -0,0 +1,8 @@ +# About the web app + +The web app provides access to Joplin from a web browser. + +Like the desktop and mobile apps, the web app is local-first: +- Notes and attachments are stored locally on your computer. Changes are saved even if offline. +- [Synchronisation](https://joplinapp.org/help/apps/sync/) needs to be enabled/configured to sync data to the cloud. +- Until synchronisation is configured, each different browser/profile will have a different note collection.