增加语音对话功能

This commit is contained in:
yhy
2026-08-29 22:13:55 +08:00
parent 1ffa069151
commit 3a2438f566
51 changed files with 6207 additions and 3 deletions
+212
View File
@@ -752,3 +752,215 @@
.chatpapers-cite-btn {
flex-shrink: 0;
}
/* --- Voice lecture pane --- */
.chatpapers-lecture-root {
gap: 10px;
}
.chatpapers-lecture-empty {
padding: 20px 12px;
}
.chatpapers-lecture-status {
padding: 8px 10px;
border-radius: 8px;
font-size: 12px;
line-height: 1.45;
background: color-mix(in srgb, #1f7a8c 10%, transparent);
border: 1px solid color-mix(in srgb, #1f7a8c 22%, transparent);
}
.chatpapers-lecture-status[data-status="failed"] {
background: color-mix(in srgb, #dc2626 10%, transparent);
border-color: color-mix(in srgb, #dc2626 25%, transparent);
}
.chatpapers-lecture-status[data-status="ready"] {
background: color-mix(in srgb, #16a34a 10%, transparent);
border-color: color-mix(in srgb, #16a34a 25%, transparent);
}
.chatpapers-lecture-actions {
display: flex;
gap: 8px;
}
.chatpapers-lecture-primary {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
border: none;
border-radius: 8px;
background: #1f7a8c;
color: #fff;
font-size: 13px;
font-weight: 600;
cursor: pointer;
}
.chatpapers-lecture-primary:hover:not(:disabled) {
background: #186678;
}
.chatpapers-lecture-status-text {
white-space: pre-line;
}
.chatpapers-lecture-primary:disabled {
opacity: 0.55;
cursor: not-allowed;
}
.chatpapers-lecture-secondary {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 14px;
border: 1px solid color-mix(in srgb, #1f7a8c 35%, transparent);
border-radius: 8px;
background: transparent;
color: inherit;
font-size: 13px;
font-weight: 600;
cursor: pointer;
}
.chatpapers-lecture-secondary:hover:not(:disabled) {
background: color-mix(in srgb, #1f7a8c 10%, transparent);
}
.chatpapers-lecture-secondary:disabled {
opacity: 0.55;
cursor: not-allowed;
}
.chatpapers-lecture-tts-meta {
font-size: 12px;
opacity: 0.75;
}
.chatpapers-lecture-audio {
width: 100%;
margin-top: 4px;
}
.chatpapers-lecture-btn-icon {
flex-shrink: 0;
}
.chatpapers-lecture-hint {
font-size: 11px;
opacity: 0.65;
line-height: 1.4;
}
.chatpapers-lecture-player {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 4px;
}
.chatpapers-lecture-player-title {
font-size: 12px;
font-weight: 600;
opacity: 0.85;
}
.chatpapers-lecture-beat-list {
display: flex;
flex-direction: column;
gap: 4px;
max-height: 220px;
overflow-y: auto;
}
.chatpapers-lecture-beat-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 8px 10px;
border: 1px solid color-mix(in srgb, #1f7a8c 18%, transparent);
border-radius: 8px;
background: color-mix(in srgb, #1f7a8c 4%, transparent);
cursor: pointer;
text-align: left;
font: inherit;
color: inherit;
}
.chatpapers-lecture-beat-item:hover:not(:disabled) {
background: color-mix(in srgb, #1f7a8c 10%, transparent);
}
.chatpapers-lecture-beat-item.is-active {
border-color: color-mix(in srgb, #16a34a 45%, transparent);
background: color-mix(in srgb, #16a34a 10%, transparent);
}
.chatpapers-lecture-beat-item.is-pending {
opacity: 0.55;
cursor: default;
}
.chatpapers-lecture-beat-meta {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.chatpapers-lecture-beat-type {
font-size: 10px;
font-weight: 600;
opacity: 0.65;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.chatpapers-lecture-beat-title {
font-size: 12px;
line-height: 1.35;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.chatpapers-lecture-beat-status {
flex-shrink: 0;
font-size: 11px;
opacity: 0.7;
}
.chatpapers-lecture-player-controls {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.chatpapers-lecture-player-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border: 1px solid color-mix(in srgb, #1f7a8c 30%, transparent);
border-radius: 999px;
background: transparent;
cursor: pointer;
color: inherit;
}
.chatpapers-lecture-player-btn:hover {
background: color-mix(in srgb, #1f7a8c 12%, transparent);
}
.chatpapers-lecture-error {
padding: 12px;
color: #dc2626;
font-size: 12px;
}
+28
View File
@@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
<!-- ChatPapers voice lecture: paper + headphones -->
<path
fill="context-fill"
fill-opacity="0.92"
d="M3.2 2.8h7.4c.4 0 .7.15.95.4l2.05 2.1c.25.25.4.58.4.95V14.2c0 .9-.73 1.63-1.63 1.63H3.2c-.9 0-1.63-.73-1.63-1.63V4.43C1.57 3.53 2.3 2.8 3.2 2.8z"
/>
<path
fill="context-fill"
fill-opacity="0.35"
d="M10.6 2.85v2.35c0 .45.37.82.82.82h2.35L10.6 2.85z"
/>
<path
stroke="context-stroke"
stroke-opacity="0.55"
stroke-width="0.9"
stroke-linecap="round"
d="M4.35 7.1h5.1M4.35 9.15h4.2"
/>
<path
fill="context-fill"
d="M12.1 8.35c1.45 0 2.65 1.15 2.65 2.55v2.1c0 .35-.28.62-.62.62h-.75v1.05c0 .55-.45 1-1 1h-.55c-.55 0-1-.45-1-1v-1.05h-.55c-.35 0-.62-.28-.62-.62v-2.1c0-1.4 1.2-2.55 2.65-2.55z"
/>
<path
fill="context-fill"
d="M16.55 9.05c1.05 0 1.9.82 1.9 1.85v1.35c0 1-.85 1.85-1.9 1.85-.35 0-.62-.28-.62-.62v-3.8c0-.35.28-.62.62-.62z"
/>
</svg>

After

Width:  |  Height:  |  Size: 1020 B

+63
View File
@@ -116,6 +116,69 @@
</hbox>
</groupbox>
<groupbox>
<label><html:h2 data-l10n-id="prefs-section-lecture"></html:h2></label>
<html:p id="chatpapers-pref-tts-hint" class="chatpapers-pref-hint"></html:p>
<hbox align="center">
<html:label
for="chatpapers-pref-tts-provider"
data-l10n-id="prefs-tts-provider"
></html:label>
<html:select id="chatpapers-pref-tts-provider" preference="ttsProvider">
</html:select>
</hbox>
<hbox align="center">
<html:label
for="chatpapers-pref-tts-voice"
data-l10n-id="prefs-tts-voice"
></html:label>
<html:input
type="text"
id="chatpapers-pref-tts-voice"
preference="ttsVoice"
></html:input>
</hbox>
<vbox id="chatpapers-pref-piper-box" hidden="true">
<hbox align="center">
<html:label
for="chatpapers-pref-piper-path"
data-l10n-id="prefs-piper-path"
></html:label>
<html:input
type="text"
id="chatpapers-pref-piper-path"
preference="piperPath"
></html:input>
</hbox>
<hbox align="center">
<html:label
for="chatpapers-pref-piper-model"
data-l10n-id="prefs-piper-model"
></html:label>
<html:input
type="text"
id="chatpapers-pref-piper-model"
preference="piperModelPath"
></html:input>
</hbox>
</vbox>
<hbox align="center">
<html:label
for="chatpapers-pref-mineru-path"
data-l10n-id="prefs-mineru-path"
></html:label>
<html:input
type="text"
id="chatpapers-pref-mineru-path"
preference="mineruPath"
></html:input>
</hbox>
</groupbox>
<groupbox>
<label><html:h2 data-l10n-id="prefs-section-prompts"></html:h2></label>
<html:label data-l10n-id="prefs-system-prompt"></html:label>