Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e27f541
feat: チャートのデモを追加
273Do May 13, 2026
2b4f27e
fix: タブバーの表示を修正
273Do May 13, 2026
b9be739
fix: ジャーナル作成画面のボトムシートの挙動を修正
273Do May 13, 2026
3571727
fix: uiパーツの軽微な修正
273Do May 13, 2026
fb079cf
feat: エントリーを削除する処理を実装
273Do May 14, 2026
4777597
refactor: コードの可読性を高めるためのリファクタ
273Do May 14, 2026
a701edf
fix: 軽微な修正
273Do May 15, 2026
4f63325
feat: journalを削除する処理を実装
273Do May 15, 2026
3ee1162
fix: 全てのエントリーを削除できない問題を修正
273Do May 15, 2026
5b12b5b
feat: エントリー削除contextmenuを実装
273Do May 15, 2026
94e301a
feat: エントリーのブックマーク機能を実装
273Do May 16, 2026
70fa4ff
feat: エントリーの編集機能を実装
273Do May 16, 2026
429d1ab
fix: FieldObjのスペルを修正
273Do May 16, 2026
c5170ed
refactor: コード整理と軽微なリファクタ
273Do May 16, 2026
5286227
fix: スペルミスを修正
273Do May 16, 2026
3555f3d
feat: エントリー一覧画面から編集画面に遷移
273Do May 16, 2026
fa29900
feat: ジャーナル名を10文字に制限
273Do May 16, 2026
7f987c7
fix: エントリー数を表示するよう修正
273Do May 16, 2026
afbd52e
refactor: 検索の状態管理をリファクタ
273Do May 16, 2026
e2f43e3
refactor: ヘッダー右上のボタンをリファクタ
273Do May 17, 2026
2f506fd
fix: キーボードが表示されている状態で画面遷移するとクラッシュする問題を修正
273Do May 17, 2026
77389ae
fix: 軽微な修正
273Do May 17, 2026
d5e4022
feat: エントリー編集機能を実装
273Do May 17, 2026
9cfff9b
fix: フィールド並び替えによる表示のバグを修正
273Do May 17, 2026
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
17 changes: 8 additions & 9 deletions drizzle/migrations.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// This file is required for Expo/React Native SQLite migrations - https://orm.drizzle.team/quick-sqlite/expo

import journal from './meta/_journal.json';
import m0000 from './0000_young_bulldozer.sql';
import m0000 from "./0000_young_bulldozer.sql";
import journal from "./meta/_journal.json";

export default {
journal,
migrations: {
m0000
}
}

export default {
journal,
migrations: {
m0000,
},
};
200 changes: 98 additions & 102 deletions src/app/(journal)/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
import { useState } from "react";

import { Stack, useLocalSearchParams } from "expo-router";
import { Stack, useLocalSearchParams, useRouter } from "expo-router";

import { EntryListView } from "@/components/entry/entry-list-view";

/**
* ソート一覧
*/
export type SortKey =
| "dateDesc"
| "dateAsc"
| "titleAsc"
| "titleDesc"
| "bookmark";

/**
* ソートラベル
*/
const SORT_LABELS: Record<SortKey, string> = {
dateDesc: "Newest First",
dateAsc: "Oldest First",
titleAsc: "Title (A→Z)",
titleDesc: "Title (Z→A)",
bookmark: "Bookmarked",
};
import { deleteAllEntries } from "@/db/queries/entries";
import { SortKey } from "@/utils/entry/consts";

