Skip to content

Commit cea38cd

Browse files
authored
Merge pull request #338 from fccview/develop
Lift off!
2 parents 7376def + 0ddab91 commit cea38cd

44 files changed

Lines changed: 853 additions & 353 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
<p align="center">
2-
<a href="http://discord.gg/invite/mMuk2WzVZu">
3-
<img width="40" src="https://github.com/fccview/jotty/blob/main/public/repo-images/discord_icon.webp?raw=true">
2+
<a href="https://discord.gg/invite/mMuk2WzVZu">
3+
<img width="40" src="https://skills.syvixor.com/api/icons?i=discord">
4+
</a>
5+
<a href="https://www.reddit.com/r/jotty">
6+
<img width="40" src="https://skills.syvixor.com/api/icons?i=reddit">
7+
</a>
8+
<a href="https://t.me/jottypage">
9+
<img width="40" src="https://skills.syvixor.com/api/icons?i=telegram">
410
</a>
511
<br />
6-
<i>Join the discord to stay up to date and have early previews</i>
12+
<br />
13+
<i>Join our communities</i>
714
<br />
815
</p>
916

@@ -14,13 +21,17 @@
1421
# Changelog
1522

1623
**bugfixes**
24+
1725
<!-- Enter all bugfixes here and tag the relative issue -->
1826

1927
**features**
28+
2029
<!-- Enter all features here and tag the relative issue -->
2130

2231
**New api endpoints**
32+
2333
<!-- Enter all new api endpoints here -->
2434

2535
**Translations**
26-
<!-- Enter all new translations here -->
36+
37+
<!-- Enter all new translations here -->

