Skip to content

Commit c13d195

Browse files
committed
Merge branch 'develop' of github.com:kc3hack/2026_team19 into develop
2 parents 242727b + 7d18239 commit c13d195

File tree

10 files changed

+260
-184
lines changed

10 files changed

+260
-184
lines changed

.github/workflows/vercel.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Deploy to Vercel
2+
3+
on:
4+
push:
5+
branches: [ develop ]
6+
workflow_dispatch:
7+
8+
jobs:
9+
deploy:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout repo
13+
uses: actions/checkout@v4
14+
15+
- name: Strip Git metadata for Vercel
16+
run: rm -rf .git
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: 20
22+
23+
- name: Install Vercel CLI
24+
run: npm install -g vercel@latest
25+
26+
- name: Pull Vercel env
27+
env:
28+
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
29+
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
30+
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
31+
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
32+
33+
- name: Deploy to Vercel (Production)
34+
env:
35+
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
36+
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
37+
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
38+
run: vercel deploy --prod --yes --token=${{ secrets.VERCEL_TOKEN }}

Frontend/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>LexiFlow</title>
7+
<title>TalkScope</title>
88
</head>
99
<body>
1010
<div id="root"></div>

Frontend/src/app/App.tsx

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
makeLeftRightLayout,
2929
removeLeaf,
3030
} from './layout/layoutUtils';
31-
import { VectorApiCheckButton } from './components/VectorApiCheckButton';
31+
3232

3333

3434

@@ -42,7 +42,7 @@ const PRESETS = [
4242
] as const;
4343

4444
const App: React.FC = () => {
45-
if (import.meta.env.DEV) console.log('[LexiFlow] App.tsx 読み込み(主題入力あり)');
45+
if (import.meta.env.DEV) console.log('[TalkScope] App.tsx 読み込み(主題入力あり)');
4646
const { transcript, setTranscript, isListening, startListening, stopListening, error } = useSpeechRecognition();
4747

4848
const [activeTerms, setActiveTerms] = useState<Term[]>([]);
@@ -53,7 +53,7 @@ const App: React.FC = () => {
5353
const [isDictionaryManagerOpen, setIsDictionaryManagerOpen] = useState(false);
5454
const [isLayoutMenuOpen, setIsLayoutMenuOpen] = useState(false);
5555
const [layout, setLayout] = useState<LayoutNode>(makeDefaultLayout);
56-
const [settings, setSettings] = useState({ darkMode: true, themeColor: 'indigo' });
56+
const [settings, setSettings] = useState({ darkMode: false, themeColor: 'indigo' });
5757
const [isPinned, setIsPinned] = useState<Set<string>>(new Set());
5858
/** ピン留めした用語一覧(IndexedDB と同期・ピン中タブで表示) */
5959
const [pinnedTermsList, setPinnedTermsList] = useState<Term[]>([]);
@@ -67,7 +67,7 @@ const App: React.FC = () => {
6767
/** API 用語の意味ベクトル (termId → vector)。バブルサイズ計算用 */
6868
const [termVectors, setTermVectors] = useState<Record<string, number[]>>({});
6969
/** フィルタ基準語(現状固定)との類似度フィルタ有効化 */
70-
const [isSimilarityFilterEnabled, setIsSimilarityFilterEnabled] = useState(true);
70+
const [isSimilarityFilterEnabled, setIsSimilarityFilterEnabled] = useState(false);
7171
/** ベクトルフィルタの強さ(0〜100) */
7272
const [similarityFilterStrength, setSimilarityFilterStrength] = useState(8);
7373
/** "it" の基準ベクトル(初期はフォールバックで即時利用可能にする) */
@@ -107,7 +107,6 @@ const App: React.FC = () => {
107107
// ── デモ機能(コア機能から独立) ──────────────────────────────
108108
const demoStream = useDemoStream({
109109
onAppend: (text) => setTranscript(text),
110-
intervalMs: 220,
111110
});
112111
// ──────────────────────────────────────────────────────────────
113112

@@ -489,13 +488,6 @@ const App: React.FC = () => {
489488
termVectors={termVectors}
490489
categoryFilter={categoryFilter}
491490
onCategoryFilterChange={setCategoryFilter}
492-
similarityFilterEnabled={isSimilarityFilterEnabled}
493-
onSimilarityFilterEnabledChange={setIsSimilarityFilterEnabled}
494-
similarityFilterStrength={similarityFilterStrength}
495-
onSimilarityFilterStrengthChange={setSimilarityFilterStrength}
496-
similarityThreshold={similarityThreshold}
497-
similarityReferenceWord="it"
498-
similarityReady={isItReferenceReady}
499491
/>
500492
),
501493
detail: (
@@ -517,7 +509,7 @@ const App: React.FC = () => {
517509
/>
518510
),
519511
// eslint-disable-next-line react-hooks/exhaustive-deps
520-
}), [transcript, isListening, filteredTerms, termWeights, termFrequencies, selectedTerm, searchHistory, dk, categoryFilter, handleTermClick, isPinned, handleTogglePin, themeVector, themeText, termVectors, apiTerms, isSimilarityFilterEnabled, similarityFilterStrength, similarityThreshold, isItReferenceReady]);
512+
}), [transcript, isListening, filteredTerms, termWeights, termFrequencies, selectedTerm, searchHistory, dk, categoryFilter, handleTermClick, isPinned, handleTogglePin, themeVector, themeText, termVectors, apiTerms]);
521513

