ai_co_discuss 0.3.62 → 0.3.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend/free_room.py +23 -0
- package/backend/message_queue.py +16 -7
- package/backend/server.py +2 -2
- package/package.json +1 -1
- package/web/app.js +5 -3
- package/web/markdown.css +1 -1
- package/web/modern.css +1 -1
- package/web/modern.js +7245 -7212
package/backend/free_room.py
CHANGED
|
@@ -2319,6 +2319,29 @@ def interrupt_member(connection, room_id, member_id, token):
|
|
|
2319
2319
|
return free_view(connection, room_id)
|
|
2320
2320
|
|
|
2321
2321
|
|
|
2322
|
+
def interrupt_for_message(connection, room_id, message_id):
|
|
2323
|
+
"""The owner's "send now" of a queued message: interrupt the busy members it was just given to, so they take it next.
|
|
2324
|
+
|
|
2325
|
+
Members whose software reported it cannot stop are not interrupted: voiding their turn would only discard its answer
|
|
2326
|
+
while the next delivery still waits for it to end. Unlike the owner's stop, the rest of the queue is not paused.
|
|
2327
|
+
|
|
2328
|
+
Raises:
|
|
2329
|
+
FileExistsError: a recipient is busy and cannot be stopped; the caller keeps the message queued.
|
|
2330
|
+
"""
|
|
2331
|
+
busy = connection.execute("""SELECT DISTINCT r.member_id, m.name, c.stoppable FROM member_requests r
|
|
2332
|
+
JOIN room_members m ON m.id=r.member_id
|
|
2333
|
+
JOIN member_executions e ON e.member_id=r.member_id AND e.status IN ('dispatched','started')
|
|
2334
|
+
LEFT JOIN execution_capabilities c ON c.execution_id=e.id
|
|
2335
|
+
WHERE r.room_id=? AND r.message_id=? AND r.status='pending'""", (room_id, message_id)).fetchall()
|
|
2336
|
+
blocked = [row["name"] for row in busy if row["stoppable"] == 0]
|
|
2337
|
+
if blocked:
|
|
2338
|
+
raise FileExistsError(f"{'、'.join(blocked)} 正在执行且无法打断,这条消息继续排队,等它答完后发送")
|
|
2339
|
+
for row in busy:
|
|
2340
|
+
stop_member_work(connection, row["member_id"], "用户立即发送", "user_stop", keep_pending=True)
|
|
2341
|
+
if busy:
|
|
2342
|
+
settle_batches(connection, room_id)
|
|
2343
|
+
|
|
2344
|
+
|
|
2322
2345
|
def withdrawals(connection, room_id):
|
|
2323
2346
|
"""The room's taken-back messages by id, so the page keeps them in place while AI readers skip them."""
|
|
2324
2347
|
return [dict(row) for row in connection.execute("""SELECT w.message_id,w.kind FROM message_withdrawal_rooms r
|
package/backend/message_queue.py
CHANGED
|
@@ -72,18 +72,22 @@ def enqueue(connection, room_id, payload):
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def post_item(connection, room_id, row, post):
|
|
75
|
-
"""Post one queued message through the normal path and drop its row; a refused post keeps the row with the reason.
|
|
75
|
+
"""Post one queued message through the normal path and drop its row; a refused post keeps the row with the reason.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
The post's result (with the saved `message`), or None when it was refused.
|
|
79
|
+
"""
|
|
76
80
|
connection.execute("SAVEPOINT queued_post")
|
|
77
81
|
try:
|
|
78
|
-
post(connection, room_id, json.loads(row["payload"]), "用户")
|
|
82
|
+
result = post(connection, room_id, json.loads(row["payload"]), "用户")
|
|
79
83
|
except QUEUE_ERRORS as error:
|
|
80
84
|
connection.execute("ROLLBACK TO queued_post")
|
|
81
85
|
connection.execute("RELEASE queued_post")
|
|
82
86
|
connection.execute("UPDATE queued_messages SET failure=? WHERE id=?", (str(error)[:500] or "发送失败", row["id"]))
|
|
83
|
-
return
|
|
87
|
+
return None
|
|
84
88
|
connection.execute("RELEASE queued_post")
|
|
85
89
|
connection.execute("DELETE FROM queued_messages WHERE id=?", (row["id"],))
|
|
86
|
-
return
|
|
90
|
+
return result
|
|
87
91
|
|
|
88
92
|
|
|
89
93
|
def drain(connection, room_id, post):
|
|
@@ -131,10 +135,12 @@ def reorder(connection, room_id, ids):
|
|
|
131
135
|
connection.execute("UPDATE queued_messages SET position=? WHERE id=?", (position, item_id))
|
|
132
136
|
|
|
133
137
|
|
|
134
|
-
def queue_action(connection, room_id, token, payload, post, check):
|
|
138
|
+
def queue_action(connection, room_id, token, payload, post, check, interrupt):
|
|
135
139
|
"""The owner acts on the queue: send one now, edit, delete, reorder, resume, or switch queueing for the site.
|
|
136
140
|
|
|
137
|
-
`post(connection, room_id, payload, actor)` posts a message; `check(payload)` validates an edited one
|
|
141
|
+
`post(connection, room_id, payload, actor)` posts a message; `check(payload)` validates an edited one;
|
|
142
|
+
`interrupt(connection, room_id, message_id)` stops the busy members a message sent now was given to, so it does not
|
|
143
|
+
wait behind their current turn, and raises when one cannot be stopped, which leaves the whole write undone.
|
|
138
144
|
"""
|
|
139
145
|
require_owner(connection, room_id, token)
|
|
140
146
|
begin_write(connection)
|
|
@@ -144,8 +150,11 @@ def queue_action(connection, room_id, token, payload, post, check):
|
|
|
144
150
|
if action == "send":
|
|
145
151
|
row = queued_row(connection, room_id, payload.get("id"))
|
|
146
152
|
connection.execute("UPDATE queued_messages SET failure='' WHERE id=?", (row["id"],))
|
|
147
|
-
|
|
153
|
+
result = post_item(connection, room_id, row, post)
|
|
154
|
+
if not result:
|
|
148
155
|
raise ValueError(connection.execute("SELECT failure FROM queued_messages WHERE id=?", (row["id"],)).fetchone()[0])
|
|
156
|
+
if result.get("message"):
|
|
157
|
+
interrupt(connection, room_id, result["message"]["id"])
|
|
149
158
|
elif action == "edit":
|
|
150
159
|
edit_item(connection, queued_row(connection, room_id, payload.get("id")), payload.get("text"), check)
|
|
151
160
|
elif action == "delete":
|
package/backend/server.py
CHANGED
|
@@ -28,7 +28,7 @@ from .remote_launch import (COMMAND_WAIT_MAX, claim_machine_commands, finish_mac
|
|
|
28
28
|
machine_launch_action, machine_sync, pair_machine, remote_launch_status, submit_machine_command,
|
|
29
29
|
submit_remote_launch)
|
|
30
30
|
from .free_room import (add_member, after_free_message, after_proactive, authorize_free_write, check_answer, execution_action, free_view,
|
|
31
|
-
inbox, interrupt_member, member_action, member_capability, member_values, migrate_free_tables, reserve_execution,
|
|
31
|
+
inbox, interrupt_for_message, interrupt_member, member_action, member_capability, member_values, migrate_free_tables, reserve_execution,
|
|
32
32
|
save_room_access, view_execution)
|
|
33
33
|
from .free_room import convert_suggestion, message_suggestions, save_suggestions, sync_participants
|
|
34
34
|
from .free_room import adopt_recommendation, recommend_member, register_member, require_member
|
|
@@ -2280,7 +2280,7 @@ class DiscussionHandler(BaseHTTPRequestHandler):
|
|
|
2280
2280
|
connection.commit()
|
|
2281
2281
|
return self.respond(result)
|
|
2282
2282
|
if parts[3:] == ["queue"] and method == "POST":
|
|
2283
|
-
result = queue_action(connection, room_id, token, self.read_payload(), post_queued, check_queued)
|
|
2283
|
+
result = queue_action(connection, room_id, token, self.read_payload(), post_queued, check_queued, interrupt_for_message)
|
|
2284
2284
|
connection.commit()
|
|
2285
2285
|
return self.respond(result)
|
|
2286
2286
|
if parts[3:4] in (["inbox"], ["executions"], ["members"], ["suggestions"], ["recommendations"], ["stop"]):
|
package/package.json
CHANGED
package/web/app.js
CHANGED
|
@@ -59,8 +59,9 @@ const RELAY_CIPHER_INFO = "codiscuss-relay-v1";
|
|
|
59
59
|
const RELAY_PROTOCOL = "codiscuss-relay";
|
|
60
60
|
const RELAY_PING_MS = 25000;
|
|
61
61
|
const ROOM_RELAY_PATH = /^\/api\/(rooms|folders|revisions)(\/|\?|$)/;
|
|
62
|
-
// One part
|
|
63
|
-
|
|
62
|
+
// One part is base64-encoded, encrypted and base64-encoded again (about 16/9 of its size), and the sealed request
|
|
63
|
+
// must stay inside the hosted site's 512 KiB request limit (backend/worker.mjs MAX_BODY_BYTES).
|
|
64
|
+
const RELAY_UPLOAD_PART_BYTES = 256 * 1024;
|
|
64
65
|
const COMPUTER_UNREACHABLE = "电脑未连接:请先与电脑配对,并确认电脑开机且运行 codiscuss";
|
|
65
66
|
let local_connection = null;
|
|
66
67
|
let computer_connecting = false;
|
|
@@ -4543,7 +4544,8 @@ function view_snapshot() {
|
|
|
4543
4544
|
archive_pending: [...state.archive_changes.keys()], import_progress: structuredClone(state.import_progress),
|
|
4544
4545
|
directory_pending: [...state.directory_pending.keys()], folder_pending: [...state.folder_moves.keys()], creating_room: state.creating_room,
|
|
4545
4546
|
connected: state.connected, reconnecting: state.reconnecting, backup_pending: Boolean(state.backup_pending), page: state.page, pages: state.pages, query: state.query,
|
|
4546
|
-
attachment_drafts: state.attachment_drafts.map(item => ({ id: item.id, file_name: item.file.name, size: item.file.size, preview_url: item.preview_url
|
|
4547
|
+
attachment_drafts: state.attachment_drafts.map(item => ({ id: item.id, file_name: item.file.name, size: item.file.size, preview_url: item.preview_url,
|
|
4548
|
+
uploading: state.sending_message && !item.uploaded })),
|
|
4547
4549
|
upload_status: state.upload_status, sending_message: state.sending_message, sending_preview: state.sending_preview,
|
|
4548
4550
|
mention_only: state.mention_only, host_only: state.host_only, reply_to: state.reply_to, editing_queued: state.editing_queued?.id ?? null,
|
|
4549
4551
|
access: access_snapshot(), admin: admin_snapshot(),
|
package/web/markdown.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.markdown-body{--markdown-line:#c3ced8;--markdown-panel:#edf2f6;--markdown-link:#31647d;white-space:normal;overflow-wrap:anywhere;min-width:0}html[data-theme=channel] .markdown-body{--markdown-line:#454852;--markdown-panel:#202228;--markdown-code:#ffffff14;--markdown-link:#abb8ff}html[data-theme=channel-light] .markdown-body{--markdown-line:#dedede;--markdown-panel:#f6f6f6;--markdown-link:#0969da}.markdown-body>:first-child{margin-top:0}.markdown-body>:last-child{margin-bottom:0}.markdown-body p{margin:0 0 .8em}.markdown-body :is(h1,h2,h3,h4,h5,h6){color:inherit;margin:1.3em 0 .55em;font-weight:650;line-height:1.4}.markdown-body h1{font-size:1.5em}.markdown-body h2{font-size:1.3em}.markdown-body h3{font-size:1.15em}.markdown-body :is(h4,h5,h6){font-size:1em}.markdown-body strong{font-weight:700}.markdown-body em{font-style:italic}.markdown-body :is(ul,ol){margin:.5em 0 .9em;padding-left:1.7em}.markdown-body ul{list-style:outside}.markdown-body ol{list-style:decimal}.markdown-body ul ul{list-style:circle}.markdown-body li{margin:.25em 0;padding-left:.15em}.markdown-body li>:is(ul,ol,p){margin-top:.3em;margin-bottom:.3em}.markdown-body blockquote{border-left:3px solid var(--markdown-line);color:inherit;margin:1em 0;padding:.2em 1em}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body hr{border:0;border-top:1px solid var(--markdown-line);margin:1.3em 0}.markdown-body a{color:var(--markdown-link);text-underline-offset:3px;text-decoration:underline}.markdown-body code{background:var(--markdown-code,var(--markdown-panel));border-radius:4px;padding:.15em .35em;font-family:ui-monospace,Consolas,monospace;font-size:.88em}.markdown-body pre{border:1px solid var(--markdown-line);background:var(--markdown-panel);white-space:pre;overflow-wrap:normal;border-radius:6px;max-width:100%;margin:.8em 0 1em;padding:14px 16px;line-height:1.6;overflow-x:auto}.markdown-body pre code{white-space:inherit;background:0 0;border:0;border-radius:0;padding:0}.markdown-body .markdown-table{max-width:100%;margin:1em 0;overflow-x:auto}.markdown-body table{border-collapse:collapse;width:max-content;min-width:50%;max-width:100%;font-size:.93em}.markdown-body :is(th,td){border:1px solid var(--markdown-line);text-align:left;min-width:6em;padding:.55em .8em}.markdown-body th{background:var(--markdown-panel);font-weight:650}.markdown-body img{max-width:100%;height:auto}.markdown-body .mention{color:var(--markdown-link);background:0 0;border-radius:3px;padding:0 2px}.markdown-body .katex{font-size:1.1em}.markdown-body .katex-display{max-width:100%;padding:.3em 0;overflow:auto hidden}.markdown-body .katex-error{color:inherit;white-space:pre-wrap;font-family:ui-monospace,Consolas,monospace}.message-attachments{flex-direction:column;align-items:flex-start;gap:10px;max-width:100%;margin:10px 0 0;display:flex}.attachment-image{cursor:zoom-in;background:0 0;border:0;border-radius:8px;max-width:100%;padding:0;display:block;overflow:hidden}.attachment-image img{object-fit:contain;border-radius:inherit;width:auto;max-width:min(360px,100%);height:auto;max-height:320px;display:block}.attachment-file,.attachment-draft-file{color:#253044;background:#fff;border:1px solid #dce1e9;border-radius:8px;align-items:center;display:flex}.attachment-file{width:min(400px,100%);min-height:76px;padding-right:12px}.attachment-file-main{text-align:left;min-width:0;color:inherit;border-radius:inherit;cursor:pointer;font:inherit;background:0 0;border:0;flex:1;align-items:center;gap:14px;padding:14px 16px;text-decoration:none;display:flex}.attachment-file-main:hover .attachment-name>span{text-underline-offset:3px;text-decoration:underline}.attachment-file-icon{color:#3973f9;flex:none;width:32px;height:40px;display:block;position:relative}.attachment-file-icon svg{width:100%;height:100%;display:block}.attachment-file-icon>span{text-align:center;color:#fff;letter-spacing:-.2px;width:100%;font:650 9px/1.2 system-ui,sans-serif;position:absolute;top:21px;left:0}.attachment-file-icon[data-tone=red]{color:#e65c58}.attachment-file-icon[data-tone=green]{color:#2aa875}.attachment-file-icon[data-tone=orange]{color:#e58b3b}.attachment-name{flex:1;min-width:0;font-size:13px;line-height:1.5;display:block}.attachment-name>span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.attachment-name small{color:#808998;margin-top:4px;font-size:11px;font-weight:400;display:block}.attachment-download{color:#707b8c;border-radius:5px;flex-shrink:0;place-items:center;width:32px;height:32px;text-decoration:none;display:grid}.attachment-download svg{width:18px;height:18px}.attachment-download:hover{color:#3868d9;background:#edf2fc}.attachment-drafts{flex-wrap:wrap;align-items:center;gap:10px;margin:0;padding:16px 14px 6px;display:flex}.attachment-drafts:empty{display:none}.attachment-draft-image{background:#edf0f4;border-radius:7px;width:88px;height:88px;position:relative}.attachment-draft-image img{object-fit:contain;border-radius:inherit;width:100%;height:100%;display:block}.attachment-remove{color:#707b8c;cursor:pointer;background:0 0;border:0;border-radius:50%;flex-shrink:0;place-items:center;width:24px;height:24px;padding:0;font-size:14px;display:grid}.attachment-remove:hover{color:#253044;background:#e9edf4}.attachment-remove:disabled{opacity:.4;cursor:default}.attachment-draft-image .attachment-remove{color:#fff;background:#444d60;border:2px solid #fff;position:absolute;top:-5px;right:-5px}.attachment-draft-image .attachment-remove:hover{background:#252d3e}.attachment-draft-file{gap:10px;width:min(280px,100%);padding:10px}.attachment-draft-file>span:first-child{flex-shrink:0}.attachment-draft-file .attachment-file-icon{width:28px;height:34px}.attachment-draft-file .attachment-file-icon>span{font-size:8px;top:18px}.attachment-composer-tools{align-items:center;gap:12px;margin-top:8px;font-size:12px;display:flex}.attachment-status{overflow-wrap:anywhere;margin:8px 0;font-size:12px;line-height:1.5}.attachment-status:empty{display:none}.attachment-status[role=alert]{color:#b44b40}.attachment-dialog{color:#253044;background:#f4f6f9;border:1px solid #cad2df;border-radius:12px;width:min(1100px,100vw - 32px);max-width:none;height:min(850px,100dvh - 48px);max-height:none;margin:auto;padding:0;box-shadow:0 16px 64px #0006}.attachment-dialog[open]{flex-direction:column;display:flex}.attachment-dialog::backdrop{background:#0d142bb3}.attachment-preview-heading{border-bottom:1px solid #cad2df;flex-shrink:0;align-items:center;gap:16px;padding:14px 18px;display:flex}.attachment-preview-heading h2{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;margin:0;font-size:15px;font-weight:600;overflow:hidden}.attachment-preview-heading a{color:inherit;flex-shrink:0;font-size:13px;text-decoration:underline}.attachment-dialog button{color:inherit;cursor:pointer;font:inherit;background:0 0;border:1px solid #b8c4d3;border-radius:5px;padding:5px 9px;font-size:13px}.attachment-dialog button:disabled{opacity:.4;cursor:default}.attachment-pdf-controls{flex-wrap:wrap;flex-shrink:0;justify-content:center;align-items:center;gap:10px;padding:10px;display:flex}.attachment-dialog .attachment-status{padding:0 18px}.attachment-viewer{overscroll-behavior:contain;flex:1;min-height:0;padding:16px;overflow:auto}.attachment-viewer img{object-fit:contain;width:auto;max-width:100%;height:auto;max-height:100%;margin:auto;display:block}.attachment-viewer canvas{background:#fff;margin:0 auto;display:block;box-shadow:0 1px 8px #0002}.attachment-dialog [hidden]{display:none!important}html[data-theme=channel] :is(.attachment-file,.attachment-draft-file,.attachment-dialog){color:#dde1ec;background:#282c36;border-color:#434958}html[data-theme=channel] .attachment-name small{color:#99a1b1}html[data-theme=channel] :is(.attachment-download,.attachment-remove){color:#aeb7c7}html[data-theme=channel] :is(.attachment-download,.attachment-remove):hover{color:#e3e9fb;background:#3b4252}html[data-theme=channel] .attachment-draft-image{background:#1b1f29}html[data-theme=channel] .attachment-draft-image .attachment-remove{color:#fff;border-color:#282c36}html[data-theme=channel] :is(.attachment-preview-heading,.attachment-dialog button){border-color:#4b5366}html[data-theme=channel] .attachment-status[role=alert]{color:#f4a89e}@media (width<=600px){.attachment-dialog{width:calc(100vw - 16px);height:calc(100dvh - 24px)}.attachment-preview-heading{gap:10px;padding:12px}.attachment-composer-tools{flex-wrap:wrap}}
|
|
1
|
+
.markdown-body{--markdown-line:#c3ced8;--markdown-panel:#edf2f6;--markdown-link:#31647d;white-space:normal;overflow-wrap:anywhere;min-width:0}html[data-theme=channel] .markdown-body{--markdown-line:#454852;--markdown-panel:#202228;--markdown-code:#ffffff14;--markdown-link:#abb8ff}html[data-theme=channel-light] .markdown-body{--markdown-line:#dedede;--markdown-panel:#f6f6f6;--markdown-link:#0969da}.markdown-body>:first-child{margin-top:0}.markdown-body>:last-child{margin-bottom:0}.markdown-body p{margin:0 0 .8em}.markdown-body :is(h1,h2,h3,h4,h5,h6){color:inherit;margin:1.3em 0 .55em;font-weight:650;line-height:1.4}.markdown-body h1{font-size:1.5em}.markdown-body h2{font-size:1.3em}.markdown-body h3{font-size:1.15em}.markdown-body :is(h4,h5,h6){font-size:1em}.markdown-body strong{font-weight:700}.markdown-body em{font-style:italic}.markdown-body :is(ul,ol){margin:.5em 0 .9em;padding-left:1.7em}.markdown-body ul{list-style:outside}.markdown-body ol{list-style:decimal}.markdown-body ul ul{list-style:circle}.markdown-body li{margin:.25em 0;padding-left:.15em}.markdown-body li>:is(ul,ol,p){margin-top:.3em;margin-bottom:.3em}.markdown-body blockquote{border-left:3px solid var(--markdown-line);color:inherit;margin:1em 0;padding:.2em 1em}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body hr{border:0;border-top:1px solid var(--markdown-line);margin:1.3em 0}.markdown-body a{color:var(--markdown-link);text-underline-offset:3px;text-decoration:underline}.markdown-body code{background:var(--markdown-code,var(--markdown-panel));border-radius:4px;padding:.15em .35em;font-family:ui-monospace,Consolas,monospace;font-size:.88em}.markdown-body pre{border:1px solid var(--markdown-line);background:var(--markdown-panel);white-space:pre;overflow-wrap:normal;border-radius:6px;max-width:100%;margin:.8em 0 1em;padding:14px 16px;line-height:1.6;overflow-x:auto}.markdown-body pre code{white-space:inherit;background:0 0;border:0;border-radius:0;padding:0}.markdown-body .markdown-table{max-width:100%;margin:1em 0;overflow-x:auto}.markdown-body table{border-collapse:collapse;width:max-content;min-width:50%;max-width:100%;font-size:.93em}.markdown-body :is(th,td){border:1px solid var(--markdown-line);text-align:left;min-width:6em;padding:.55em .8em}.markdown-body th{background:var(--markdown-panel);font-weight:650}.markdown-body img{max-width:100%;height:auto}.markdown-body .mention{color:var(--markdown-link);background:0 0;border-radius:3px;padding:0 2px}.markdown-body .katex{font-size:1.1em}.markdown-body .katex-display{max-width:100%;padding:.3em 0;overflow:auto hidden}.markdown-body .katex-error{color:inherit;white-space:pre-wrap;font-family:ui-monospace,Consolas,monospace}.message-attachments{flex-direction:column;align-items:flex-start;gap:10px;max-width:100%;margin:10px 0 0;display:flex}.attachment-image{cursor:zoom-in;background:0 0;border:0;border-radius:8px;max-width:100%;padding:0;display:block;overflow:hidden}.attachment-image img{object-fit:contain;border-radius:inherit;width:auto;max-width:min(360px,100%);height:auto;max-height:320px;display:block}.attachment-image:has(img[data-relay-src]:not([src])){width:160px;height:120px;color:inherit;background:color-mix(in srgb, currentColor 8%, transparent);place-items:center;display:grid;position:relative}.attachment-image img[data-relay-src]:not([src]){display:none}.attachment-image:has(img[data-relay-src]:not([src]):not([data-relay-failed])):after{content:"";border:2px solid color-mix(in srgb, currentColor 25%, transparent);border-top-color:color-mix(in srgb, currentColor 70%, transparent);border-radius:50%;width:24px;height:24px;animation:.8s linear infinite attachment-spin}.attachment-image:has(img[data-relay-failed]):after{content:"图片加载失败";opacity:.6;font-size:12px}.attachment-file,.attachment-draft-file{color:#253044;background:#fff;border:1px solid #dce1e9;border-radius:8px;align-items:center;display:flex}.attachment-file{width:min(400px,100%);min-height:76px;padding-right:12px}.attachment-file-main{text-align:left;min-width:0;color:inherit;border-radius:inherit;cursor:pointer;font:inherit;background:0 0;border:0;flex:1;align-items:center;gap:14px;padding:14px 16px;text-decoration:none;display:flex}.attachment-file-main:hover .attachment-name>span{text-underline-offset:3px;text-decoration:underline}.attachment-file-icon{color:#3973f9;flex:none;width:32px;height:40px;display:block;position:relative}.attachment-file-icon svg{width:100%;height:100%;display:block}.attachment-file-icon>span{text-align:center;color:#fff;letter-spacing:-.2px;width:100%;font:650 9px/1.2 system-ui,sans-serif;position:absolute;top:21px;left:0}.attachment-file-icon[data-tone=red]{color:#e65c58}.attachment-file-icon[data-tone=green]{color:#2aa875}.attachment-file-icon[data-tone=orange]{color:#e58b3b}.attachment-name{flex:1;min-width:0;font-size:13px;line-height:1.5;display:block}.attachment-name>span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.attachment-name small{color:#808998;margin-top:4px;font-size:11px;font-weight:400;display:block}.attachment-download{color:#707b8c;border-radius:5px;flex-shrink:0;place-items:center;width:32px;height:32px;text-decoration:none;display:grid}.attachment-download svg{width:18px;height:18px}.attachment-download:hover{color:#3868d9;background:#edf2fc}.attachment-drafts{flex-wrap:wrap;align-items:center;gap:10px;margin:0;padding:16px 14px 6px;display:flex}.attachment-drafts:empty{display:none}.attachment-draft-image{background:#edf0f4;border-radius:7px;width:88px;height:88px;position:relative}.attachment-draft-image img{object-fit:contain;border-radius:inherit;width:100%;height:100%;display:block}.attachment-remove{color:#707b8c;cursor:pointer;background:0 0;border:0;border-radius:50%;flex-shrink:0;place-items:center;width:24px;height:24px;padding:0;font-size:14px;display:grid}.attachment-remove:hover{color:#253044;background:#e9edf4}.attachment-remove:disabled{opacity:.4;cursor:default}.attachment-draft-image .attachment-remove{color:#fff;background:#444d60;border:2px solid #fff;position:absolute;top:-5px;right:-5px}.attachment-draft-image .attachment-remove:hover{background:#252d3e}.attachment-draft-file{gap:10px;width:min(280px,100%);padding:10px;position:relative}.attachment-uploading{z-index:1;border-radius:inherit;color:#fff;background:#0008;place-items:center;display:grid;position:absolute;inset:0}.attachment-uploading>span{width:26px;height:26px;animation:.8s linear infinite attachment-spin}@keyframes attachment-spin{to{transform:rotate(360deg)}}.attachment-draft-file>span:first-child{flex-shrink:0}.attachment-draft-file .attachment-file-icon{width:28px;height:34px}.attachment-draft-file .attachment-file-icon>span{font-size:8px;top:18px}.attachment-composer-tools{align-items:center;gap:12px;margin-top:8px;font-size:12px;display:flex}.attachment-status{overflow-wrap:anywhere;margin:8px 0;font-size:12px;line-height:1.5}.attachment-status:empty{display:none}.attachment-status[role=alert]{color:#b44b40}.attachment-dialog{color:#253044;background:#f4f6f9;border:1px solid #cad2df;border-radius:12px;width:min(1100px,100vw - 32px);max-width:none;height:min(850px,100dvh - 48px);max-height:none;margin:auto;padding:0;box-shadow:0 16px 64px #0006}.attachment-dialog[open]{flex-direction:column;display:flex}.attachment-dialog::backdrop{background:#0d142bb3}.attachment-preview-heading{border-bottom:1px solid #cad2df;flex-shrink:0;align-items:center;gap:16px;padding:14px 18px;display:flex}.attachment-preview-heading h2{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;margin:0;font-size:15px;font-weight:600;overflow:hidden}.attachment-preview-heading a{color:inherit;flex-shrink:0;font-size:13px;text-decoration:underline}.attachment-dialog button{color:inherit;cursor:pointer;font:inherit;background:0 0;border:1px solid #b8c4d3;border-radius:5px;padding:5px 9px;font-size:13px}.attachment-dialog button:disabled{opacity:.4;cursor:default}.attachment-pdf-controls{flex-wrap:wrap;flex-shrink:0;justify-content:center;align-items:center;gap:10px;padding:10px;display:flex}.attachment-dialog .attachment-status{padding:0 18px}.attachment-viewer{overscroll-behavior:contain;flex:1;min-height:0;padding:16px;overflow:auto}.attachment-viewer img{object-fit:contain;width:auto;max-width:100%;height:auto;max-height:100%;margin:auto;display:block}.attachment-viewer canvas{background:#fff;margin:0 auto;display:block;box-shadow:0 1px 8px #0002}.attachment-dialog [hidden]{display:none!important}html[data-theme=channel] :is(.attachment-file,.attachment-draft-file,.attachment-dialog){color:#dde1ec;background:#282c36;border-color:#434958}html[data-theme=channel] .attachment-name small{color:#99a1b1}html[data-theme=channel] :is(.attachment-download,.attachment-remove){color:#aeb7c7}html[data-theme=channel] :is(.attachment-download,.attachment-remove):hover{color:#e3e9fb;background:#3b4252}html[data-theme=channel] .attachment-draft-image{background:#1b1f29}html[data-theme=channel] .attachment-draft-image .attachment-remove{color:#fff;border-color:#282c36}html[data-theme=channel] :is(.attachment-preview-heading,.attachment-dialog button){border-color:#4b5366}html[data-theme=channel] .attachment-status[role=alert]{color:#f4a89e}@media (width<=600px){.attachment-dialog{width:calc(100vw - 16px);height:calc(100dvh - 24px)}.attachment-preview-heading{gap:10px;padding:12px}.attachment-composer-tools{flex-wrap:wrap}}
|
|
2
2
|
/*$vite$:1*/
|