tgstate-rust / app /templates /image_hosting.html
bhgi's picture
Deploy tgstate-rust
71217a7
Raw
History Blame Contribute Delete
6.44 kB
{% extends "base.html" %}
{% block title %}图床模式 - tgState{% endblock %}
{% block content %}
<div style="display: flex; flex-direction: column; gap: 24px;">
<!-- Header -->
<div class="flex-between">
<h1 style="font-size: 24px; font-weight: 700;">图床模式</h1>
<div style="display: flex; gap: 12px; flex: 1; justify-content: flex-end; min-width: 0;">
<div class="input-group" style="margin-bottom: 0; max-width: 300px; width: 100%;">
<input type="text" id="file-search" class="input-field" placeholder="搜索图片..." style="width: 100%;">
</div>
</div>
</div>
{% if not cfg.bot_ready %}
<div class="empty-state">
<div class="empty-icon">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
</div>
<h3 class="empty-title">需要配置</h3>
<p class="empty-desc">缺少 Bot Token 或频道名,图片功能暂不可用。</p>
<a href="/settings" class="btn btn-primary">前往设置</a>
</div>
{% else %}
<!-- Upload Area -->
<div class="card" style="border-style: dashed; text-align: center; padding: 40px; cursor: pointer; transition: all 0.2s;"
id="upload-zone">
<input type="file" id="file-picker" hidden multiple accept="image/*">
<div style="color: var(--primary-color); margin-bottom: 12px;">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>
</div>
<h3 style="font-size: 16px; font-weight: 600; margin-bottom: 4px;">上传图片</h3>
<p style="color: var(--text-secondary); font-size: 14px;">拖拽图片到此处或点击选择</p>
</div>
<!-- Progress Area -->
<div id="prog-zone" style="display: flex; flex-direction: column; gap: 12px;"></div>
<div id="done-zone" style="display: flex; flex-direction: column; gap: 12px;"></div>
<!-- Batch Actions -->
<div class="flex-between hidden" id="batch-actions-bar" style="background: var(--bg-surface-hover); padding: 12px 16px; border-radius: var(--radius-md);">
<span class="text-sm font-medium"><span id="selection-counter">0</span> 项已选</span>
<div style="display: flex; gap: 8px; align-items: center; flex-wrap: wrap;">
<div class="link-format-selector" style="display: flex; gap: 4px; margin-right: 8px;">
<button class="btn btn-ghost btn-sm active format-option" data-format="url" style="height: 32px; font-size: 12px;">URL</button>
<button class="btn btn-ghost btn-sm format-option" data-format="markdown" style="height: 32px; font-size: 12px;">MD</button>
<button class="btn btn-ghost btn-sm format-option" data-format="html" style="height: 32px; font-size: 12px;">HTML</button>
</div>
<button id="copy-links-btn" class="btn btn-secondary btn-sm" style="height: 32px; font-size: 13px;">复制</button>
<button id="batch-delete-btn" class="btn btn-secondary btn-sm" style="height: 32px; font-size: 13px; color: var(--danger-color);">删除</button>
</div>
</div>
<!-- Image Grid -->
<div class="card image-grid" style="padding: 24px;">
<input type="checkbox" id="select-all-checkbox" style="display:none;"> <!-- Hidden logic hook -->
<div class="file-list" id="file-list-disk" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 16px;">
{% if files %}
{% for file in files %}
<div class="file-item image-card" style="border: 1px solid var(--border-color); border-radius: var(--radius-md); overflow: hidden; background: var(--bg-body);" id="file-item-{{ file.file_id | replace(from=':', to='-') }}" data-file-id="{{ file.file_id }}" data-file-url="/d/{{ file.display_id }}" data-filename="{{ file.filename }}" data-short-id="{{ file.short_id }}">
<div style="position: relative; aspect-ratio: 16/9; background: #000;">
<img src="/d/{{ file.display_id }}" loading="lazy" style="width: 100%; height: 100%; object-fit: contain;" alt="{{ file.filename }}">
<div style="position: absolute; top: 8px; left: 8px;">
<input type="checkbox" class="file-checkbox" data-file-id="{{ file.file_id }}" style="width: 20px; height: 20px; cursor: pointer; border-radius: 4px;">
</div>
</div>
<div style="padding: 12px;">
<div class="text-sm font-medium" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 4px;" title="{{ file.filename }}">{{ file.filename }}</div>
<div class="text-sm text-muted" style="margin-bottom: 12px;">{{ file.filesize_mb }} MB</div>
<div style="display: flex; gap: 8px;">
<button class="btn btn-secondary btn-sm copy-link-btn" style="flex: 1; height: 32px;">复制</button>
<button class="btn btn-secondary btn-sm delete" style="height: 32px; color: var(--danger-color);" onclick="deleteFile('{{ file.file_id }}')">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
</button>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div style="grid-column: 1/-1; padding: 40px; text-align: center; color: var(--text-tertiary);">
<p>暂无图片</p>
</div>
{% endif %}
</div>
</div>
{% endif %}
</div>
<script src="/static/js/main.js?v=4.0"></script>
{% endblock %}