522514
return (
523515
<div
@@ -541,7 +533,7 @@ const App: React.FC = () => {
541533
<div className="bg-indigo-600 p-1.5 rounded-xl text-white shadow-lg shadow-indigo-600/30">
542534
<Book size={18} />
543535
</div>
544-
<span className="text-lg font-black tracking-tight">LexiFlow</span>
536+
<span className="text-lg font-black tracking-tight">TalkScope</span>
545537
<span className="text-[9px] font-bold text-indigo-400 uppercase tracking-[0.2em] hidden sm:inline">Pro</span>
546538
</div>
547539

@@ -606,7 +598,7 @@ const App: React.FC = () => {
606598
単語管理
607599
</button>
608600

609-
<VectorApiCheckButton darkMode={dk} />
601+
610602
<button onClick={() => setIsSettingsOpen(true)} className={`p-1.5 rounded-lg transition-colors ${dk ? 'hover:bg-slate-800 text-slate-500 hover:text-slate-300' : 'hover:bg-slate-100 text-slate-400'}`}>
611603
<Settings size={18} />
612604
</button>
@@ -638,6 +630,12 @@ const App: React.FC = () => {
638630
onClose={() => setIsSettingsOpen(false)}
639631
settings={settings}
640632
updateSettings={s => setSettings(prev => ({ ...prev, ...s }))}
633+
similarityFilterEnabled={isSimilarityFilterEnabled}
634+
onSimilarityFilterEnabledChange={setIsSimilarityFilterEnabled}
635+
similarityFilterStrength={similarityFilterStrength}
636+
onSimilarityFilterStrengthChange={setSimilarityFilterStrength}
637+
similarityReferenceWord="IT"
638+
similarityReady={isItReferenceReady}
641639
/>
642640

643641
<DictionaryManagerModal

Frontend/src/app/components/BubbleCloud.tsx

Lines changed: 33 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState, useMemo } from 'react';
22
import { motion, AnimatePresence } from 'motion/react';
33
import { Term } from '../data/terms';
44
import { TermBubble } from './TermBubble';
5-
import { Hexagon, Shuffle, Pause, ChevronUp, ChevronDown, Loader2 } from 'lucide-react';
5+
import { Hexagon, Shuffle, Pause, ChevronUp, ChevronDown } from 'lucide-react';
66
import {
77
getMockTermVector,
88
getMockThemeVector,
@@ -49,20 +49,6 @@ interface BubbleCloudProps {
4949
categoryFilter?: string;
5050
/** カテゴリフィルター変更 */
5151
onCategoryFilterChange?: (category: string) => void;
52-
/** 類似度フィルタの有効状態 */
53-
similarityFilterEnabled?: boolean;
54-
/** 類似度フィルタ有効状態の変更 */
55-
onSimilarityFilterEnabledChange?: (enabled: boolean) => void;
56-
/** ベクトルフィルタの強さ(0〜100) */
57-
similarityFilterStrength?: number;
58-
/** ベクトルフィルタ強さ変更 */
59-
onSimilarityFilterStrengthChange?: (value: number) => void;
60-
/** 現在しきい値(表示用) */
61-
similarityThreshold?: number;
62-
/** 類似度基準語(現状は "it") */
63-
similarityReferenceWord?: string;
64-
/** 基準ベクトルが利用可能か */
65-
similarityReady?: boolean;
6652
}
6753

6854
export const BubbleCloud: React.FC<BubbleCloudProps> = ({
@@ -79,13 +65,6 @@ export const BubbleCloud: React.FC<BubbleCloudProps> = ({
7965
termVectors = {},
8066
categoryFilter = 'ALL',
8167
onCategoryFilterChange,
82-
similarityFilterEnabled = false,
83-
onSimilarityFilterEnabledChange,
84-
similarityFilterStrength = 50,
85-
onSimilarityFilterStrengthChange,
86-
similarityThreshold = 0.33,
87-
similarityReferenceWord = 'it',
88-
similarityReady = false,
8968
}) => {
9069
const dk = darkMode;
9170
const categories = ['ALL', 'ピン中', ...Object.keys(CATEGORY_COLORS)];
@@ -312,78 +291,41 @@ export const BubbleCloud: React.FC<BubbleCloudProps> = ({
312291

313292
return (
314293
<div className={`flex flex-col h-full transition-colors ${dk ? 'bg-[#0d0e1a]' : 'bg-white'}`}>
315-
{/* Header */}
316-
<div className={`flex items-center justify-between px-4 py-2.5 border-b shrink-0 ${dk ? 'border-slate-800/60 bg-slate-900/30' : 'border-slate-100 bg-slate-50/80'}`}>
317-
<div className="flex items-center gap-2 min-w-0">
318-
<Hexagon size={13} className={dk ? 'text-slate-600' : 'text-slate-300'} />
319-
<span className={`text-xs font-bold ${dk ? 'text-slate-300' : 'text-slate-600'}`}>用語マップ</span>
320-
{onCategoryFilterChange && (
321-
<select
322-
value={categoryFilter}
323-
onChange={(e) => onCategoryFilterChange(e.target.value)}
324-
className={`text-[10px] py-1 px-2 rounded border ${dk ? 'bg-slate-800/50 border-slate-700/50 text-slate-300' : 'bg-white border-slate-200 text-slate-700'}`}
325-
>
326-
{categories.map((c) => (
327-
<option key={c} value={c}>{c}</option>
328-
))}
329-
</select>
330-
)}
331-
{onSimilarityFilterEnabledChange && (
332-
<label className={`flex items-center gap-1.5 text-[10px] font-semibold px-2 py-1 rounded border whitespace-nowrap ${dk ? 'border-slate-700/60 bg-slate-800/40 text-slate-300' : 'border-slate-200 bg-white text-slate-700'}`}>
333-
<input
334-
type="checkbox"
335-
checked={similarityFilterEnabled}
336-
onChange={(e) => onSimilarityFilterEnabledChange(e.target.checked)}
337-
/>
338-
<span>{`"${similarityReferenceWord}" 類似`}</span>
339-
{!similarityReady && (
340-
<span className="inline-flex items-center gap-1 text-[9px] opacity-80">
341-
<Loader2 size={10} className="animate-spin" />
342-
準備中
343-
</span>
344-
)}
345-
</label>
346-
)}
347-
{onSimilarityFilterStrengthChange && similarityFilterEnabled && (
348-
<div className={`flex items-center gap-1.5 px-2 py-1 rounded border ${dk ? 'border-slate-700/60 bg-slate-800/40 text-slate-300' : 'border-slate-200 bg-white text-slate-700'}`}>
349-
<input
350-
type="range"
351-
min={0}
352-
max={100}
353-
step={1}
354-
value={similarityFilterStrength}
355-
onChange={(e) => onSimilarityFilterStrengthChange(Number(e.target.value))}
356-
className="w-20"
357-
/>
358-
<span className="text-[10px] font-mono w-10 text-right">{similarityFilterStrength}</span>
359-
<span className="text-[10px] opacity-70 whitespace-nowrap">{`th:${similarityThreshold.toFixed(2)}`}</span>
360-
</div>
361-
)}
362-
</div>
363-
<span className={`text-[10px] font-mono border px-1.5 py-0.5 rounded ${dk ? 'bg-slate-800/50 border-slate-700/50 text-slate-500' : 'bg-slate-100 border-slate-200 text-slate-400'}`}>
294+
{/* Header: filter + scale slider + term count — 1 row */}
295+
<div className={`flex items-center gap-2 px-4 py-2 border-b shrink-0 ${dk ? 'border-slate-800/60 bg-slate-900/30' : 'border-slate-100 bg-slate-50/80'}`}>
296+
<Hexagon size={13} className={dk ? 'text-slate-600' : 'text-slate-300'} />
297+
{onCategoryFilterChange && (
298+
<select
299+
value={categoryFilter}
300+
onChange={(e) => onCategoryFilterChange(e.target.value)}
301+
className={`text-[10px] py-1 px-2 rounded border shrink-0 ${dk ? 'bg-slate-800/50 border-slate-700/50 text-slate-300' : 'bg-white border-slate-200 text-slate-700'}`}
302+
>
303+
{categories.map((c) => (
304+
<option key={c} value={c}>{c}</option>
305+
))}
306+
</select>
307+
)}
308+
{categoryFilter !== 'ピン中' && (
309+
<>
310+
<span className={`text-[10px] font-bold shrink-0 ${dk ? 'text-slate-500' : 'text-slate-500'}`}>倍率</span>
311+
<input
312+
type="range"
313+
min={0.5}
314+
max={2}
315+
step={0.1}
316+
value={bubbleScale}
317+
onChange={(e) => setBubbleScale(Number(e.target.value))}
318+
className={`flex-1 h-1.5 rounded-full appearance-none cursor-pointer accent-indigo-500 min-w-0 ${dk ? 'bg-slate-700' : 'bg-slate-200'}`}
319+
/>
320+
<span className={`text-[10px] font-mono font-bold tabular-nums shrink-0 ${dk ? 'text-slate-400' : 'text-slate-600'}`}>
321+
{Math.round(bubbleScale * 100)}%
322+
</span>
323+
</>
324+
)}
325+
<span className={`ml-auto text-[10px] font-mono border px-1.5 py-0.5 rounded shrink-0 ${dk ? 'bg-slate-800/50 border-slate-700/50 text-slate-500' : 'bg-slate-100 border-slate-200 text-slate-400'}`}>
364326
{categoryFilter === 'ピン中' ? `${activeTerms.length} ピン` : `${activeTerms.length} terms`}
365327
</span>
366328
</div>
367-
368-
{/* バブル倍率スライダー(バブル表示時のみ) */}
369-
{categoryFilter !== 'ピン中' && (
370-
<div className={`flex items-center gap-3 px-4 py-2 border-b shrink-0 ${dk ? 'border-slate-800/60 bg-slate-900/20' : 'border-slate-100 bg-slate-50/50'}`}>
371-
<span className={`text-[10px] font-bold shrink-0 ${dk ? 'text-slate-400' : 'text-slate-500'}`}>バブル倍率</span>
372-
<input
373-
type="range"
374-
min={0.5}
375-
max={2}
376-
step={0.1}
377-
value={bubbleScale}
378-
onChange={(e) => setBubbleScale(Number(e.target.value))}
379-
className={`flex-1 h-2 rounded-full appearance-none cursor-pointer accent-indigo-500 ${dk ? 'bg-slate-700' : 'bg-slate-200'}`}
380-
/>
381-
<span className={`text-[10px] font-mono font-bold tabular-nums w-10 shrink-0 ${dk ? 'text-slate-400' : 'text-slate-600'}`}>
382-
{Math.round(bubbleScale * 100)}%
383-
</span>
384-
</div>
385-
)}
386-
387329
{/* ピン中: IndexedDB のピン留め一覧を表で表示(文字起こしハイライト風) */}
388330
{categoryFilter === 'ピン中' ? (
389331
<div className="flex-1 overflow-auto">

0 commit comments

Comments
 (0)