Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions firestore.rules
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ service cloud.firestore {

function isRequestorViewer(uid) {
return
"scopeOverwrite" in resource.data &&
!resource.data.scopeOverwrite &&
"viewersFlat" in resource.data &&
uid in resource.data.viewersFlat;
}
Expand Down
16 changes: 13 additions & 3 deletions src/db/howtos/HowToDatabase.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ const HowToSchemaV1 = z.object({
viewers: z.record(z.string(), z.array(z.string())),
/** Flat version of viewers, calculated in a firestore function, for firestore rule queries */
viewersFlat: z.array(z.string()),
/** If the user wants to overwrite the scope set by the gallery curator */
/** True if the user restricts access to the how-to to only those who have direct access to the gallery
* I.e., overwrites the gallery curator "expanding" how-to viewing permissions
*/
scopeOverwrite: z.boolean(),
/** Locales that the how-to depends on All ISO 639-1 languaage codes, followed by a -, followed by ISO 3166-2 region code: https://en.wikipedia.org/wiki/ISO_3166-2 */
locales: z.array(z.string()),
Expand Down Expand Up @@ -239,6 +241,10 @@ export default class HowTo {
return this.data.social.viewCount;
}

getScopeOverwrite() {
return this.data.scopeOverwrite;
}

getData() {
return { ...this.data };
}
Expand Down Expand Up @@ -345,6 +351,7 @@ export class HowToDatabase {
locales: string[],
reactionTypes: Record<string, string>,
notify: boolean,
overwriteAccessScope: boolean,
): Promise<HowTo | undefined | false> {
if (firestore === undefined) return undefined;
const user = this.db.getUser()?.uid;
Expand Down Expand Up @@ -384,7 +391,7 @@ export class HowToDatabase {
collaborators: collaborators,
viewers: {} as Record<string, string[]>,
viewersFlat: [] as string[],
scopeOverwrite: false,
scopeOverwrite: overwriteAccessScope,
locales: locales,
social: newHowToSocial,
};
Expand Down Expand Up @@ -488,7 +495,10 @@ export class HowToDatabase {
or(
or(...creatorOrCollaborator),
or(...editorGalleryConstraints),
where('viewersFlat', 'array-contains', userId),
and(
where('scopeOverwrite', '==', false),
where('viewersFlat', 'array-contains', userId)
),
),
);

Expand Down
21 changes: 20 additions & 1 deletion src/locale/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -4559,10 +4559,29 @@
"placeholder": "Title"
},
"titlePlaceholder": "Untitled how-to",
"collaboratorsPrompt": "Add a collaborator, who can edit this how-to",
"collaborators": {
"header": "👥 collaborators",
"explanation": "Collaborators can edit this how-to and view it in drafts."
},
"collaboratorsToggle": {
"on": "collapse the collaborators panel",
"off": "expand the collaborators panel"
},
"access": {
"header": "↗ share",
"explanation": "The curator of this gallery can let creators and curators of other galleries they curate view this how-to. If you don't want them to be able to view it, you can restrict who can view this how-to to only the curators and creators in this gallery."
},
"accessToggle": {
"on": "collapse the access settings panel",
"off": "expand the access settings panel"
},
"accessMode": {
"label": "restrict who can view this how-to",
"labels": ["restricted", "expanded"],
"tips": [
"only creators in this gallery can view",
"creators and curators in any gallery the curator curates can view"
]
}
},
"viewer": {
Expand Down
48 changes: 40 additions & 8 deletions src/routes/gallery/[galleryid]/howto/HowToForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import MarkupHTMLView from '@components/concepts/MarkupHTMLView.svelte';
import { getUser } from '@components/project/Contexts';
import CreatorList from '@components/project/CreatorList.svelte';
import { TileKind } from '@components/project/Tile';
import Button from '@components/widgets/Button.svelte';
import ConfirmButton from '@components/widgets/ConfirmButton.svelte';
import Dialog from '@components/widgets/Dialog.svelte';
Expand All @@ -21,7 +20,6 @@
import type Gallery from '@db/galleries/Gallery';
import HowTo from '@db/howtos/HowToDatabase.svelte';
import type { ButtonText } from '@locale/UITexts';
import { COLLABORATE_SYMBOL } from '@parser/Symbols';
import type { Snippet } from 'svelte';
import type { SvelteMap } from 'svelte/reactivity';
import { movePermitted } from './HowToMovement';
Expand Down Expand Up @@ -232,6 +230,7 @@
['en-US'],
gallery ? gallery.getHowToReactions() : {},
notify,
overwriteAccess,
);

// pan the camera to the new how-to
Expand Down Expand Up @@ -261,6 +260,7 @@
xcoord: writeX,
ycoord: writeY,
collaborators: allCollaborators,
scopeOverwrite: overwriteAccess,
social: {
...howTo.getSocial(),
notifySubscribers: notify,
Expand Down Expand Up @@ -433,6 +433,12 @@
});
}
}

