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
13 changes: 7 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ These notes are publicly posted in [production](https://wordplay.dev/updates), s

### Added

- We added a new "tour" help feature for each tile in the project view, explaining its purpose and core features. Try them out and let us know if we should expand the explanations! (#687).
- We added additional keywords to all emojis to improve searching (#1090), but also translated all of those keywords, so that works in all supported locales (#639).
- We added a new visual style for blocks editing mode, for improved readability. It also accounts for whether an editor is read only, hiding editing controls for more compactness.
- We added much more robust menu suggestions for locales (#1099), text and formatted literals (#635), and unit suggestions.
- We added a way to highlight expressions by adding 👀 inside some code's preceding explanatio, e.g., \¶👀¶"I'm highlighted!" This is helpful for how-to authors who want to emphasize some code.
- We added a setting to control the spacing in blocks mode, for accessibility.
- There's a new "tour" help feature for each tile in the project view, explaining its purpose and core features. Try them out and let us know if we should expand the explanations! (#687).
- Emoji searching now supports many more keywords (#1090), but also translations all of those keywords, so that works in all supported locales (#639).
- Blocks have a new visual style for blocks editing mode, for improved readability. It also accounts for whether an editor is read only, hiding editing controls for more compactness.
- Menu suggestions in the editor are now much more helpful for locales (#1099), text and formatted literals (#635), and unit suggestions.
- How-to authors can now highlight expressions by adding 👀 inside some code's preceding explanatio, e.g., \¶👀¶"I'm highlighted!" This is helpful for how-to authors who want to emphasize some code.
- Block spacing can now be controlled.
- We added a machine translated Tagalog locale (#1089).
- The guide in the project view now shows _all_ how-tos a creator has access to, can filter between just all and gallery-specific how-tos (#1087).

### Changed

Expand Down
25 changes: 20 additions & 5 deletions src/components/concepts/ConceptLinkUI.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
<script lang="ts">
import Link from '@components/app/Link.svelte';
import TutorialHighlight from '@components/app/TutorialHighlight.svelte';
import CharacterView from '@components/output/CharacterView.svelte';
import {
getConceptIndex,
getConceptPath,
getUser,
} from '@components/project/Contexts';
import Button from '@components/widgets/Button.svelte';
import Concept from '@concepts/Concept';
import GalleryHowConcept from '@concepts/GalleryHowConcept';
import { locales } from '@db/Database';
import ConceptRef from '@locale/ConceptRef';
import ConceptLink, {
CharacterName,
CodepointName,
ConceptName,
HowToName,
UIName,
} from '@nodes/ConceptLink';
import { locales } from '@db/Database';
import ConceptRef from '@locale/ConceptRef';
import { withMonoEmoji } from '@unicode/emoji';
import TutorialHighlight from '@components/app/TutorialHighlight.svelte';
import { getConceptIndex, getConceptPath } from '@components/project/Contexts';
import Button from '@components/widgets/Button.svelte';
import MarkupHTMLView from './MarkupHTMLView.svelte';

interface Props {
link: ConceptRef | ConceptLink | Concept | string;
Expand Down Expand Up @@ -135,6 +141,12 @@
: undefined,
);

let isConceptGalleryHow: boolean = $derived(
concept instanceof GalleryHowConcept,
);

let user = getUser();

let longName: string = $derived(concept?.getName($locales, false) ?? '');
let symbolicName: string = $derived(concept?.getName($locales, true) ?? '');

Expand Down Expand Up @@ -166,6 +178,9 @@
</script>

{#if concept}
{#if isConceptGalleryHow && (concept as GalleryHowConcept).howTo.hasBookmarker($user?.uid ?? '')}
<MarkupHTMLView inline markup={'🔖'} />
{/if}
<Button
padding={false}
action={navigate}
Expand Down
87 changes: 67 additions & 20 deletions src/components/concepts/Documentation.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,18 @@
});

// get the user generated how-tos that are in a gallery, if the gallery exists
let galleryHowTos = $state<GalleryHowTo[]>([]);
let gallery: Gallery | undefined = $state(undefined);

// determine if the guide will only show how-tos from the project's gallery
// or if it will show all how-tos that the user has access to
let galleryOnly: boolean = $state(false);
$effect(() => {
const galleryID: string | null = project.getGallery();
galleryOnly = project.getGallery() == null && !standalone;
});

let galleryID: string | null = $derived(project.getGallery());
let gallery: Gallery | undefined = $state(undefined);
let galleryHowTos: GalleryHowTo[] = $state([]);
$effect(() => {
if (galleryID) {
Galleries.get(galleryID).then((gal) => {
// Found a store? Subscribe to it, updating the gallery when it changes.
Expand All @@ -187,11 +194,55 @@
}
},
);
} else if (standalone) {
galleryHowTos = HowTos.allAccessiblePublishedHowTos;
}
});

let allBookmarks: GalleryHowTo[] = $derived(
HowTos.allAccessiblePublishedHowTos.filter((ht) =>
ht.hasBookmarker($user?.uid ?? ''),
),
);

// order of how-tos shown in the Guide panel
// 1: all bookmarked how-tos first
// 2: then how-tos from the gallery that the project is in, if applicable (must be in project view and project must be in gallery)
// 3: then all other how-tos, if applicable (if filter is set to all, project is not in gallery, or )
let galleryHowConcepts: GalleryHowConcept[] = $derived(
index
? (galleryID && galleryOnly
? [...galleryHowTos, ...allBookmarks]
: HowTos.allAccessiblePublishedHowTos
)
.map((ht) => index.getGalleryHowConcept(ht.getHowToId()))
.filter((c): c is GalleryHowConcept => c !== undefined)
.toSorted((a, b) => {
let aBookmarked = a.howTo.hasBookmarker($user?.uid ?? '');
let bBookmarked = b.howTo.hasBookmarker($user?.uid ?? '');

if (aBookmarked && !bBookmarked) {
return -1;
} else if (!aBookmarked && bBookmarked) {
return 1;
} else if (galleryID) {
let aInGallery =
a.howTo.getHowToGalleryId() === galleryID;
let bInGallery =
b.howTo.getHowToGalleryId() === galleryID;

if (aInGallery && !bInGallery) {
return -1;
} else if (!aInGallery && bInGallery) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
})
: [],
);

// When the path changes, reset the query
const queryResetUnsub = path.subscribe(() => {
query = '';
Expand Down Expand Up @@ -459,25 +510,21 @@
{#if howTos === undefined}
<Spinning></Spinning>
{:else}
{#if galleryHowTos.length > 0}
{@const galleryHow = index.concepts
.filter((c) => c instanceof GalleryHowConcept)
.toSorted((a, b) => {
return a.howTo.hasBookmarker(
$user?.uid ?? '',
) == b.howTo.hasBookmarker($user?.uid ?? '')
? 0
: a.howTo.hasBookmarker(
$user?.uid ?? '',
)
? -1
: 1;
})}
{#if !standalone && gallery}
<Mode
modes={(l) => l.ui.docs.mode.howToFilter}
choice={galleryOnly ? 1 : 0}
select={(choice) => {
galleryOnly = choice === 1;
}}
/>
{/if}
{#if galleryHowConcepts.length > 0}
<Subheader
text={(l) => l.ui.docs.how.category.gallery}
/>
<div class="howtos">
{#each galleryHow as how}
{#each galleryHowConcepts as how}
<CodeView
node={how.getRepresentation()}
concept={how}
Expand Down
2 changes: 2 additions & 0 deletions src/components/concepts/DocumentationText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ type DocumentationText = {
string,
]
>;
/** Toggle between seeing all user-created how-tos or only those in the project's gallery */
howToFilter: ModeText<[string, string]>;
};
header: {
/** Names header */
Expand Down
10 changes: 5 additions & 5 deletions src/components/project/ProjectView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import setKeyboardFocus from '@components/util/setKeyboardFocus';
import LocalizedText from '@components/widgets/LocalizedText.svelte';
import Options from '@components/widgets/Options.svelte';
import Tour, {
type UIExplanation,
} from '@components/widgets/Tour.svelte';
import type Concept from '@concepts/Concept';
import ConceptIndex from '@concepts/ConceptIndex';
import {
Expand Down Expand Up @@ -56,14 +59,11 @@
type ArrangementType,
} from '@db/settings/Arrangement';
import type Locale from '@locale/Locale';
import Evaluate from '@nodes/Evaluate';
import Node, { isFieldPosition } from '@nodes/Node';
import Source from '@nodes/Source';
import type Color from '@output/Color';
import { CANCEL_SYMBOL, INFO_SYMBOL } from '@parser/Symbols';
import Evaluate from '@nodes/Evaluate';
import Tour, {
type UIExplanation,
} from '@components/widgets/Tour.svelte';
import { isName } from '@parser/Tokenizer';
import Evaluator from '@runtime/Evaluator';
import type Value from '@values/Value';
Expand Down Expand Up @@ -936,7 +936,7 @@
currentProject,
$locales,
resolvedHowTos ?? [],
currentGalleryHowTos,
HowTos.allAccessiblePublishedHowTos,
).withExamples(
index === undefined ? new Map() : index.examples,
)
Expand Down
38 changes: 23 additions & 15 deletions src/concepts/ConceptIndex.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
import GalleryHowTo from '@db/howtos/HowToDatabase.svelte';
import Bind from '@nodes/Bind';
import FunctionDefinition from '@nodes/FunctionDefinition';
import type Node from '@nodes/Node';
import StructureDefinition from '@nodes/StructureDefinition';
import type Type from '@nodes/Type';
import type TypeSet from '@nodes/TypeSet';
import type Project from '@db/projects/Project';
import type Locales from '@locale/Locales';
import BinaryEvaluate from '@nodes/BinaryEvaluate';
import Evaluate from '@nodes/Evaluate';
import FunctionType from '@nodes/FunctionType';
import Reference from '@nodes/Reference';
import StreamDefinition from '@nodes/StreamDefinition';
import UnaryEvaluate from '@nodes/UnaryEvaluate';
import BindConcept from '@concepts/BindConcept';
import type Concept from '@concepts/Concept';
import {
Expand All @@ -28,6 +13,21 @@ import NodeConcept from '@concepts/NodeConcept';
import { Purpose, type PurposeType } from '@concepts/Purpose';
import StreamConcept from '@concepts/StreamConcept';
import StructureConcept from '@concepts/StructureConcept';
import GalleryHowTo from '@db/howtos/HowToDatabase.svelte';
import type Project from '@db/projects/Project';
import type Locales from '@locale/Locales';
import BinaryEvaluate from '@nodes/BinaryEvaluate';
import Bind from '@nodes/Bind';
import Evaluate from '@nodes/Evaluate';
import FunctionDefinition from '@nodes/FunctionDefinition';
import FunctionType from '@nodes/FunctionType';
import type Node from '@nodes/Node';
import Reference from '@nodes/Reference';
import StreamDefinition from '@nodes/StreamDefinition';
import StructureDefinition from '@nodes/StructureDefinition';
import type Type from '@nodes/Type';
import type TypeSet from '@nodes/TypeSet';
import UnaryEvaluate from '@nodes/UnaryEvaluate';

export default class ConceptIndex {
readonly project: Project;
Expand Down Expand Up @@ -264,6 +264,14 @@ export default class ConceptIndex {
);
}

getGalleryHowConcept(howToId: string): GalleryHowConcept | undefined {
return this.concepts.find(
(concept): concept is GalleryHowConcept =>
concept instanceof GalleryHowConcept &&
concept.getHowToId() === howToId,
);
}

getEquivalent(concept: Concept): Concept | undefined {
return this.concepts.find((c) => c.isEqualTo(concept));
}
Expand Down
10 changes: 7 additions & 3 deletions src/concepts/GalleryHowConcept.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Concept from '@concepts/Concept';
import { Purpose } from '@concepts/Purpose';
import type HowTo from '@db/howtos/HowToDatabase.svelte';
import Locales from '@locale/Locales';
import type Context from '@nodes/Context';
Expand All @@ -9,8 +11,6 @@ import type CharacterSymbols from '../lore/BasisCharacter';
import Characters from '../lore/BasisCharacters';
import { Emotion } from '../lore/Emotion';
import type { CharacterName } from '../tutorial/Tutorial';
import Concept from '@concepts/Concept';
import { Purpose } from '@concepts/Purpose';

// modified from HowConcept.ts

Expand Down Expand Up @@ -46,7 +46,7 @@ export default class GalleryHowConcept extends Concept {
}

getNames(locales: Locales): string[] {
return [this.howTo.getTitleInLocale(locales.getLocaleString())];
return [this.getName(locales)];
}

getName(locales: Locales): string {
Expand Down Expand Up @@ -90,4 +90,8 @@ export default class GalleryHowConcept extends Concept {
getPath(): string {
return `/gallery/${this.howTo.getHowToGalleryId()}/howto?id=${this.howTo.getHowToId()}`;
}

getHowToId(): string {
return this.howTo.getHowToId();
}
}
8 changes: 8 additions & 0 deletions src/locale/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -5157,6 +5157,14 @@
"documentation and comments",
"advanced language concepts"
]
},
"howToFilter": {
"label": "user-created how-tos",
"labels": ["all", "gallery & bookmarks"],
"tips": [
"see all user-created how-tos",
"see only the user-created how-tos from this project's gallery and all bookmarks"
]
}
},
"note": {
Expand Down
12 changes: 10 additions & 2 deletions static/locales/ar-SA/ar-SA.json
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@
},
"UnknownType": {
"name": "$~مجهول",
"description": "$~مثِّل نوعاً غير محدد",
"description": "$~مجهول",
"connector": "$~، لأن",
"emotion": "curious",
"doc": "$~همم... لا أعرف ما الذي أمثله، لكنني فضولي حقاً. هل تعرف؟ يبدو أنه من المفترض أن نعرف. قد تحتاج إلى إخبارنا إذا لم نتمكن من معرفة ذلك."
Expand Down Expand Up @@ -1699,7 +1699,7 @@
},
"UnknownNameType": {
"name": "$~اسمغيرمعروف",
"description": "$~$1[$1 غير مُعرّف|لم يتم إعطاء اسم]",
"description": "$~$1[$1 لم يتم تعريفها بعد|لم يتم إعطاء الاسم]",
"emotion": "curious",
"doc": "$~هل تعلمون كيف أن بعض حسابات @Reference و @PropertyReference لا تعرف الاسم الذي تتحدثون عنه؟ أنا موجود عندما يحدث ذلك، لأوضح أننا لا نعرف من تتحدثون عنه."
},
Expand Down Expand Up @@ -5118,6 +5118,14 @@
"$~الوثائق والتعليقات",
"$~مفاهيم لغوية متقدمة"
]
},
"howToFilter": {
"label": "$~إرشادات من إنشاء المستخدمين",
"labels": ["$~الجميع", "$~معرض الصور والإشارات المرجعية"],
"tips": [
"$~اطلع على جميع الأدلة الإرشادية التي أنشأها المستخدمون",
"$~يمكنك الاطلاع فقط على الأدلة الإرشادية التي أنشأها المستخدمون من معرض هذا المشروع وجميع الإشارات المرجعية."
]
}
},
"note": {
Expand Down
Loading