Fehlerbehebung Dateien und Smilies in Nachrichten

This commit is contained in:
2026-05-28 11:56:50 +02:00
parent 970872111b
commit 340e4bcc67
2 changed files with 39 additions and 28 deletions

View File

@@ -196,6 +196,23 @@ router.post('/', authenticate, (req, res) => {
});
});
router.get('/storage', authenticate, (req, res) => {
const uid = req.user.id;
const used = db.prepare('SELECT COALESCE(SUM(size),0) AS s FROM files WHERE user_id=?').get(uid).s;
const maxMb = parseInt(getSetting('file_max_size_mb') || '50');
const maxCount = parseInt(getSetting('file_max_count') || '20');
const max = maxMb * maxCount * 1024 * 1024;
let diskFree = null;
try {
const { execSync } = require('child_process');
const out = execSync(`df -k "${process.env.UPLOAD_DIR || '/data/uploads'}"`, { timeout:3000 }).toString();
const line = out.trim().split('\n').pop();
const parts = line.trim().split(/\s+/);
if (parts[3]) diskFree = parseInt(parts[3]) * 1024;
} catch {}
res.json({ used, max, diskFree });
});
router.get('/:id/download', authenticate, async (req, res) => {
const uid = req.user.id;
const file = db.prepare('SELECT * FROM files WHERE id=?').get(req.params.id);
@@ -279,22 +296,6 @@ router.delete('/:id/share/:userId', authenticate, (req, res) => {
res.json({ success: true });
});
router.get('/storage', authenticate, (req, res) => {
const uid = req.user.id;
const used = db.prepare('SELECT COALESCE(SUM(size),0) AS s FROM files WHERE user_id=?').get(uid).s;
const max = parseInt(getSetting('file_max_size_mb') || '50') *
parseInt(getSetting('file_max_count') || '20') * 1024 * 1024;
// Disk space via Node
const { execSync } = require('child_process');
let diskFree = null;
try {
const out = execSync(`df -k "${process.env.UPLOAD_DIR || '/data/uploads'}" | tail -1`).toString();
const parts = out.trim().split(/\s+/);
diskFree = parseInt(parts[3]) * 1024; // available bytes
} catch {}
res.json({ used, max, diskFree });
});
// Settings
router.get('/settings', authenticate, requireAdmin, (req, res) => {
const s = db.prepare('SELECT * FROM admin_settings').all();

View File

@@ -185,14 +185,15 @@ export default function Nachrichten({ toast, mobile }) {
setDecrypted({});
};
const send = async () => {
if (!text.trim() || !kp || !activeUser) return;
const send = async (overrideText) => {
const msg = (overrideText ?? text).trim();
if (!msg || !kp || !activeUser) return;
if (!activeUser.public_key) { toast('Empfänger hat noch keinen Schlüssel', 'error'); return; }
if (sharedKey === 'error') { toast('Schlüssel inkompatibel Empfänger muss Schlüssel neu generieren', 'error'); return; }
if (!sharedKey) { toast('Schlüssel wird vorbereitet…', 'error'); return; }
setSending(true);
try {
const { encrypted_content, iv } = await encryptMsg(sharedKey, text.trim());
const { encrypted_content, iv } = await encryptMsg(sharedKey, msg);
await api(`/tools/nachrichten/messages/${activeUser.id}`, { body: { encrypted_content, iv } });
setText('');
await loadMessages(activeUser.id);
@@ -439,18 +440,19 @@ export default function Nachrichten({ toast, mobile }) {
Senden nicht möglich
</div>
) : (
<div style={{ display:'flex', gap:8, alignItems:'flex-end', position:'relative' }} ref={pickerRef}>
{showPicker && (
<EmojiPicker
onSelect={em => { setText(t => t + em); setShowPicker(false); }}
onClose={() => setShowPicker(false)}
/>
)}
<div style={{ display:'flex', gap:8, alignItems:'flex-end', position:'relative' }}>
<div ref={pickerRef} style={{ position:'absolute', bottom:'100%', right:0 }}>
{showPicker && (
<EmojiPicker
onSelect={em => { setText(t => t + em); setShowPicker(false); }}
onClose={() => setShowPicker(false)}
/>
)}
</div>
<textarea
value={text}
onChange={e => {
const val = e.target.value;
// Kürzel nur konvertieren wenn gerade ein Leerzeichen oder Enter getippt wurde
const last = val[val.length - 1];
if (last === ' ' || last === '\n') {
setText(convertEmojis(val));
@@ -458,7 +460,15 @@ export default function Nachrichten({ toast, mobile }) {
setText(val);
}
}}
onKeyDown={e => { if (e.key==='Enter' && !e.shiftKey) { e.preventDefault(); send(); }}}
onFocus={() => setShowPicker(false)}
onKeyDown={e => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
const converted = convertEmojis(text + ' ').trimEnd();
if (converted !== text) setText(converted);
send(converted);
}
}}
placeholder="Nachricht… (Enter senden · Shift+Enter neue Zeile)"
rows={2}
style={{ ...S.inp, resize:'none', flex:1, fontSize:13, padding:'8px 10px',