Skip to content

Commit

Permalink
Rework quick add card + refine card preview & review UI
Browse files Browse the repository at this point in the history
  • Loading branch information
kubk committed Nov 17, 2023
1 parent 97fb561 commit 461c7d8
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 74 deletions.
52 changes: 28 additions & 24 deletions src/screens/deck-list/main-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,31 +136,35 @@ export const MainScreen = observer(() => {
</div>
</div>

<div>
<ListHeader text={"News and updates"} />
<Button
icon={"mdi-call-made"}
onClick={() => {
const channelLink = import.meta.env.VITE_CHANNEL_LINK;
assert(channelLink, "Channel link env variable is empty");
{deckListStore.myInfo?.state === "fulfilled" && (
<>
<div>
<ListHeader text={"News and updates"} />
<Button
icon={"mdi-call-made"}
onClick={() => {
const channelLink = import.meta.env.VITE_CHANNEL_LINK;
assert(channelLink, "Channel link env variable is empty");

WebApp.openTelegramLink(channelLink);
}}
>
Telegram channel
</Button>
</div>
<div>
<Button
icon={"mdi-cog"}
disabled={deckListStore.myInfo?.state !== "fulfilled"}
onClick={() => {
screenStore.navigateToUserSettings();
}}
>
Settings
</Button>
</div>
WebApp.openTelegramLink(channelLink);
}}
>
Telegram channel
</Button>
</div>
<div>
<Button
icon={"mdi-cog"}
disabled={deckListStore.myInfo?.state !== "fulfilled"}
onClick={() => {
screenStore.navigateToUserSettings();
}}
>
Settings
</Button>
</div>
</>
)}
</div>
);
});
25 changes: 3 additions & 22 deletions src/screens/deck-list/my-deck.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,12 @@ export const MyDeck = observer((props: Props) => {
{deck.name}
</div>
<div
onClick={(event) => {
if (deckListStore.myId && deck.author_id === deckListStore.myId) {
event.stopPropagation();
screenStore.navigateToQuickCardAdd(deck.id);
}
}}
className={css({
display: "flex",
paddingLeft: 8,
gap: 8,
alignItems: "center",
color: theme.success,
fontWeight: 600,
})}
>
{deckListStore.myId && deck.author_id === deckListStore.myId ? (
<span className={css({ position: "relative", top: -1 })}>+</span>
) : null}

<span
className={css({
color: theme.success,
fontWeight: 600,
})}
>
{deck.cardsToReview.length}
</span>
{deck.cardsToReview.length}
</div>
</motion.div>
);
Expand Down
52 changes: 43 additions & 9 deletions src/screens/deck-review/deck-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { Button } from "../../ui/button.tsx";
import { ShareDeckButton } from "./share-deck-button.tsx";
import { useBackButton } from "../../lib/telegram/use-back-button.tsx";
import { useMainButton } from "../../lib/telegram/use-main-button.tsx";
import { trimEnd } from "../../lib/string/trim.ts";
import WebApp from "@twa-dev/sdk";

export const DeckPreview = observer(() => {
const reviewStore = useReviewStore();
Expand Down Expand Up @@ -61,20 +63,45 @@ export const DeckPreview = observer(() => {
<h4 className={css({ paddingBottom: 4 })}>Description</h4>
<div>{deck.description}</div>
</div>
<div className={css({ display: "flex", gap: 4 })}>
<h4>Cards available to review: </h4>
<span>{deck.cardsToReview.length}</span>
</div>
<div className={css({ display: "flex", gap: 4 })}>
<h4 className={css({ paddingBottom: 4 })}>Total cards: </h4>
<span>{deck.deck_card.length}</span>
<div
className={css({
display: "flex",
gap: 4,
flexDirection: "column",
borderTop: `1px solid ${theme.dividerColor}`,
paddingTop: 8,
})}
>
<div className={css({ display: "flex", gap: 4 })}>
<span>Cards to review: </span>
<h4 className={css({ color: theme.success })}>
{deck.cardsToReview.length}
</h4>
</div>
<div className={css({ display: "flex", gap: 4 })}>
<span>Total cards: </span>
<h4>{deck.deck_card.length}</h4>
</div>
</div>

<div className={css({ display: "flex", gap: 16 })}>
<ShareDeckButton deckId={deck.id} shareId={deck.share_id} />
{deckListStore.myId && deck.author_id === deckListStore.myId ? (
<Button
icon={"mdi-pencil"}
column
icon={"mdi-plus-circle mdi-24px"}
noPseudoClasses
outline
onClick={() => {
screenStore.navigateToQuickCardAdd(deck.id);
}}
>
Add card
</Button>
) : null}
{deckListStore.myId && deck.author_id === deckListStore.myId ? (
<Button
column
icon={"mdi-pencil-circle mdi-24px"}
noPseudoClasses
outline
onClick={() => {
Expand All @@ -84,6 +111,13 @@ export const DeckPreview = observer(() => {
Edit
</Button>
) : null}

<ShareDeckButton
column={
deckListStore.myId ? deck.author_id === deckListStore.myId : false
}
shareId={deck.share_id}
/>
</div>
</div>
{deck.cardsToReview.length === 0 && (
Expand Down
15 changes: 13 additions & 2 deletions src/screens/deck-review/review.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ export const Review = observer(() => {
})}
>
<div
style={{
className={css({
width: cardSize,
position: "absolute",
top: 8,
}}
})}
>
{reviewStore.initialCardCount && (
<ProgressBar
Expand All @@ -114,6 +114,17 @@ export const Review = observer(() => {
/>
)}
</div>
<div
className={css({
position: "absolute",
top: 41,
fontSize: 14,
whiteSpace: "nowrap",
color: theme.hintColor,
})}
>
{reviewStore.currentCard?.deckName}
</div>
<div
className={css({
height: 350,
Expand Down
14 changes: 10 additions & 4 deletions src/screens/deck-review/share-deck-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import WebApp from "@twa-dev/sdk";
import { Button } from "../../ui/button.tsx";

type Props = {
deckId: number;
shareId?: string | null;
column?: boolean;
};

export const ShareDeckButton = (props: Props) => {
const { shareId } = props;
const { shareId, column } = props;

const onClick = async () => {
const botUrl = import.meta.env.VITE_BOT_APP_URL;
Expand All @@ -21,8 +21,14 @@ export const ShareDeckButton = (props: Props) => {
};

return (
<Button icon={"mdi-share"} noPseudoClasses outline onClick={onClick}>
Share deck
<Button
column={column}
icon={"mdi-share-circle mdi-24px"}
noPseudoClasses
outline
onClick={onClick}
>
Share
</Button>
);
};
1 change: 1 addition & 0 deletions src/store/card-form-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export class CardFormStore {
public front: string,
public back: string,
public example: string | null = null,
public deckName?: string,
) {
makeAutoObservable(this, {}, { autoBind: true });
}
Expand Down
12 changes: 6 additions & 6 deletions src/store/deck-list-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ export class DeckListStore {
}
}

updateSettings(body: Pick<UserDbType, 'is_remind_enabled' | 'last_reminded_date'>) {
assert(this.myInfo?.state === 'fulfilled');
Object.assign(this.myInfo.value.user, body);
}

async loadSharedDeck(shareId?: string) {
if (!shareId || this.isSharedDeckLoaded) {
return;
Expand Down Expand Up @@ -112,7 +107,7 @@ export class DeckListStore {
deckListStore.addDeckToMine(deckListStore.selectedDeck.id);
}

reviewStore.startDeckReview(deckListStore.selectedDeck.cardsToReview);
reviewStore.startDeckReview(deckListStore.selectedDeck.cardsToReview, deckListStore.selectedDeck.name);
}

addDeckToMine(deckId: number) {
Expand Down Expand Up @@ -187,6 +182,11 @@ export class DeckListStore {
this.myDecks.every((deck) => deck.cardsToReview.length === 0)
);
}

updateSettings(body: Pick<UserDbType, 'is_remind_enabled' | 'last_reminded_date'>) {
assert(this.myInfo?.state === 'fulfilled');
Object.assign(this.myInfo.value.user, body);
}
}

const getCardsToReview = (
Expand Down
14 changes: 10 additions & 4 deletions src/store/review-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,19 @@ export class ReviewStore {
makeAutoObservable(this, {}, { autoBind: true });
}

startDeckReview(decks: DeckCardDbType[]) {
if (!decks.length) {
startDeckReview(deckCards: DeckCardDbType[], deckName: string) {
if (!deckCards.length) {
return;
}
decks.forEach((card) => {
deckCards.forEach((card) => {
this.cardsToReview.push(
new CardFormStore(card.id, card.front, card.back, card.example),
new CardFormStore(
card.id,
card.front,
card.back,
card.example,
deckName,
),
);
});
this.initialCardCount = this.cardsToReview.length;
Expand Down
7 changes: 5 additions & 2 deletions src/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Props = {
outline?: boolean;
noPseudoClasses?: boolean;
icon?: string;
column?: boolean;
} & React.ButtonHTMLAttributes<HTMLButtonElement>;

export const Button = (props: Props) => {
Expand All @@ -20,6 +21,7 @@ export const Button = (props: Props) => {
children,
icon,
noPseudoClasses,
column,
...restProps
} = props;

Expand All @@ -32,8 +34,9 @@ export const Button = (props: Props) => {
reset.button,
css({
display: "flex",
flexDirection: column ? 'column' : undefined,
width: "100%",
gap: 8,
gap: column ? 0 : 8,
justifyContent: "center",
alignItems: "center",
backgroundColor: mainColor,
Expand Down Expand Up @@ -72,7 +75,7 @@ export const Button = (props: Props) => {
outline &&
css({
backgroundColor: parsedColor
.lighten(isDarkTheme() ? 0.2 : 0.4)
.lighten(isDarkTheme() ? 0.35 : 0.4)
.toHex(),
color: mainColor,
":hover": noPseudoClasses
Expand Down
2 changes: 1 addition & 1 deletion src/ui/horizontal-divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const HorizontalDivider = () => {
width: "100%",
margin: "8px 0",
height: 1,
background: theme.hintColor,
background: theme.dividerColor,
})}
/>
);
Expand Down
1 change: 1 addition & 0 deletions src/ui/theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const theme = {
successLight: colord("#2ecb47").alpha(0.4).toHex(),
danger: "#fc2025",
dangerLight: colord("#fc2025").alpha(0.4).toHex(),
dividerColor: '#ccc',

borderRadius: 12,
};

0 comments on commit 461c7d8

Please sign in to comment.