// allowing the user to overwrite the gallery's expanded viewing permissions
let accessToggle: boolean = $state(false);
let overwriteAccess: boolean = $derived(
howTo ? howTo.getScopeOverwrite() : false,
);
</script>

<!-- button to click to open the how-to dialog. if there is a preview (i.e., it is published), use the preview as the button.
Expand Down Expand Up @@ -499,11 +505,12 @@
<div class="optionsarea">
{#if collabToggle}
<div class="optionspanel">
<Subheader>
{COLLABORATE_SYMBOL}{TileKind.Collaborate}
</Subheader>
<Subheader
text={(l) => l.ui.howto.editor.collaborators.header}
/>
<MarkupHTMLView
markup={(l) => l.ui.howto.editor.collaboratorsPrompt}
markup={(l) =>
l.ui.howto.editor.collaborators.explanation}
></MarkupHTMLView>

<Labeled label={(l) => l.ui.collaborate.role.collaborators}>
Expand All @@ -522,6 +529,19 @@
</Labeled>
</div>
{/if}
{#if accessToggle}
<div class="optionspanel">
<Subheader text={(l) => l.ui.howto.editor.access.header} />
<MarkupHTMLView
markup={(l) => l.ui.howto.editor.access.explanation}
/>
<Mode
modes={(l) => l.ui.howto.editor.accessMode}
choice={overwriteAccess ? 0 : 1}
select={(num) => (overwriteAccess = num === 0)}
/>
</div>
{/if}
</div>

<div class="toolbar">
Expand All @@ -533,8 +553,20 @@
collabToggle = !collabToggle;
}}
>
{COLLABORATE_SYMBOL}
{TileKind.Collaborate}
<MarkupHTMLView
markup={(l) => l.ui.howto.editor.collaborators.header}
/>
</Toggle>
<Toggle
tips={(l) => l.ui.howto.editor.accessToggle}
on={accessToggle}
toggle={() => {
accessToggle = !accessToggle;
}}
>
<MarkupHTMLView
markup={(l) => l.ui.howto.editor.access.header}
/>
</Toggle>
</div>
<div class="toolbar-right">
Expand Down
10 changes: 8 additions & 2 deletions src/routes/gallery/[galleryid]/howto/PageText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@ type PageText = {
title: FieldText;
/** Placeholder for an untitled how-to */
titlePlaceholder: string;
/** Collaboration */
collaboratorsPrompt: string;
/** Header for collaborator settings */
collaborators: HeaderAndExplanationText;
/** Collaborator toggle text */
collaboratorsToggle: ToggleText;
/** Header for access settings */
access: HeaderAndExplanationText;
/** Access settings toggle text */
accessToggle: ToggleText;
/** Mode text for opting in/out of expanded access to how-tos */
accessMode: ModeText<[string, string]>;
};
viewer: {
/** Button text for viewing the how-to */
Expand Down
25 changes: 20 additions & 5 deletions static/schemas/LocaleText.json
Original file line number Diff line number Diff line change
Expand Up @@ -10802,9 +10802,21 @@
"editor": {
"additionalProperties": false,
"properties": {
"collaboratorsPrompt": {
"description": "Collaboration",
"type": "string"
"access": {
"$ref": "#/definitions/HeaderAndExplanationText",
"description": "Header for access settings"
},
"accessMode": {
"$ref": "#/definitions/ModeText%3C%5Bstring%2Cstring%5D%3E",
"description": "Mode text for opting in/out of expanded access to how-tos"
},
"accessToggle": {
"$ref": "#/definitions/ToggleText",
"description": "Access settings toggle text"
},
"collaborators": {
"$ref": "#/definitions/HeaderAndExplanationText",
"description": "Header for collaborator settings"
},
"collaboratorsToggle": {
"$ref": "#/definitions/ToggleText",
Expand Down Expand Up @@ -10852,8 +10864,11 @@
"editor",
"title",
"titlePlaceholder",
"collaboratorsPrompt",
"collaboratorsToggle"
"collaborators",
"collaboratorsToggle",
"access",
"accessToggle",
"accessMode"
],
"type": "object"
},
Expand Down