app/_components/FeatureComponents/Admin/Parts/AdminUsers.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export const AdminUsers = ({
127127
size="sm"
128128
onClick={() => onEditUser(user)}
129129
className="h-8 w-8 p-0"
130-
title={user.isSuperAdmin && !isSuperAdmin ? t("admin.systemOwner") : t('admin.editUser')}
130+
aria-label={user.isSuperAdmin && !isSuperAdmin ? t("admin.systemOwner") : t('admin.editUser')}
131131
disabled={user.isSuperAdmin && !isSuperAdmin}
132132
>
133133
<UserEdit01Icon className="h-4 w-4" />
@@ -139,7 +139,7 @@ export const AdminUsers = ({
139139
onClick={() => onDeleteUser(user)}
140140
disabled={deletingUser === user.username || (user.isSuperAdmin && !isSuperAdmin)}
141141
className="h-8 w-8 p-0"
142-
title={user.isSuperAdmin && !isSuperAdmin ? t("admin.cannotDeleteSuperAdmin") : t('admin.deleteUser')}
142+
aria-label={user.isSuperAdmin && !isSuperAdmin ? t("admin.cannotDeleteSuperAdmin") : t('admin.deleteUser')}
143143
>
144144
{deletingUser === user.username ? (
145145
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-destructive mx-auto"></div>

app/_components/FeatureComponents/Checklists/Parts/Common/ChecklistHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export const ChecklistHeader = ({
163163
<DropdownMenu
164164
align="right"
165165
trigger={
166-
<Button variant="outline" size="sm" className="h-10 w-10 p-0">
166+
<Button variant="outline" size="sm" className="h-10 w-10 p-0" aria-label={t("common.moreOptions")}>
167167
<MoreHorizontalIcon className="h-4 w-4" />
168168
</Button>
169169
}

app/_components/FeatureComponents/Checklists/Parts/Common/ChecklistHeading.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export const ChecklistHeading = ({
165165
variant="outline"
166166
size="icon"
167167
onClick={() => setInputToggled(!inputToggled)}
168+
aria-label={inputToggled ? t("common.close") : t("common.add")}
168169
>
169170
{!inputToggled ? (
170171
<PlusSignIcon className="h-5 w-5" />

app/_components/FeatureComponents/Checklists/Parts/Simple/ChecklistBody.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ export const ChecklistBody = ({
203203
}
204204
isAnyItemDragging={isDragging}
205205
overItem={overItem}
206+
draggedItemId={activeItem?.id}
206207
/>
207208
<DropIndicator
208209
id={`drop-after::${item.id}`}
@@ -273,6 +274,7 @@ export const ChecklistBody = ({
273274
}
274275
isAnyItemDragging={isDragging}
275276
overItem={overItem}
277+
draggedItemId={activeItem?.id}
276278
/>
277279
<DropIndicator
278280
id={`drop-after::${item.id}`}

app/_components/FeatureComponents/Checklists/Parts/Simple/Droppable.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,26 @@ interface DroppableProps {
88
data: Record<string, unknown>;
99
children: ReactNode | ((props: { isOver: boolean }) => ReactNode);
1010
className?: string;
11+
disabled?: boolean;
1112
}
1213

1314
export const Droppable = ({
1415
id,
1516
data,
1617
children,
1718
className,
19+
disabled = false,
1820
}: DroppableProps) => {
21+
const [showDropIntoIndicator, setShowDropIntoIndicator] = useState(false);
22+
1923
const { setNodeRef, isOver, active } = useDroppable({
2024
id,
21-
data,
25+
data: {
26+
...data,
27+
allowDropInto: showDropIntoIndicator && !disabled,
28+
},
29+
disabled,
2230
});
23-
const [showDropIntoIndicator, setShowDropIntoIndicator] = useState(false);
2431

2532
useEffect(() => {
2633
if (!isOver || !active) {

app/_components/FeatureComponents/Checklists/Parts/Simple/NestedChecklistItem.tsx

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ interface NestedChecklistItemProps {
4848
overPosition?: "before" | "after";
4949
isAnyItemDragging?: boolean;
5050
overItem?: { id: string; position: "before" | "after" } | null;
51+
draggedItemId?: string;
5152
}
5253

5354
const NestedChecklistItemComponent = ({
@@ -68,6 +69,7 @@ const NestedChecklistItemComponent = ({
6869
overPosition,
6970
isAnyItemDragging = false,
7071
overItem = null,
72+
draggedItemId,
7173
}: NestedChecklistItemProps) => {
7274
const t = useTranslations();
7375
const { usersPublicData, user } = useAppMode();
@@ -239,13 +241,16 @@ const NestedChecklistItemComponent = ({
239241
}
240242
}, [item.children, hasChildren]);
241243

244+
const isBeingDragged = draggedItemId === item.id;
245+
242246
return (
243247
<Droppable
244248
id={`drop-into-item::${item.id}`}
245249
data={{
246250
type: "item",
247251
itemId: item.id,
248252
}}
253+
disabled={isBeingDragged}
249254
>
250255
{({ isOver: isOverDroppable }) => (
251256
<div
@@ -397,7 +402,7 @@ const NestedChecklistItemComponent = ({
397402
size="sm"
398403
onClick={() => setShowAddSubItem(!showAddSubItem)}
399404
className="h-8 w-8 p-0"
400-
title={t("checklists.addSubItem")}
405+
aria-label={t("checklists.addSubItem")}
401406
>
402407
<Add01Icon className="h-4 w-4" />
403408
</Button>
@@ -409,6 +414,7 @@ const NestedChecklistItemComponent = ({
409414
size="sm"
410415
onClick={handleEdit}
411416
className="h-8 w-8 p-0"
417+
aria-label={t("common.edit")}
412418
>
413419
<PencilEdit02Icon className="h-4 w-4" />
414420
</Button>
@@ -420,6 +426,7 @@ const NestedChecklistItemComponent = ({
420426
size="sm"
421427
onClick={() => onDelete(item.id)}
422428
className="h-8 w-8 p-0"
429+
aria-label={t("common.delete")}
423430
>
424431
<Delete03Icon className="h-4 w-4" />
425432
</Button>
@@ -434,6 +441,7 @@ const NestedChecklistItemComponent = ({
434441
size="sm"
435442
onClick={handleDropdownToggle}
436443
className="h-8 w-8 p-0"
444+
aria-label={t("common.moreOptions")}
437445
>
438446
<MoreHorizontalIcon className="h-4 w-4" />
439447
</Button>
@@ -473,6 +481,7 @@ const NestedChecklistItemComponent = ({
473481
size="sm"
474482
onClick={() => setIsExpanded(!isExpanded)}
475483
className="h-6 w-6 p-0"
484+
aria-label={isExpanded ? t("common.collapseAll") : t("common.expandAll")}
476485
>
477486
{isExpanded ? (
478487
<ArrowDown01Icon className="h-4 w-4" />
@@ -508,7 +517,7 @@ const NestedChecklistItemComponent = ({
508517
size="sm"
509518
disabled={!newSubItemText.trim()}
510519
className="h-8 w-8 p-0"
511-
title={t("common.add")}
520+
aria-label={t("common.add")}
512521
>
513522
<Add01Icon className="h-4 w-4" />
514523
</Button>
@@ -521,6 +530,7 @@ const NestedChecklistItemComponent = ({
521530
setNewSubItemText("");
522531
}}
523532
className="h-8 w-8 p-0"
533+
aria-label={t("common.close")}
524534
>
525535
<MultiplicationSignIcon className="h-4 w-4" />
526536
</Button>
@@ -530,17 +540,19 @@ const NestedChecklistItemComponent = ({
530540

531541
{hasChildren && isExpanded && (
532542
<div className={cn("pt-1")}>
533-
<DropIndicator
534-
id={`drop-before-child::${
535-
item.children![0]?.id || `${item.id}-start`
536-
}`}
537-
data={{
538-
type: "drop-indicator",
539-
position: "before",
540-
targetId: item.children![0]?.id,
541-
parentId: item.id,
542-
}}
543-
/>
543+
{draggedItemId !== item.id && (
544+
<DropIndicator
545+
id={`drop-before-child::${
546+
item.children![0]?.id || `${item.id}-start`
547+
}`}
548+
data={{
549+
type: "drop-indicator",
550+
position: "before",
551+
targetId: item.children![0]?.id,
552+
parentId: item.id,
553+
}}
554+
/>
555+
)}
544556
{item.children!.map((child, childIndex) => (
545557
<div key={child.id}>
546558
<NestedChecklistItem
@@ -552,7 +564,7 @@ const NestedChecklistItemComponent = ({
552564
onEdit={onEdit}
553565
onAddSubItem={onAddSubItem}
554566
isDeletingItem={isDeletingItem}
555-
isDragDisabled={isDragDisabled}
567+
isDragDisabled={isDragDisabled || draggedItemId === item.id}
556568
isPublicView={isPublicView}
557569
checklist={checklist}
558570
isOver={overItem?.id === child.id}
@@ -561,16 +573,19 @@ const NestedChecklistItemComponent = ({
561573
}
562574
isAnyItemDragging={isAnyItemDragging}
563575
overItem={overItem}
576+
draggedItemId={draggedItemId}
564577
/>
565-
<DropIndicator
566-
id={`drop-after-child::${child.id}`}
567-
data={{
568-
type: "drop-indicator",
569-
position: "after",
570-
targetId: child.id,
571-
parentId: item.id,
572-
}}
573-
/>
578+
{draggedItemId !== item.id && (
579+
<DropIndicator
580+
id={`drop-after-child::${child.id}`}
581+
data={{
582+
type: "drop-indicator",
583+
position: "after",
584+
targetId: child.id,
585+
parentId: item.id,
586+
}}
587+
/>
588+
)}
574589
</div>
575590
))}
576591
</div>

app/_components/FeatureComponents/Header/QuickNav.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { NavigationSearchIcon } from "../Navigation/Parts/NavigationSearchIcon";
1818
import { UserDropdown } from "../Navigation/Parts/UserDropdown";
1919
import { logout } from "@/app/_server/actions/auth";
2020
import { useState, useEffect, useRef } from "react";
21+
import { useTranslations } from "next-intl";
2122

2223
interface QuickNavProps {
2324
showSidebarToggle?: boolean;
@@ -41,6 +42,7 @@ export const QuickNav = ({
4142
const router = useRouter();
4243
const { mode } = useAppMode();
4344
const { checkNavigation } = useNavigationGuard();
45+
const t = useTranslations();
4446
const [isScrolled, setIsScrolled] = useState(true);
4547
const lastScrollY = useRef(0);
4648

@@ -84,6 +86,7 @@ export const QuickNav = ({
8486
size="icon"
8587
onClick={onSidebarToggle}
8688
className="lg:hidden jotty-mobile-navigation-icon"
89+
aria-label={t("common.toggleSidebar")}
8790
>
8891
<SidebarLeftIcon className="h-6 w-6" />
8992
</Button>
@@ -105,6 +108,7 @@ export const QuickNav = ({
105108
size="icon"
106109
onClick={handleLogout}
107110
className="jotty-mobile-navigation-icon"
111+
aria-label={t("common.logout")}
108112
>
109113
<Logout01Icon className="h-5 w-5" />
110114
</Button>

app/_components/FeatureComponents/Navigation/Parts/NavigationSearchIcon.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useAppMode } from "@/app/_providers/AppModeProvider";
66
import { AppMode } from "@/app/_types";
77
import { useNavigationGuard } from "@/app/_providers/NavigationGuardProvider";
88
import { useShortcut } from "@/app/_providers/ShortcutsProvider";
9+
import { useTranslations } from "next-intl";
910

1011
interface NavigationSearchIconProps {
1112
onModeChange?: (mode: AppMode) => void;
@@ -17,6 +18,7 @@ export const NavigationSearchIcon = ({
1718
const { checkNavigation } = useNavigationGuard();
1819
const { mode } = useAppMode();
1920
const { isSearchOpen, toggleSearch, closeSearch } = useShortcut();
21+
const t = useTranslations();
2022

2123
return (
2224
<>
@@ -64,6 +66,7 @@ export const NavigationSearchIcon = ({
6466
className="jotty-mobile-navigation-icon"
6567
size="icon"
6668
onClick={toggleSearch}
69+
aria-label={isSearchOpen ? t("common.closeSearch") : t("common.openSearch")}
6770
>
6871
{isSearchOpen ? (
6972
<MultiplicationSignIcon className="h-5 w-5" />

app/_components/FeatureComponents/Notes/Parts/NoteEditor/NoteEditorHeader.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ export const NoteEditorHeader = ({
265265
size="icon"
266266
onClick={onBack}
267267
className="h-8 w-8 flex-shrink-0"
268+
aria-label={t("common.back")}
268269
>
269270
<ArrowLeft01Icon className="h-5 w-5" />
270271
</Button>
@@ -378,7 +379,7 @@ export const NoteEditorHeader = ({
378379
</Button>
379380

380381
<div className={`fixed bottom-[20px] ${user?.handedness === "left-handed" ? "left-[2.5%]" : "right-[2.5%]"} lg:hidden z-50 flex flex-col gap-1 bg-background border border-border rounded-jotty p-1`}>
381-
<Button variant="outline" size="icon" onClick={handleCancel}>
382+
<Button variant="outline" size="icon" onClick={handleCancel} aria-label={t("common.cancel")}>
382383
<Cancel01Icon className="h-5 w-5" />
383384
</Button>
384385

@@ -394,7 +395,7 @@ export const NoteEditorHeader = ({
394395
}}
395396
className="h-10 w-10"
396397
disabled={status.isSaving || status.isAutoSaving}
397-
title={status.isSaving ? t('common.saving') : t('common.save')}
398+
aria-label={status.isSaving ? t('common.saving') : t('common.save')}
398399
>
399400
{status.isSaving ? (
400401
<Logo
@@ -417,7 +418,7 @@ export const NoteEditorHeader = ({
417418
variant="outline"
418419
size="icon"
419420
onClick={() => handleSave()}
420-
title={t("notes.quickSave")}
421+
aria-label={t("notes.quickSave")}
421422
className="text-primary hover:text-primary/80"
422423
>
423424
{status.isSaving ? (
@@ -447,7 +448,7 @@ export const NoteEditorHeader = ({
447448
handleEdit();
448449
}
449450
}}
450-
title={note?.encrypted ? t('encryption.editEncrypted') : t('common.edit')}
451+
aria-label={note?.encrypted ? t('encryption.editEncrypted') : t('common.edit')}
451452
>
452453
{note?.encrypted ? (
453454
<MessageLock02Icon className="h-5 w-5" />
@@ -459,7 +460,7 @@ export const NoteEditorHeader = ({
459460
<DropdownMenu
460461
align="right"
461462
trigger={
462-
<Button variant="outline" size="icon">
463+
<Button variant="outline" size="icon" aria-label={t("common.moreOptions")}>
463464
<MoreHorizontalIcon className="h-5 w-5" />
464465
</Button>
465466
}

0 commit comments

Comments
 (0)