/**
* ジャーナル詳細(エントリー一覧)
*/
export default function JournalScreen() {
const { id, name } = useLocalSearchParams<{ id: string; name: string }>();
const [searchText, setSearchText] = useState<string>("");
const [sortKey, setSortKey] = useState<SortKey>("dateDesc");
const router = useRouter();

const { id: journalId, name } = useLocalSearchParams<{
id: string;
name: string;
}>();

const [filter, setFilter] = useState<{
searchText: string;
sortKey: SortKey;
}>({
searchText: "",
sortKey: "dateDesc",
});

const handleDeleteAll = async () => {
await deleteAllEntries(journalId).catch(console.error);
};

return (
<>
Expand All @@ -42,10 +38,61 @@ export default function JournalScreen() {
headerSearchBarOptions: {
placeholder: "Search",
hideWhenScrolling: false,
onChangeText: (e) => setSearchText(e.nativeEvent.text),
onCancelButtonPress: () => setSearchText(""),
onChangeText: (e) => {
const text = e.nativeEvent?.text ?? "";
setFilter((prev) => ({ ...prev, searchText: text }));
},
onCancelButtonPress: () =>
setFilter((prev) => ({ ...prev, searchText: "" })),
},
unstable_headerRightItems: () => [
{
type: "menu",
label: "Sort",
icon: {
type: "sfSymbol",
name: "arrow.up.arrow.down",
},
menu: {
items: [
{
type: "action",
label: "Newest First",
state: filter.sortKey === "dateDesc" ? "on" : "off",
onPress: () =>
setFilter((prev) => ({ ...prev, sortKey: "dateDesc" })),
},
{
type: "action",
label: "Oldest First",
state: filter.sortKey === "dateAsc" ? "on" : "off",
onPress: () =>
setFilter((prev) => ({ ...prev, sortKey: "dateAsc" })),
},
{
type: "action",
label: "Title (A→Z)",
state: filter.sortKey === "titleAsc" ? "on" : "off",
onPress: () =>
setFilter((prev) => ({ ...prev, sortKey: "titleAsc" })),
},
{
type: "action",
label: "Title (Z→A)",
state: filter.sortKey === "titleDesc" ? "on" : "off",
onPress: () =>
setFilter((prev) => ({ ...prev, sortKey: "titleDesc" })),
},
{
type: "action",
label: "Bookmarked",
state: filter.sortKey === "bookmark" ? "on" : "off",
onPress: () =>
setFilter((prev) => ({ ...prev, sortKey: "bookmark" })),
},
],
},
},
{
type: "menu",
label: "Options",
Expand All @@ -56,88 +103,37 @@ export default function JournalScreen() {
menu: {
items: [
{
type: "submenu",
label: "",
inline: true,
items: [
{
type: "submenu",
label: "Sort",
details: SORT_LABELS[sortKey],
icon: {
type: "sfSymbol",
name: "arrow.up.arrow.down",
},
items: [
{
type: "action",
label: "Newest First",
state: sortKey === "dateDesc" ? "on" : "off",
onPress: () => setSortKey("dateDesc"),
},
{
type: "action",
label: "Oldest First",
state: sortKey === "dateAsc" ? "on" : "off",
onPress: () => setSortKey("dateAsc"),
},
{
type: "action",
label: "Title (A→Z)",
state: sortKey === "titleAsc" ? "on" : "off",
onPress: () => setSortKey("titleAsc"),
},
{
type: "action",
label: "Title (Z→A)",
state: sortKey === "titleDesc" ? "on" : "off",
onPress: () => setSortKey("titleDesc"),
},
{
type: "action",
label: "Bookmarked",
state: sortKey === "bookmark" ? "on" : "off",
onPress: () => setSortKey("bookmark"),
},
],
},
{
type: "action",
icon: {
type: "sfSymbol",
name: "ellipsis.circle",
},
label: "Edit Journal",
onPress: () => {
// Do something
console.log("Edit Journal");
},
},
{
type: "action",
icon: {
type: "sfSymbol",
name: "square.and.arrow.up.on.square",
},
label: "Export",
onPress: () => {
// Do something
},
},
],
type: "action",
icon: {
type: "sfSymbol",
name: "ellipsis.circle",
},
label: "Edit",
onPress: () => {
router.push(`/(journal)/edit?journalId=${journalId}`);
},
},
{
type: "action",
icon: {
type: "sfSymbol",
name: "trash",
name: "square.and.arrow.up.on.square",
},
destructive: true,
label: "Delete All",
label: "Export",
onPress: () => {
// Do something
},
},
{
type: "action",
label: "Delete All Entries",
icon: {
type: "sfSymbol",
name: "trash",
},
destructive: true,
onPress: handleDeleteAll,
},
],
},
},
Expand All @@ -147,10 +143,10 @@ export default function JournalScreen() {
{/* TODO: 空の場合の処理を追加する */}
{/* エントリー一覧にはheaderTitleのデータは含まないので src/app/(journal)/entry/[id].tsx と混同しないように。 */}
<EntryListView
id={id}
journalId={journalId}
journalName={name}
searchText={searchText}
sortKey={sortKey}
searchText={filter.searchText}
sortKey={filter.sortKey}
/>
</>
);
Expand Down
28 changes: 14 additions & 14 deletions src/app/(journal)/create.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { PlatformColor, Pressable } from "react-native";
import { Keyboard, PlatformColor } from "react-native";

import { Stack, useRouter } from "expo-router";
import { SymbolView } from "expo-symbols";

import { JournalCreateView } from "@/components/journal/journal-create-view";
import { useJournalField } from "@/utils/journal/use-journal-field";
Expand All @@ -25,6 +24,7 @@ export default function JournalCreateScreen() {
} = useJournalField();

const handleJournalCreate = async () => {
Keyboard.dismiss();
const { id: newJournalId, name } = await createJournal();

// replace でスタックせずにジャーナル詳細画面からジャーナル一覧へ戻れるようにする
Expand All @@ -36,18 +36,18 @@ export default function JournalCreateScreen() {
<Stack.Screen
options={{
title: "New Journal",
headerRight: () => (
<Pressable onPress={handleJournalCreate} disabled={formDisabled}>
<SymbolView
name="checkmark"
tintColor={
formDisabled
? PlatformColor("tertiaryLabel")
: PlatformColor("systemIndigo")
}
/>
</Pressable>
),
unstable_headerRightItems: () => [
{
type: "button",
label: "Save",
icon: { type: "sfSymbol", name: "checkmark" },
tintColor: formDisabled
? PlatformColor("tertiaryLabel")
: PlatformColor("systemIndigo"),
disabled: formDisabled,
onPress: formDisabled ? () => {} : handleJournalCreate,
},
],
}}
/>
<JournalCreateView
Expand Down
Loading
Loading