Skip to content

Commit

Permalink
Merge pull request #1 from rknyryn/develop
Browse files Browse the repository at this point in the history
voice reading added, word card refactored.
  • Loading branch information
rknyryn authored Mar 22, 2024
2 parents e6f1d74 + 42d5a4a commit cc41f0f
Show file tree
Hide file tree
Showing 14 changed files with 797 additions and 26 deletions.
435 changes: 430 additions & 5 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@
},
"type": "module",
"dependencies": {
"add": "^2.0.6",
"bits-ui": "^0.19.6",
"clsx": "^2.1.0",
"mode-watcher": "^0.2.2",
"select": "^1.1.2",
"shadcn-svelte": "^0.9.1",
"svelte-radix": "^1.1.0",
"tailwind-merge": "^2.2.1",
"tailwind-variants": "^0.2.0"
Expand Down
18 changes: 18 additions & 0 deletions src/components/Pause.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts">
</script>

<svg
width="30px"
height="30px"
viewBox="0 0 24 24"
class="fill-[#313131] dark:fill-blue-400"
xmlns="http://www.w3.org/2000/svg"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M14 8C14.5523 8 15 8.44772 15 9L15 15C15 15.5523 14.5523 16 14 16C13.4477 16 13 15.5523 13 15L13 9C13 8.44772 13.4477 8 14 8ZM10 8C10.5523 8 11 8.44772 11 9L11 15C11 15.5523 10.5523 16 10 16C9.44771 16 9 15.5523 9 15L9 9C9 8.44772 9.44772 8 10 8ZM7.25007 2.38782C8.54878 2.0992 10.1243 2 12 2C13.8757 2 15.4512 2.0992 16.7499 2.38782C18.06 2.67897 19.1488 3.176 19.9864 4.01358C20.824 4.85116 21.321 5.94002 21.6122 7.25007C21.9008 8.54878 22 10.1243 22 12C22 13.8757 21.9008 15.4512 21.6122 16.7499C21.321 18.06 20.824 19.1488 19.9864 19.9864C19.1488 20.824 18.06 21.321 16.7499 21.6122C15.4512 21.9008 13.8757 22 12 22C10.1243 22 8.54878 21.9008 7.25007 21.6122C5.94002 21.321 4.85116 20.824 4.01358 19.9864C3.176 19.1488 2.67897 18.06 2.38782 16.7499C2.0992 15.4512 2 13.8757 2 12C2 10.1243 2.0992 8.54878 2.38782 7.25007C2.67897 5.94002 3.176 4.85116 4.01358 4.01358C4.85116 3.176 5.94002 2.67897 7.25007 2.38782Z"
/>
</svg>

<style lang="scss">
</style>
19 changes: 19 additions & 0 deletions src/components/Play.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script lang="ts">
</script>

<svg
width="30px"
height="30px"
viewBox="0 0 24 24"
class="fill-[#313131] dark:fill-blue-400"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.25007 2.38782C8.54878 2.0992 10.1243 2 12 2C13.8757 2 15.4512 2.0992 16.7499 2.38782C18.06 2.67897 19.1488 3.176 19.9864 4.01358C20.824 4.85116 21.321 5.94002 21.6122 7.25007C21.9008 8.54878 22 10.1243 22 12C22 13.8757 21.9008 15.4512 21.6122 16.7499C21.321 18.06 20.824 19.1488 19.9864 19.9864C19.1488 20.824 18.06 21.321 16.7499 21.6122C15.4512 21.9008 13.8757 22 12 22C10.1243 22 8.54878 21.9008 7.25007 21.6122C5.94002 21.321 4.85116 20.824 4.01358 19.9864C3.176 19.1488 2.67897 18.06 2.38782 16.7499C2.0992 15.4512 2 13.8757 2 12C2 10.1243 2.0992 8.54878 2.38782 7.25007C2.67897 5.94002 3.176 4.85116 4.01358 4.01358C4.85116 3.176 5.94002 2.67897 7.25007 2.38782ZM15.5963 10.3318C16.8872 11.0694 16.8872 12.9307 15.5963 13.6683L11.154 16.2068C9.9715 16.8825 8.5002 16.0287 8.5002 14.6667L8.5002 9.33339C8.5002 7.97146 9.9715 7.11762 11.154 7.79333L15.5963 10.3318Z"
/>
</svg>

<style lang="scss">
</style>
150 changes: 150 additions & 0 deletions src/components/WordCard.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<script lang="ts" context="module">
export type WordCardDataType = {
word: string;
ipa: string;
meaning: {
adjective: string | undefined;
adverb: string | undefined;
noun: string | undefined;
verb: string | undefined;
};
example: string[];
};
</script>

<script lang="ts">
import * as Accordion from '$lib/components/ui/accordion';
import { onMount } from 'svelte';
import * as Alert from '$lib/components/ui/alert';
import * as Card from '$lib/components/ui/card';
import Pause from './Pause.svelte';
import Play from './Play.svelte';
export let data: WordCardDataType;
export let index: number;
let Speaker: SpeechSynthesisUtterance;
let isSpeaking: boolean = false;
let SelectedSpeakerLang = { label: 'English (US)', value: 'en-US' };
let SpeakerLangOptions: { label: string; value: string }[] = [
{ label: 'English (US)', value: 'en-US' },
{ label: 'Turkish', value: 'tr-TR' }
];
function Speech(text: string) {
if (isSpeaking) {
window.speechSynthesis.cancel();
isSpeaking = false;
return;
}
Speaker.lang = SelectedSpeakerLang.value || 'en-US';
Speaker.text = text;
window.speechSynthesis.speak(Speaker);
isSpeaking = true;
Speaker.addEventListener('end', () => {
console.log('speak end');
isSpeaking = false;
});
}
onMount(() => {
Speaker = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
Speaker.voice = voices[5];
});
</script>

<Card.Root class="">
<Card.Header>
<Card.Title class="flex gap-3 text-2xl capitalize ">
{data.word}

<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<span class="play-button" on:click={() => Speech(data.word)}>
{#if isSpeaking}
<Pause />
{:else}
<Play />
{/if}
</span>

<!-- <Select.Root bind:selected={SelectedSpeakerLang[index]}>
<Select.Trigger class="w-[180px]">
<Select.Value />
</Select.Trigger>
<Select.Content>
<Select.Group>
{#each SpeakerLangOptions as lang}
<Select.Item value={lang.value} label={lang.label}>
{lang.label}
</Select.Item>
{/each}
</Select.Group>
</Select.Content>
<Select.Input name="favoriteFruit" />
</Select.Root> -->
</Card.Title>
</Card.Header>
<Card.Content class="grid gap-2">
{#if data.meaning.noun}
<Alert.Root>
<Alert.Title>Noun</Alert.Title>
<Alert.Description>
{data.meaning.noun}
</Alert.Description>
</Alert.Root>
{/if}
{#if data.meaning.adverb}
<Alert.Root>
<Alert.Title>Adverb</Alert.Title>
<Alert.Description>
{data.meaning.adverb}
</Alert.Description>
</Alert.Root>
{/if}
{#if data.meaning.verb}
<Alert.Root>
<Alert.Title>Verb</Alert.Title>
<Alert.Description>
{data.meaning.verb}
</Alert.Description>
</Alert.Root>
{/if}
{#if data.meaning.adjective}
<Alert.Root>
<Alert.Title>Adjective</Alert.Title>
<Alert.Description>
{data.meaning.adjective}
</Alert.Description>
</Alert.Root>
{/if}
{#if data.example}
<Accordion.Root class="rounded-md border px-4 hover:border-slate-400">
<Accordion.Item value={index.toString()}>
<Accordion.Trigger>Examples</Accordion.Trigger>
<Accordion.Content class="text-wrap">
<ul class="my-6 ml-6 list-disc [&>li]:mt-2">
{#each data.example as e}
<li>{e}</li>
{/each}
</ul>
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
{/if}
</Card.Content>
</Card.Root>

<style lang="scss">
.play-button {
cursor: pointer;
user-select: none;
transition: all ease-in-out 100ms;
&:hover {
transform: scale(1.05);
}
}
</style>
34 changes: 34 additions & 0 deletions src/lib/components/ui/select/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Select as SelectPrimitive } from "bits-ui";

import Label from "./select-label.svelte";
import Item from "./select-item.svelte";
import Content from "./select-content.svelte";
import Trigger from "./select-trigger.svelte";
import Separator from "./select-separator.svelte";

const Root = SelectPrimitive.Root;
const Group = SelectPrimitive.Group;
const Input = SelectPrimitive.Input;
const Value = SelectPrimitive.Value;

export {
Root,
Item,
Group,
Input,
Label,
Value,
Content,
Trigger,
Separator,
//
Root as Select,
Item as SelectItem,
Group as SelectGroup,
Input as SelectInput,
Label as SelectLabel,
Value as SelectValue,
Content as SelectContent,
Trigger as SelectTrigger,
Separator as SelectSeparator,
};
36 changes: 36 additions & 0 deletions src/lib/components/ui/select/select-content.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts">
import { Select as SelectPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js.js";
import { scale } from "svelte/transition";
type $$Props = SelectPrimitive.ContentProps;
let className: $$Props["class"] = undefined;
export let sideOffset: $$Props["sideOffset"] = 4;
export let inTransition: $$Props["inTransition"] = flyAndScale;
export let inTransitionConfig: $$Props["inTransitionConfig"] = undefined;
export let outTransition: $$Props["outTransition"] = scale;
export let outTransitionConfig: $$Props["outTransitionConfig"] = {
start: 0.95,
opacity: 0,
duration: 50,
};
export { className as class };
</script>

<SelectPrimitive.Content
{inTransition}
{inTransitionConfig}
{outTransition}
{outTransitionConfig}
{sideOffset}
class={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md focus:outline-none",
className
)}
{...$$restProps}
>
<div class="w-full p-1">
<slot />
</div>
</SelectPrimitive.Content>
37 changes: 37 additions & 0 deletions src/lib/components/ui/select/select-item.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script lang="ts">
import { cn } from "$lib/utils.js.js";
import { Select as SelectPrimitive } from "bits-ui";
import Check from "svelte-radix/Check.svelte";
type $$Props = SelectPrimitive.ItemProps;
type $$Events = Required<SelectPrimitive.ItemEvents>;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"];
export let label: $$Props["label"] = undefined;
export let disabled: $$Props["disabled"] = undefined;
export { className as class };
</script>

<SelectPrimitive.Item
{value}
{disabled}
{label}
class={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className
)}
{...$$restProps}
on:click
on:pointermove
on:focusin
>
<span class="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check class="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<slot>
{label ? label : value}
</slot>
</SelectPrimitive.Item>
13 changes: 13 additions & 0 deletions src/lib/components/ui/select/select-label.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script lang="ts">
import { Select as SelectPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js.js";
type $$Props = SelectPrimitive.LabelProps;
let className: $$Props["class"] = undefined;
export { className as class };
</script>

<SelectPrimitive.Label class={cn("px-2 py-1.5 text-sm font-semibold", className)} {...$$restProps}>
<slot />
</SelectPrimitive.Label>
11 changes: 11 additions & 0 deletions src/lib/components/ui/select/select-separator.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import { Select as SelectPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js.js";
type $$Props = SelectPrimitive.SeparatorProps;
let className: $$Props["class"] = undefined;
export { className as class };
</script>

<SelectPrimitive.Separator class={cn("-mx-1 my-1 h-px bg-muted", className)} {...$$restProps} />
24 changes: 24 additions & 0 deletions src/lib/components/ui/select/select-trigger.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { Select as SelectPrimitive } from "bits-ui";
import CaretSort from "svelte-radix/CaretSort.svelte";
import { cn } from "$lib/utils.js.js";
type $$Props = SelectPrimitive.TriggerProps;
type $$Events = SelectPrimitive.TriggerEvents;
let className: $$Props["class"] = undefined;
export { className as class };
</script>

<SelectPrimitive.Trigger
class={cn(
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className
)}
{...$$restProps}
>
<slot />
<div>
<CaretSort class="h-4 w-4 opacity-50" />
</div>
</SelectPrimitive.Trigger>
Loading

0 comments on commit cc41f0f

Please sign in to comment.