Skip to content

Commit 8ebfb01

Browse files
committed
Merge branch 'dev' into main
2 parents d10dc54 + 1d7b5d6 commit 8ebfb01

53 files changed

Lines changed: 724 additions & 145 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/client/components.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ declare module '@vue/runtime-core' {
1919
DisplayBtn: typeof import('./src/components/DisplayBtn.vue')['default']
2020
EvaluatedPasswordField: typeof import('./src/components/EvaluatedPasswordField.vue')['default']
2121
Gap: typeof import('./src/components/Gap.vue')['default']
22+
Indicator: typeof import('./src/components/Indicator.vue')['default']
2223
InlineGap: typeof import('./src/components/InlineGap.vue')['default']
2324
LinkURL: typeof import('./src/components/LinkURL.vue')['default']
2425
LoadingOverlay: typeof import('./src/components/LoadingOverlay.vue')['default']
@@ -36,6 +37,7 @@ declare module '@vue/runtime-core' {
3637
TextEditor: typeof import('./src/components/TextEditor.vue')['default']
3738
TextField: typeof import('./src/components/TextField.vue')['default']
3839
ToolbarBtn: typeof import('./src/components/ToolbarBtn.vue')['default']
40+
TutorialTooltip: typeof import('./src/components/TutorialTooltip.vue')['default']
3941
ViewportLoadingOverlay: typeof import('./src/components/ViewportLoadingOverlay.vue')['default']
4042
}
4143
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
#Mon Aug 14 09:02:19 AMT 2023
2-
VERSION_CODE=47
1+
#Mon Aug 21 14:15:23 AMT 2023
2+
VERSION_CODE=52

apps/client/src-capacitor/android/variables.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
ext {
22
minSdkVersion = 22
3-
compileSdkVersion = 32
4-
targetSdkVersion = 32
3+
compileSdkVersion = 33
4+
targetSdkVersion = 33
55
androidxActivityVersion = '1.4.0'
66
androidxAppCompatVersion = '1.4.2'
77
androidxCoordinatorLayoutVersion = '1.2.0'

apps/client/src-capacitor/ios/App/App.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,14 +348,14 @@
348348
CODE_SIGN_IDENTITY = "Apple Development";
349349
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
350350
CODE_SIGN_STYLE = Manual;
351-
CURRENT_PROJECT_VERSION = 4;
351+
CURRENT_PROJECT_VERSION = 7;
352352
DEVELOPMENT_TEAM = "";
353353
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NK86B84G2A;
354354
INFOPLIST_FILE = App/Info.plist;
355355
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
356356
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
357357
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
358-
MARKETING_VERSION = 1.0.4;
358+
MARKETING_VERSION = 1.0.8;
359359
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
360360
PRODUCT_BUNDLE_IDENTIFIER = app.deepnotes;
361361
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -375,14 +375,14 @@
375375
CODE_SIGN_IDENTITY = "Apple Development";
376376
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
377377
CODE_SIGN_STYLE = Manual;
378-
CURRENT_PROJECT_VERSION = 4;
378+
CURRENT_PROJECT_VERSION = 7;
379379
DEVELOPMENT_TEAM = "";
380380
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = NK86B84G2A;
381381
INFOPLIST_FILE = App/Info.plist;
382382
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
383383
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
384384
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
385-
MARKETING_VERSION = 1.0.4;
385+
MARKETING_VERSION = 1.0.8;
386386
PRODUCT_BUNDLE_IDENTIFIER = app.deepnotes;
387387
PRODUCT_NAME = "$(TARGET_NAME)";
388388
PROVISIONING_PROFILE_SPECIFIER = "";

apps/client/src/code/pages/composables/use-keyboard-shortcuts.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ export function useKeyboardShortcuts() {
7575
return true;
7676
}
7777

78+
if (modsMatch(event, ['Alt', 'Shift']) && event.code === 'KeyQ') {
79+
page.selection.format((chain) => chain.toggleBlockquote());
80+
return true;
81+
}
7882
if (modsMatch(event, ['Alt', 'Shift']) && event.code === 'KeyC') {
7983
page.selection.format((chain) => chain.toggleCodeBlock());
8084
return true;
@@ -309,6 +313,28 @@ export function useKeyboardShortcuts() {
309313
return true;
310314
}
311315

316+
if (modsMatch(event, ['Control', 'Shift']) && event.code === 'Digit7') {
317+
page.selection.format((chain) => chain.toggleOrderedList());
318+
return true;
319+
}
320+
if (modsMatch(event, ['Control', 'Shift']) && event.code === 'Digit8') {
321+
page.selection.format((chain) => chain.toggleBulletList());
322+
return true;
323+
}
324+
if (modsMatch(event, ['Control', 'Shift']) && event.code === 'Digit9') {
325+
page.selection.format((chain) => chain.toggleTaskList());
326+
return true;
327+
}
328+
329+
if (modsMatch(event, ['Alt', 'Shift']) && event.code === 'KeyQ') {
330+
page.selection.format((chain) => chain.toggleBlockquote());
331+
return true;
332+
}
333+
if (modsMatch(event, ['Alt', 'Shift']) && event.code === 'KeyC') {
334+
page.selection.format((chain) => chain.toggleCodeBlock());
335+
return true;
336+
}
337+
312338
// Others
313339

314340
if (modsMatch(event, []) && event.code === 'F2' && activeElem != null) {

apps/client/src/code/pages/page/arrows/arrow.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,10 @@ export const PageArrow = once(
523523
grab(event: PointerEvent) {
524524
this.page.clickSelection.perform(this, event);
525525

526+
if (this.page.react.readOnly) {
527+
return;
528+
}
529+
526530
const path = document.querySelector(
527531
`#arrow-${this.id} .arrow`,
528532
) as SVGPathElement;

apps/client/src/code/pages/page/elems/find-and-replace.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Editor } from '@tiptap/vue-3';
1+
import type { Editor, Range } from '@tiptap/vue-3';
22
import { scrollIntoView } from 'src/code/utils/scroll-into-view';
33
import type { UnwrapNestedRefs } from 'vue';
44

@@ -251,7 +251,7 @@ export class PageFindAndReplace {
251251
return;
252252
}
253253

254-
editor.commands.insertContentAt(result, replacement);
254+
replaceText(editor, result, replacement);
255255

256256
if (!replacement.includes(this.findTerm)) {
257257
this.resultIndex--;
@@ -268,9 +268,17 @@ export class PageFindAndReplace {
268268
for (const result of (editor.state as any).findAndReplace$.results
269269
.slice()
270270
.reverse()) {
271-
editor.commands.insertContentAt(result, replacement);
271+
replaceText(editor, result, replacement);
272272
}
273273
}
274274
}
275275
}
276276
}
277+
278+
function replaceText(editor: Editor, range: Range, replacement: string) {
279+
if (replacement !== '') {
280+
editor.commands.insertContentAt(range, replacement);
281+
} else {
282+
editor.commands.deleteRange(range);
283+
}
284+
}

apps/client/src/code/pages/page/notes/cloning.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class NoteCloning {
88
this.page = input.page;
99
}
1010

11-
async perform() {
11+
async perform(options?: { shiftNotes?: boolean }) {
1212
if (this.page.react.readOnly) {
1313
return;
1414
}
@@ -21,11 +21,13 @@ export class NoteCloning {
2121

2222
// Shift notes before deserialization
2323

24-
for (const noteIndex of serialObject.root.noteIdxs) {
25-
const serialNote = serialObject.notes[noteIndex];
24+
if (options?.shiftNotes ?? true) {
25+
for (const noteIndex of serialObject.root.noteIdxs) {
26+
const serialNote = serialObject.notes[noteIndex];
2627

27-
serialNote.pos.x += 8;
28-
serialNote.pos.y += 8;
28+
serialNote.pos.x += 8;
29+
serialNote.pos.y += 8;
30+
}
2931
}
3032

3133
// Deserialize into structure

apps/client/src/code/pages/page/notes/dragging.ts

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { listenPointerEvents } from '@stdlib/misc';
22
import { Vec2 } from '@stdlib/misc';
33
import { refProp, watchUntilTrue } from '@stdlib/vue';
4+
import { isCtrlDown } from 'src/code/utils/misc';
45
import type { UnwrapRef } from 'vue';
56

67
import type { Page } from '../page';
78
import { roundTimeToMinutes } from './date';
9+
import type { PageNote } from './note';
810

911
export interface IDraggingReact {
1012
active: boolean;
1113

12-
currentPos: Vec2;
13-
1414
dropRegionId?: string;
1515
dropIndex?: number;
1616
}
@@ -23,57 +23,65 @@ export class NoteDragging {
2323
initialRegionId?: string;
2424
finalRegionId?: string;
2525

26+
initialPointerPos: Vec2 = new Vec2();
27+
originalNotePositions: Record<string, Vec2> = {};
28+
2629
private _cancelPointerEvents?: () => void;
2730

2831
constructor(input: { page: Page }) {
2932
this.page = input.page;
3033

3134
this.react = refProp<IDraggingReact>(this, 'react', {
3235
active: false,
33-
34-
currentPos: new Vec2(),
3536
});
3637
}
3738

38-
start(event: PointerEvent) {
39+
start(params: { note: PageNote; event: PointerEvent }) {
3940
if (this.page.react.readOnly) {
4041
return;
4142
}
4243

4344
// Prevent dragging unmovable notes
4445

4546
if (
46-
this.page.activeElem.react.value?.type !== 'note' ||
47+
this.page.activeElem.react.value?.type === 'note' &&
4748
!this.page.activeElem.react.value.react.collab.movable
4849
) {
49-
if (event.pointerType !== 'mouse') {
50-
this.page.panning.start(event);
50+
if (params.event.pointerType !== 'mouse') {
51+
this.page.panning.start(params.event);
5152
}
5253

5354
return;
5455
}
5556

56-
this.react = {
57-
active: false,
57+
this.react = { active: false };
5858

59-
currentPos: this.page.pos.eventToClient(event),
60-
};
59+
this.initialPointerPos = this.page.pos.eventToClient(params.event);
6160

62-
this._cancelPointerEvents = listenPointerEvents(event, {
61+
this._cancelPointerEvents = listenPointerEvents(params.event, {
6362
dragStartDistance: 5,
6463

65-
dragStart: this._dragStart,
64+
dragStart: () => this._dragStart(params),
6665
dragUpdate: this._dragUpdate,
6766
dragEnd: this._dragFinish,
6867
});
6968
}
7069

71-
private _dragStart = async (event: PointerEvent) => {
70+
private _dragStart = async (params: {
71+
note: PageNote;
72+
event: PointerEvent;
73+
}) => {
7274
this.react.active = true;
7375

7476
this.initialRegionId = this.page.activeRegion.react.value.id;
7577
this.finalRegionId = this.page.id;
7678

79+
if (isCtrlDown(params.event)) {
80+
this.page.selection.add(params.note);
81+
82+
await this.page.cloning.perform({ shiftNotes: false });
83+
}
84+
7785
// Update note dragging states
7886

7987
for (const selectedNote of this.page.selection.react.notes) {
@@ -90,23 +98,38 @@ export class NoteDragging {
9098
await this._dragOut();
9199
}
92100

93-
this._dragUpdate(event);
101+
// Store original note positions
102+
103+
this.originalNotePositions = {};
104+
105+
for (const selectedNote of this.page.selection.react.notes) {
106+
this.originalNotePositions[selectedNote.id] = new Vec2(
107+
selectedNote.react.collab.pos,
108+
);
109+
}
94110
};
95111

96112
private _dragUpdate = (event: PointerEvent) => {
97113
const clientPos = this.page.pos.eventToClient(event);
98114

99-
const worldDelta = this.page.sizes.screenToWorld2D(
100-
clientPos.sub(this.react.currentPos),
115+
const worldDiff = this.page.sizes.screenToWorld2D(
116+
clientPos.sub(this.initialPointerPos),
101117
);
102118

103-
this.react.currentPos = clientPos;
119+
if (event.shiftKey) {
120+
if (Math.abs(worldDiff.x) < Math.abs(worldDiff.y)) {
121+
worldDiff.x = 0;
122+
} else {
123+
worldDiff.y = 0;
124+
}
125+
}
104126

105127
// Move selected notes
106128

107129
this.page.collab.doc.transact(() => {
108130
for (const selectedNote of this.page.selection.react.notes) {
109-
const newPos = new Vec2(selectedNote.react.collab.pos).add(worldDelta);
131+
const newPos =
132+
this.originalNotePositions[selectedNote.id].add(worldDiff);
110133

111134
selectedNote.react.collab.pos.x = newPos.x || 0;
112135
selectedNote.react.collab.pos.y = newPos.y || 0;
@@ -182,7 +205,7 @@ export class NoteDragging {
182205

183206
this.page.collab.doc.transact(() => {
184207
for (const selectedNote of this.page.selection.react.notes) {
185-
const worldPos = this.page.pos.clientToWorld(this.react.currentPos);
208+
const worldPos = this.page.pos.clientToWorld(this.initialPointerPos);
186209
const mouseOffset = worldPos.sub(prevCenters.get(activeElem.id)!);
187210

188211
const prevCenter = prevCenters.get(selectedNote.id)!;

apps/client/src/code/pages/page/notes/note.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ export class PageNote extends PageElem() implements IPageRegion {
336336
self: computed(() => {
337337
if (
338338
this.react.collapsing.collapsed &&
339-
!isNumeric(this.react.collab.width.collapsed)
339+
!isNumeric(this.react.collab.width.collapsed) &&
340+
this.react.collab.width.collapsed !== 'Minimum'
340341
) {
341342
return this.react.collab.width.expanded;
342343
}
@@ -457,6 +458,14 @@ export class PageNote extends PageElem() implements IPageRegion {
457458
}),
458459

459460
cursor: computed(() => {
461+
if (this.page.react.readOnly) {
462+
if (this.react.link.url) {
463+
return 'pointer';
464+
} else {
465+
return 'auto';
466+
}
467+
}
468+
460469
if (this.react.editing) {
461470
return 'auto';
462471
}
@@ -536,11 +545,18 @@ export class PageNote extends PageElem() implements IPageRegion {
536545

537546
getElem(part: string | null): HTMLElement | null {
538547
if (part == null) {
539-
return document.getElementById(`note-${this.id}`);
548+
return document.querySelector(`#note-${this.id}`);
540549
} else {
541550
return document.querySelector(`#note-${this.id} .${part}`);
542551
}
543552
}
553+
getElems(part: string | null): HTMLElement[] {
554+
if (part == null) {
555+
return Array.from(document.querySelectorAll(`#note-${this.id}`));
556+
} else {
557+
return Array.from(document.querySelectorAll(`#note-${this.id} .${part}`));
558+
}
559+
}
544560

545561
scrollIntoView() {
546562
if (this.react.region.type === 'page') {

0 commit comments

Comments
 (0)