Update App.jsx via upload script - 2026-08-13 11:08:12
This commit is contained in:
parent
7c37a4e171
commit
4b8747d72f
38
App.jsx
38
App.jsx
|
|
@ -2523,6 +2523,10 @@ function MainApp({ username, onLogout }) {
|
||||||
notify('已删除');
|
notify('已删除');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reorderJmsLines(fromIndex, toIndex) {
|
||||||
|
setJmsLines(prev => reorderArray(prev, fromIndex, toIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function handleExportProductPdf() {
|
async function handleExportProductPdf() {
|
||||||
|
|
@ -3243,6 +3247,7 @@ function MainApp({ username, onLogout }) {
|
||||||
lines={jmsLines}
|
lines={jmsLines}
|
||||||
onSave={saveJmsLine}
|
onSave={saveJmsLine}
|
||||||
onDelete={deleteJmsLine}
|
onDelete={deleteJmsLine}
|
||||||
|
onReorder={reorderJmsLines}
|
||||||
onNotify={notify}
|
onNotify={notify}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -4352,15 +4357,25 @@ function jmsCopyText(text, label, onNotify) {
|
||||||
.catch(() => onNotify && onNotify('复制失败,请手动选择'));
|
.catch(() => onNotify && onNotify('复制失败,请手动选择'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function JmsLineCard({ line, ip, onRefreshIp, onCopy, onQr, onDuplicate, onEdit, onDelete, onNotify }) {
|
function JmsLineCard({ line, idx, ip, dragIdx, onDragStart, onDropCard, onDragEnd, onRefreshIp, onCopy, onQr, onDuplicate, onEdit, onDelete, onNotify }) {
|
||||||
const meta = JMS_PROTO_META[line.protocol] || { label: line.protocol };
|
const meta = JMS_PROTO_META[line.protocol] || { label: line.protocol };
|
||||||
const ipDisplay = ip === 'resolving' ? '解析中…' : (ip || '解析中…');
|
const ipDisplay = ip === 'resolving' ? '解析中…' : (ip || '解析中…');
|
||||||
const hasPassword = line.protocol === 'ss' && !!line.password;
|
const hasPassword = line.protocol === 'ss' && !!line.password;
|
||||||
|
const hasMethod = line.protocol === 'ss' && !!line.method;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="jms-card">
|
<div
|
||||||
|
className="jms-card"
|
||||||
|
style={{ opacity: dragIdx === idx ? 0.5 : 1 }}
|
||||||
|
draggable
|
||||||
|
onDragStart={() => onDragStart(idx)}
|
||||||
|
onDragOver={(e) => e.preventDefault()}
|
||||||
|
onDrop={() => onDropCard(idx)}
|
||||||
|
onDragEnd={onDragEnd}
|
||||||
|
>
|
||||||
<div className="jms-card-top">
|
<div className="jms-card-top">
|
||||||
<div className="jms-card-title">
|
<div className="jms-card-title">
|
||||||
|
<GripVertical size={14} className="drag-handle" />
|
||||||
<span className="jms-card-name">{line.name || line.addr}</span>
|
<span className="jms-card-name">{line.name || line.addr}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className={`jms-proto-chip jms-proto-${line.protocol}`}>{meta.label}</span>
|
<span className={`jms-proto-chip jms-proto-${line.protocol}`}>{meta.label}</span>
|
||||||
|
|
@ -4381,6 +4396,9 @@ function JmsLineCard({ line, ip, onRefreshIp, onCopy, onQr, onDuplicate, onEdit,
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="jms-terminal-row"><span className="jms-terminal-key">端口</span><span className="jms-terminal-val">{line.port}</span></div>
|
<div className="jms-terminal-row"><span className="jms-terminal-key">端口</span><span className="jms-terminal-val">{line.port}</span></div>
|
||||||
|
{hasMethod && (
|
||||||
|
<div className="jms-terminal-row"><span className="jms-terminal-key">加密方式</span><span className="jms-terminal-val">{line.method}</span></div>
|
||||||
|
)}
|
||||||
{hasPassword && (
|
{hasPassword && (
|
||||||
<div className="jms-terminal-row">
|
<div className="jms-terminal-row">
|
||||||
<span className="jms-terminal-key">密码</span>
|
<span className="jms-terminal-key">密码</span>
|
||||||
|
|
@ -4436,7 +4454,7 @@ function JmsLineFormFields({ protocol, draft, setDraft }) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function JmsPage({ lines, onSave, onDelete, onNotify }) {
|
function JmsPage({ lines, onSave, onDelete, onReorder, onNotify }) {
|
||||||
const [ipMap, setIpMap] = useState({});
|
const [ipMap, setIpMap] = useState({});
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [editingId, setEditingId] = useState(null);
|
const [editingId, setEditingId] = useState(null);
|
||||||
|
|
@ -4444,6 +4462,13 @@ function JmsPage({ lines, onSave, onDelete, onNotify }) {
|
||||||
const [draft, setDraft] = useState({});
|
const [draft, setDraft] = useState({});
|
||||||
const [qrLine, setQrLine] = useState(null);
|
const [qrLine, setQrLine] = useState(null);
|
||||||
const [qrDataUrl, setQrDataUrl] = useState('');
|
const [qrDataUrl, setQrDataUrl] = useState('');
|
||||||
|
const [dragIdx, setDragIdx] = useState(null);
|
||||||
|
|
||||||
|
function handleJmsDrop(dropIdx) {
|
||||||
|
if (dragIdx === null || dragIdx === dropIdx) { setDragIdx(null); return; }
|
||||||
|
onReorder(dragIdx, dropIdx);
|
||||||
|
setDragIdx(null);
|
||||||
|
}
|
||||||
|
|
||||||
const total = lines.length;
|
const total = lines.length;
|
||||||
const ssCount = lines.filter(l => l.protocol === 'ss').length;
|
const ssCount = lines.filter(l => l.protocol === 'ss').length;
|
||||||
|
|
@ -4537,10 +4562,15 @@ function JmsPage({ lines, onSave, onDelete, onNotify }) {
|
||||||
|
|
||||||
<div className="jms-grid">
|
<div className="jms-grid">
|
||||||
{lines.length === 0 && <div className="empty-state" style={{ gridColumn: '1/-1' }}><Wifi size={28} />还没有线路,点右上角"新增线路"添加</div>}
|
{lines.length === 0 && <div className="empty-state" style={{ gridColumn: '1/-1' }}><Wifi size={28} />还没有线路,点右上角"新增线路"添加</div>}
|
||||||
{lines.map(line => (
|
{lines.map((line, idx) => (
|
||||||
<JmsLineCard
|
<JmsLineCard
|
||||||
key={line.id}
|
key={line.id}
|
||||||
line={line}
|
line={line}
|
||||||
|
idx={idx}
|
||||||
|
dragIdx={dragIdx}
|
||||||
|
onDragStart={setDragIdx}
|
||||||
|
onDropCard={handleJmsDrop}
|
||||||
|
onDragEnd={() => setDragIdx(null)}
|
||||||
ip={ipMap[line.id]}
|
ip={ipMap[line.id]}
|
||||||
onRefreshIp={refreshIp}
|
onRefreshIp={refreshIp}
|
||||||
onCopy={copyLink}
|
onCopy={copyLink}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue