Skip to content
Open
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
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ structured chat data and Codex sessions in the browser.
| :-------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
| Harmony conversation viewer | Renders Harmony conversations with support for different message types and metadata. |
| Codex session viewer | Detects Codex session JSONL files, converts them into a conversation, and renders them in the same viewer. |
| Flexible loading | Loads data from the clipboard, local `.json` or `.jsonl` files, or public HTTP(S) JSON/JSONL URLs. |
| Flexible loading | Loads data from drag-and-drop, the clipboard, local `.json` or `.jsonl` files, or public HTTP(S) JSON/JSONL URLs. |
| Markdown and HTML rendering | Renders markdown in message content, including formulas and optional HTML blocks. |
| Translation | Translates non-English text into English in normal mode or frontend-only mode with a user-provided OpenAI API key. |
| Metadata inspection | Exposes conversation-level and message-level metadata directly in the UI. |
Expand All @@ -50,8 +50,9 @@ There are two ways you can use Euphony.

1. Load data from one of the supported sources:
1. Paste JSON or JSONL from the clipboard
2. Choose a local `.json` or `.jsonl` file
3. Provide a public HTTP(S) URL that serves JSON or JSONL (e.g., Hugging Face)
2. Drag and drop a local `.json` or `.jsonl` file onto the app
3. Choose a local `.json` or `.jsonl` file
4. Provide a public HTTP(S) URL that serves JSON or JSONL (e.g., Hugging Face)
2. Euphony automatically detects and renders the input:
1. If the JSONL is a list of conversations → Euphony renders all conversations
2. If the JSONL is a Codex session file → Euphony renders a structured Codex session timeline
Expand Down
71 changes: 71 additions & 0 deletions src/components/app/app.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
@import '../../css/component-global.css';

.app-shell {
width: 100%;
height: 100%;
position: relative;
}

.app {
width: 100%;
height: 100%;
Expand Down Expand Up @@ -54,6 +60,69 @@
}
}

.local-file-drop-overlay {
position: absolute;
inset: 0;
z-index: 4;

display: flex;
justify-content: center;
align-items: center;

padding: 24px;
box-sizing: border-box;

background:
linear-gradient(
135deg,
color-mix(in lab, var(--blue-50), white 18%) 0%,
color-mix(in lab, var(--blue-100), white 30%) 100%
),
rgba(255, 255, 255, 0.88);
backdrop-filter: blur(6px);

opacity: 0;
pointer-events: none;
transition: opacity 160ms ease;

&[is-visible] {
opacity: 1;
}
}

.local-file-drop-panel {
width: min(520px, calc(100vw - 48px));
padding: 28px 32px;
box-sizing: border-box;

border: 2px dashed color-mix(in lab, var(--blue-300), black 8%);
border-radius: 18px;
background: rgba(255, 255, 255, 0.94);
box-shadow:
0 20px 50px rgba(0, 90, 142, 0.12),
0 6px 20px rgba(17, 27, 39, 0.08);

display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
text-align: center;
}

.local-file-drop-title {
color: var(--blue-900);
font-size: 1.35rem;
font-weight: 700;
line-height: 1.2;
}

.local-file-drop-subtitle {
color: var(--gray-700);
font-size: var(--font-d2);
line-height: 1.5;
max-width: 36ch;
}

.header {
width: 100%;
padding: 20px 0 20px 0;
Expand Down Expand Up @@ -646,6 +715,8 @@ button,
.toast-container {
position: absolute;
top: 7px;
left: 50%;
transform: translateX(-50%);
z-index: 5;
display: flex;
justify-content: center;
Expand Down
Loading