fixed auto download
This commit is contained in:
parent
867b03aa1e
commit
fbdd4274ac
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -125,7 +125,30 @@ const ChatScreen: React.FC = () => {
|
||||||
isInitialLoad.current = false;
|
isInitialLoad.current = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loadMessages();
|
loadMessages().then(async () => {
|
||||||
|
// Auto-Re-Download: fehlende Anhänge vom Server nachladen (wenn aktiviert)
|
||||||
|
const autoDownload = await AsyncStorage.getItem('aria_auto_download');
|
||||||
|
if (autoDownload === 'false') return;
|
||||||
|
setTimeout(() => {
|
||||||
|
setMessages(prev => {
|
||||||
|
const missing: {id: string, serverPath: string}[] = [];
|
||||||
|
for (const msg of prev) {
|
||||||
|
for (const att of msg.attachments || []) {
|
||||||
|
if (att.serverPath && !att.uri) {
|
||||||
|
missing.push({ id: msg.id, serverPath: att.serverPath });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (missing.length > 0) {
|
||||||
|
console.log(`[Chat] ${missing.length} fehlende Anhaenge — lade nach...`);
|
||||||
|
for (const m of missing) {
|
||||||
|
rvs.send('file_request' as any, { serverPath: m.serverPath, requestId: m.id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
});
|
||||||
|
}, 2000); // Warten bis RVS verbunden ist
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// RVS-Nachrichten abonnieren
|
// RVS-Nachrichten abonnieren
|
||||||
|
|
@ -165,20 +188,23 @@ const ChatScreen: React.FC = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STT-Ergebnis: Transkribierten Text unter den Placeholder schreiben
|
|
||||||
if (message.type === 'stt_result') {
|
|
||||||
const sttText = (message.payload.text as string) || '';
|
|
||||||
setMessages(prev => prev.map(m =>
|
|
||||||
m.sender === 'user' && m.text.includes('Spracheingabe wird verarbeitet')
|
|
||||||
? { ...m, text: sttText ? `\uD83C\uDFA4 ${sttText}` : '\uD83C\uDFA4 (nicht erkannt)' }
|
|
||||||
: m
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.type === 'chat') {
|
if (message.type === 'chat') {
|
||||||
// Nur Nachrichten von ARIA anzeigen — eigene Nachrichten werden lokal hinzugefuegt
|
|
||||||
const sender = (message.payload.sender as string) || '';
|
const sender = (message.payload.sender as string) || '';
|
||||||
|
|
||||||
|
// STT-Ergebnis: Transkribierten Text in die Sprach-Bubble schreiben
|
||||||
|
if (sender === 'stt') {
|
||||||
|
const sttText = (message.payload.text as string) || '';
|
||||||
|
if (sttText) {
|
||||||
|
setMessages(prev => prev.map(m =>
|
||||||
|
m.sender === 'user' && m.text.includes('Spracheingabe wird verarbeitet')
|
||||||
|
? { ...m, text: `\uD83C\uDFA4 ${sttText}` }
|
||||||
|
: m
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eigene Nachrichten ignorieren (werden lokal hinzugefuegt)
|
||||||
if (sender === 'user' || sender === 'diagnostic') return;
|
if (sender === 'user' || sender === 'diagnostic') return;
|
||||||
|
|
||||||
const text = (message.payload.text as string) || '';
|
const text = (message.payload.text as string) || '';
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ const SettingsScreen: React.FC = () => {
|
||||||
const [events, setEvents] = useState<EventEntry[]>([]);
|
const [events, setEvents] = useState<EventEntry[]>([]);
|
||||||
const [connLog, setConnLog] = useState<ConnectionLogEntry[]>(rvs.getConnectionLog());
|
const [connLog, setConnLog] = useState<ConnectionLogEntry[]>(rvs.getConnectionLog());
|
||||||
const [storagePath, setStoragePath] = useState(DEFAULT_STORAGE_PATH);
|
const [storagePath, setStoragePath] = useState(DEFAULT_STORAGE_PATH);
|
||||||
|
const [autoDownload, setAutoDownload] = useState(true);
|
||||||
const [storageSize, setStorageSize] = useState('...');
|
const [storageSize, setStorageSize] = useState('...');
|
||||||
const [editingPath, setEditingPath] = useState(false);
|
const [editingPath, setEditingPath] = useState(false);
|
||||||
const [tempPath, setTempPath] = useState('');
|
const [tempPath, setTempPath] = useState('');
|
||||||
|
|
@ -83,10 +84,13 @@ const SettingsScreen: React.FC = () => {
|
||||||
setManualPort(String(config.port));
|
setManualPort(String(config.port));
|
||||||
setManualToken(config.token);
|
setManualToken(config.token);
|
||||||
}
|
}
|
||||||
// Speicherpfad laden
|
// Speicherpfad + Auto-Download laden
|
||||||
AsyncStorage.getItem(STORAGE_PATH_KEY).then(saved => {
|
AsyncStorage.getItem(STORAGE_PATH_KEY).then(saved => {
|
||||||
if (saved) setStoragePath(saved);
|
if (saved) setStoragePath(saved);
|
||||||
});
|
});
|
||||||
|
AsyncStorage.getItem('aria_auto_download').then(saved => {
|
||||||
|
if (saved !== null) setAutoDownload(saved === 'true');
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Speichergroesse berechnen
|
// Speichergroesse berechnen
|
||||||
|
|
@ -441,10 +445,29 @@ const SettingsScreen: React.FC = () => {
|
||||||
{/* === Speicher === */}
|
{/* === Speicher === */}
|
||||||
<Text style={styles.sectionTitle}>Anhang-Speicher</Text>
|
<Text style={styles.sectionTitle}>Anhang-Speicher</Text>
|
||||||
<View style={styles.card}>
|
<View style={styles.card}>
|
||||||
|
<View style={styles.toggleRow}>
|
||||||
|
<View style={styles.toggleInfo}>
|
||||||
|
<Text style={styles.toggleLabel}>Auto-Download</Text>
|
||||||
|
<Text style={styles.toggleHint}>
|
||||||
|
Fehlende Anhaenge beim App-Start automatisch vom Server laden
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Switch
|
||||||
|
value={autoDownload}
|
||||||
|
onValueChange={(val) => {
|
||||||
|
setAutoDownload(val);
|
||||||
|
AsyncStorage.setItem('aria_auto_download', String(val));
|
||||||
|
}}
|
||||||
|
trackColor={{ false: '#2A2A3E', true: '#0096FF' }}
|
||||||
|
thumbColor={autoDownload ? '#FFFFFF' : '#666680'}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={{height: 16}} />
|
||||||
<Text style={styles.toggleLabel}>Lokaler Speicherort</Text>
|
<Text style={styles.toggleLabel}>Lokaler Speicherort</Text>
|
||||||
<Text style={styles.toggleHint}>
|
<Text style={styles.toggleHint}>
|
||||||
Hier werden Bilder und Dateien aus dem Chat gespeichert.
|
Hier werden Bilder und Dateien aus dem Chat gespeichert.
|
||||||
Bei geloeschtem Cache werden Anhaenge automatisch ueber RVS neu geladen.
|
{autoDownload ? ' Fehlende Dateien werden automatisch nachgeladen.' : ' Fehlende Dateien koennen per Tippen geladen werden.'}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
{editingPath ? (
|
{editingPath ? (
|
||||||
|
|
|
||||||
|
|
@ -925,7 +925,10 @@ class ARIABridge:
|
||||||
payload = message.get("payload", {})
|
payload = message.get("payload", {})
|
||||||
|
|
||||||
if msg_type == "chat":
|
if msg_type == "chat":
|
||||||
# Text von der App → an aria-core
|
# Nur User-Nachrichten weiterleiten — ARIA/Diagnostic-Antworten ignorieren (sonst Loop!)
|
||||||
|
sender = payload.get("sender", "")
|
||||||
|
if sender in ("aria", "diagnostic", "stt"):
|
||||||
|
return
|
||||||
text = payload.get("text", "")
|
text = payload.get("text", "")
|
||||||
if text:
|
if text:
|
||||||
logger.info("[rvs] App-Chat: '%s'", text[:80])
|
logger.info("[rvs] App-Chat: '%s'", text[:80])
|
||||||
|
|
@ -1104,34 +1107,23 @@ class ARIABridge:
|
||||||
|
|
||||||
if text.strip():
|
if text.strip():
|
||||||
logger.info("[rvs] STT Ergebnis: '%s'", text[:80])
|
logger.info("[rvs] STT Ergebnis: '%s'", text[:80])
|
||||||
# STT-Ergebnis zurueck an die App senden (zur Anzeige, nicht nochmal verarbeiten)
|
# ERST an aria-core senden (wichtigster Schritt)
|
||||||
|
await self.send_to_core(text, source="app-voice")
|
||||||
|
# STT-Text an RVS senden (fuer Anzeige in App + Diagnostic)
|
||||||
|
# sender="stt" damit Bridge es ignoriert (kein Loop)
|
||||||
try:
|
try:
|
||||||
await self._send_to_rvs({
|
await self._send_to_rvs({
|
||||||
"type": "stt_result",
|
"type": "chat",
|
||||||
"payload": {
|
"payload": {
|
||||||
"text": text,
|
"text": text,
|
||||||
"sender": "user",
|
"sender": "stt",
|
||||||
},
|
},
|
||||||
"timestamp": int(asyncio.get_event_loop().time() * 1000),
|
"timestamp": int(asyncio.get_event_loop().time() * 1000),
|
||||||
})
|
})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("[rvs] STT-Ergebnis konnte nicht an App gesendet werden: %s", e)
|
logger.warning("[rvs] STT-Text konnte nicht an RVS gesendet werden: %s", e)
|
||||||
# Text trotzdem an aria-core senden
|
|
||||||
await self.send_to_core(text, source="app-voice")
|
|
||||||
else:
|
else:
|
||||||
logger.info("[rvs] Keine Sprache erkannt — ignoriert")
|
logger.info("[rvs] Keine Sprache erkannt — ignoriert")
|
||||||
try:
|
|
||||||
await self._send_to_rvs({
|
|
||||||
"type": "stt_result",
|
|
||||||
"payload": {
|
|
||||||
"text": "",
|
|
||||||
"error": "Keine Sprache erkannt",
|
|
||||||
"sender": "user",
|
|
||||||
},
|
|
||||||
"timestamp": int(asyncio.get_event_loop().time() * 1000),
|
|
||||||
})
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning("[rvs] STT-Fehler konnte nicht an App gesendet werden: %s", e)
|
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception("[rvs] Audio-Verarbeitung fehlgeschlagen")
|
logger.exception("[rvs] Audio-Verarbeitung fehlgeschlagen")
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,10 @@
|
||||||
<!-- Chat Test -->
|
<!-- Chat Test -->
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card full">
|
<div class="card full">
|
||||||
<h2>Chat Test</h2>
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;">
|
||||||
|
<h2 style="margin:0;">Chat Test</h2>
|
||||||
|
<button class="btn secondary" onclick="toggleChatFullscreen()" id="btn-chat-fs" style="padding:4px 10px;font-size:11px;">Vollbild</button>
|
||||||
|
</div>
|
||||||
<div class="chat-box" id="chat-box"></div>
|
<div class="chat-box" id="chat-box"></div>
|
||||||
<div class="input-row">
|
<div class="input-row">
|
||||||
<input type="text" id="chat-input" placeholder="Nachricht an ARIA...">
|
<input type="text" id="chat-input" placeholder="Nachricht an ARIA...">
|
||||||
|
|
@ -206,6 +209,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Chat Vollbild Modal -->
|
||||||
|
<div id="chat-fullscreen" style="display:none;position:fixed;top:0;left:0;width:100vw;height:100vh;background:#0D0D1A;z-index:1000;padding:16px;flex-direction:column;">
|
||||||
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;">
|
||||||
|
<h2 style="margin:0;color:#0096FF;">ARIA Chat</h2>
|
||||||
|
<button class="btn secondary" onclick="toggleChatFullscreen()" style="padding:6px 14px;">Schliessen</button>
|
||||||
|
</div>
|
||||||
|
<div id="chat-box-fs" class="chat-box" style="flex:1;max-height:none;min-height:0;overflow-y:auto;"></div>
|
||||||
|
<div class="input-row" style="margin-top:8px;">
|
||||||
|
<input type="text" id="chat-input-fs" placeholder="Nachricht an ARIA..." onkeydown="if(event.key==='Enter'){testGatewayFS();event.preventDefault();}">
|
||||||
|
<button class="btn" onclick="testGatewayFS()">Gateway senden</button>
|
||||||
|
<button class="btn" onclick="testRVSFS()">Via RVS senden</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Session + Brain Viewer -->
|
<!-- Session + Brain Viewer -->
|
||||||
<div class="grid" style="grid-template-columns: 1fr 1fr;">
|
<div class="grid" style="grid-template-columns: 1fr 1fr;">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
@ -503,7 +520,8 @@
|
||||||
const p = msg.msg.payload || {};
|
const p = msg.msg.payload || {};
|
||||||
const sender = p.sender || '?';
|
const sender = p.sender || '?';
|
||||||
const chatType = (sender === 'aria') ? 'received' : 'sent';
|
const chatType = (sender === 'aria') ? 'received' : 'sent';
|
||||||
addChat(chatType, p.text || '?', `via RVS (${sender})`);
|
const label = sender === 'stt' ? '\uD83C\uDFA4 Spracheingabe' : `via RVS (${sender})`;
|
||||||
|
addChat(chatType, p.text || '?', label);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.type === 'proxy_result') {
|
if (msg.type === 'proxy_result') {
|
||||||
|
|
@ -856,19 +874,60 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function addChat(type, text, meta) {
|
function addChat(type, text, meta) {
|
||||||
const el = document.createElement('div');
|
|
||||||
el.className = `chat-msg ${type}`;
|
|
||||||
const escaped = escapeHtml(text);
|
const escaped = escapeHtml(text);
|
||||||
let linked = linkifyText(escaped);
|
let linked = linkifyText(escaped);
|
||||||
// /shared/uploads/ Pfade als Inline-Bilder anzeigen
|
// /shared/uploads/ Pfade als Inline-Bilder anzeigen
|
||||||
linked = linked.replace(/\/shared\/uploads\/[^\s<"]+\.(jpg|jpeg|png|gif)/gi, (match) => {
|
linked = linked.replace(/\/shared\/uploads\/[^\s<"]+\.(jpg|jpeg|png|gif)/gi, (match) => {
|
||||||
return `<a href="${match}" target="_blank">${match}</a><img src="${match}" class="chat-media" onclick="openLightbox('image','${match}')" onerror="this.style.display='none'">`;
|
return `<a href="${match}" target="_blank">${match}</a><img src="${match}" class="chat-media" onclick="openLightbox('image','${match}')" onerror="this.style.display='none'">`;
|
||||||
});
|
});
|
||||||
el.innerHTML = `${linked}<div class="meta">${escapeHtml(meta)} — ${new Date().toLocaleTimeString('de-DE')}</div>`;
|
const html = `${linked}<div class="meta">${escapeHtml(meta)} — ${new Date().toLocaleTimeString('de-DE')}</div>`;
|
||||||
chatBox.appendChild(el);
|
// In beide Chat-Boxen schreiben (normal + Vollbild)
|
||||||
chatBox.scrollTop = chatBox.scrollHeight;
|
for (const box of [chatBox, document.getElementById('chat-box-fs')]) {
|
||||||
|
if (!box) continue;
|
||||||
|
const el = document.createElement('div');
|
||||||
|
el.className = `chat-msg ${type}`;
|
||||||
|
el.innerHTML = html;
|
||||||
|
box.appendChild(el);
|
||||||
|
box.scrollTop = box.scrollHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let chatFullscreen = false;
|
||||||
|
function toggleChatFullscreen() {
|
||||||
|
const modal = document.getElementById('chat-fullscreen');
|
||||||
|
chatFullscreen = !chatFullscreen;
|
||||||
|
if (chatFullscreen) {
|
||||||
|
modal.style.display = 'flex';
|
||||||
|
// Chat-Inhalt synchronisieren
|
||||||
|
const fsBox = document.getElementById('chat-box-fs');
|
||||||
|
fsBox.innerHTML = chatBox.innerHTML;
|
||||||
|
fsBox.scrollTop = fsBox.scrollHeight;
|
||||||
|
document.getElementById('chat-input-fs').focus();
|
||||||
|
} else {
|
||||||
|
modal.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function testGatewayFS() {
|
||||||
|
const input = document.getElementById('chat-input-fs');
|
||||||
|
const text = input.value.trim();
|
||||||
|
if (!text) return;
|
||||||
|
addChat('sent', text, 'Gateway direkt');
|
||||||
|
send({ action: 'test_gateway', text });
|
||||||
|
input.value = '';
|
||||||
|
}
|
||||||
|
function testRVSFS() {
|
||||||
|
const input = document.getElementById('chat-input-fs');
|
||||||
|
const text = input.value.trim();
|
||||||
|
if (!text) return;
|
||||||
|
addChat('sent', text, 'via RVS');
|
||||||
|
send({ action: 'test_rvs', text });
|
||||||
|
input.value = '';
|
||||||
|
}
|
||||||
|
// Escape schliesst Vollbild-Chat
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Escape' && chatFullscreen) toggleChatFullscreen();
|
||||||
|
});
|
||||||
|
|
||||||
function openLightbox(mediaType, url) {
|
function openLightbox(mediaType, url) {
|
||||||
const lb = document.getElementById('lightbox');
|
const lb = document.getElementById('lightbox');
|
||||||
if (mediaType === 'video') {
|
if (mediaType === 'video') {
|
||||||
|
|
|
||||||
|
|
@ -462,11 +462,6 @@ function connectRVS(forcePlain) {
|
||||||
pipelineEnd(true, `Antwort via RVS von ${sender}: "${(msg.payload.text || "").slice(0, 120)}"`);
|
pipelineEnd(true, `Antwort via RVS von ${sender}: "${(msg.payload.text || "").slice(0, 120)}"`);
|
||||||
}
|
}
|
||||||
broadcast({ type: "rvs_chat", msg });
|
broadcast({ type: "rvs_chat", msg });
|
||||||
} else if (msg.type === "stt_result" && msg.payload) {
|
|
||||||
const text = msg.payload.text || "(nicht erkannt)";
|
|
||||||
log("info", "rvs", `STT: "${text.slice(0, 100)}"`);
|
|
||||||
// Im Chat als User-Nachricht anzeigen (zur Info, wurde schon an ARIA gesendet)
|
|
||||||
broadcast({ type: "rvs_chat", msg: { type: "chat", payload: { text: `\uD83C\uDFA4 ${text}`, sender: "user" } } });
|
|
||||||
} else if (msg.type === "heartbeat") {
|
} else if (msg.type === "heartbeat") {
|
||||||
// ignorieren
|
// ignorieren
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
36
release.sh
36
release.sh
|
|
@ -51,8 +51,30 @@ fi
|
||||||
echo -e " ${GREEN}✓${NC} Login erfolgreich"
|
echo -e " ${GREEN}✓${NC} Login erfolgreich"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
# ── Versionsnummern aktualisieren ─────────────
|
||||||
|
echo -e "${GREEN}[1/5] Versionsnummern auf $VERSION setzen...${NC}"
|
||||||
|
|
||||||
|
# package.json
|
||||||
|
sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$VERSION\"/" android/package.json
|
||||||
|
echo -e " ${GREEN}✓${NC} package.json → $VERSION"
|
||||||
|
|
||||||
|
# build.gradle: versionName + versionCode (aus Major.Minor.Patch berechnen)
|
||||||
|
MAJOR=$(echo "$VERSION" | cut -d. -f1)
|
||||||
|
MINOR=$(echo "$VERSION" | cut -d. -f2)
|
||||||
|
PATCH=$(echo "$VERSION" | cut -d. -f3)
|
||||||
|
VERSION_CODE=$((MAJOR * 10000 + MINOR * 100 + PATCH))
|
||||||
|
sed -i "s/versionName \"[^\"]*\"/versionName \"$VERSION\"/" android/android/app/build.gradle
|
||||||
|
sed -i "s/versionCode [0-9]*/versionCode $VERSION_CODE/" android/android/app/build.gradle
|
||||||
|
echo -e " ${GREEN}✓${NC} build.gradle → versionName $VERSION, versionCode $VERSION_CODE"
|
||||||
|
|
||||||
|
# SettingsScreen: Anzeige-Version
|
||||||
|
sed -i "s/Version [0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]* [^<]*/Version $VERSION /" android/src/screens/SettingsScreen.tsx
|
||||||
|
echo -e " ${GREEN}✓${NC} SettingsScreen → Version $VERSION"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
# ── APK bauen ─────────────────────────────────
|
# ── APK bauen ─────────────────────────────────
|
||||||
echo -e "${GREEN}[1/4] APK bauen...${NC}"
|
echo -e "${GREEN}[2/5] APK bauen...${NC}"
|
||||||
cd android
|
cd android
|
||||||
./build.sh release
|
./build.sh release
|
||||||
cd ..
|
cd ..
|
||||||
|
|
@ -70,7 +92,11 @@ echo -e " ${GREEN}✓${NC} APK gebaut ($APK_SIZE)"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# ── Git Tag ───────────────────────────────────
|
# ── Git Tag ───────────────────────────────────
|
||||||
echo -e "${GREEN}[2/4] Git Tag $TAG...${NC}"
|
echo -e "${GREEN}[3/5] Git Tag $TAG...${NC}"
|
||||||
|
|
||||||
|
# Versions-Aenderungen committen
|
||||||
|
git add android/package.json android/android/app/build.gradle android/src/screens/SettingsScreen.tsx
|
||||||
|
git commit -m "release: bump version to $VERSION" 2>/dev/null || echo -e " ${YELLOW}Keine Aenderungen zum Committen${NC}"
|
||||||
|
|
||||||
if git rev-parse "$TAG" &>/dev/null; then
|
if git rev-parse "$TAG" &>/dev/null; then
|
||||||
echo -e " ${YELLOW}Tag $TAG existiert bereits — überspringe${NC}"
|
echo -e " ${YELLOW}Tag $TAG existiert bereits — überspringe${NC}"
|
||||||
|
|
@ -79,7 +105,7 @@ else
|
||||||
echo -e " ${GREEN}✓${NC} Tag $TAG erstellt"
|
echo -e " ${GREEN}✓${NC} Tag $TAG erstellt"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git push origin "$TAG"
|
git push origin main "$TAG"
|
||||||
echo -e " ${GREEN}✓${NC} Tag gepusht"
|
echo -e " ${GREEN}✓${NC} Tag gepusht"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|
@ -102,7 +128,7 @@ fi
|
||||||
RELEASE_BODY_ESCAPED=$(printf '%s' "$RELEASE_BODY" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null || printf '"%s"' "$RELEASE_BODY" | sed 's/"/\\"/g')
|
RELEASE_BODY_ESCAPED=$(printf '%s' "$RELEASE_BODY" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null || printf '"%s"' "$RELEASE_BODY" | sed 's/"/\\"/g')
|
||||||
|
|
||||||
# ── Gitea Release erstellen ───────────────────
|
# ── Gitea Release erstellen ───────────────────
|
||||||
echo -e "${GREEN}[3/4] Gitea Release erstellen...${NC}"
|
echo -e "${GREEN}[4/5] Gitea Release erstellen...${NC}"
|
||||||
|
|
||||||
RELEASE_RESPONSE=$(curl -s -X POST \
|
RELEASE_RESPONSE=$(curl -s -X POST \
|
||||||
"$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
|
"$GITEA_URL/api/v1/repos/$GITEA_REPO/releases" \
|
||||||
|
|
@ -127,7 +153,7 @@ echo -e " ${GREEN}✓${NC} Release #$RELEASE_ID erstellt"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# ── APK hochladen ─────────────────────────────
|
# ── APK hochladen ─────────────────────────────
|
||||||
echo -e "${GREEN}[4/4] APK hochladen...${NC}"
|
echo -e "${GREEN}[5/5] APK hochladen...${NC}"
|
||||||
|
|
||||||
UPLOAD_RESPONSE=$(curl -s -X POST \
|
UPLOAD_RESPONSE=$(curl -s -X POST \
|
||||||
"$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$RELEASE_ID/assets?name=$APK_NAME" \
|
"$GITEA_URL/api/v1/repos/$GITEA_REPO/releases/$RELEASE_ID/assets?name=$APK_NAME" \
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ const MAX_SESSIONS = parseInt(process.env.MAX_SESSIONS || "10", 10);
|
||||||
// Erlaubte Nachrichtentypen — alles andere wird verworfen
|
// Erlaubte Nachrichtentypen — alles andere wird verworfen
|
||||||
const ALLOWED_TYPES = new Set([
|
const ALLOWED_TYPES = new Set([
|
||||||
"chat", "audio", "file", "location", "mode", "log", "event", "heartbeat",
|
"chat", "audio", "file", "location", "mode", "log", "event", "heartbeat",
|
||||||
|
"file_request", "file_response", "file_saved", "stt_result",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Token-Raum: token -> { clients: Set<ws> }
|
// Token-Raum: token -> { clients: Set<ws> }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue