add button to compose a message to an arbitrary lxmf address

This commit is contained in:
liamcottle 2024-05-28 21:14:41 +12:00
commit fd89b50da5
5 changed files with 95 additions and 10 deletions

View file

@ -1,5 +1,7 @@
const { app, BrowserWindow } = require('electron');
const { app, BrowserWindow, ipcMain } = require('electron');
const electronPrompt = require('electron-prompt');
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('node:path');
// remember main window
@ -8,6 +10,19 @@ var mainWindow = null;
// remember child process for exe so we can kill it when app exits
var exeChildProcess = null;
// add support for showing a prompt window via ipc
ipcMain.handle('prompt', async(event, message) => {
return await electronPrompt({
title: message,
label: '',
value: '',
type: 'input',
inputAttrs: {
type: 'text',
},
});
});
function log(message) {
// make sure main window exists
@ -44,7 +59,12 @@ app.whenReady().then(async () => {
await mainWindow.loadFile(path.join(__dirname, 'loading.html'));
// find path to python/cxfreeze reticulum webchat executable
const exe = path.join(__dirname, 'build/exe/ReticulumWebChat');
var exe = path.join(__dirname, 'build/exe/ReticulumWebChat');
// if dist exe doesn't exist, check local build
if(!fs.existsSync(exe)){
exe = path.join(__dirname, '..', 'build/exe/ReticulumWebChat');
}
try {

View file

@ -1,4 +1,11 @@
const { ipcRenderer } = require('electron');
const { ipcRenderer, contextBridge } = require('electron');
// forward logs received from exe to web console
ipcRenderer.on('log', (event, message) => console.log(message));
// add support for using "prompt" in electron browser window
contextBridge.exposeInMainWorld('electron', {
prompt: async function(message) {
return await ipcRenderer.invoke('prompt', message);
},
});

8
package-lock.json generated
View file

@ -8,6 +8,9 @@
"name": "reticulum-webchat",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"electron-prompt": "^1.7.0"
},
"devDependencies": {
"electron": "^30.0.8",
"electron-builder": "^24.6.3"
@ -1584,6 +1587,11 @@
"node": ">= 10.0.0"
}
},
"node_modules/electron-prompt": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/electron-prompt/-/electron-prompt-1.7.0.tgz",
"integrity": "sha512-IfqJYEgcRO6NuyPROo8AtdkAiZ6N9I1lQEf4dJAkPuhV5YgOHdmLqZJf6OXumZJfzrjpzCM5jHeYOrhGdgbnEA=="
},
"node_modules/electron-publish": {
"version": "24.5.0",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.5.0.tgz",

View file

@ -60,5 +60,8 @@
"oneClick": false,
"allowToChangeInstallationDirectory": true
}
},
"dependencies": {
"electron-prompt": "^1.7.0"
}
}

View file

@ -45,16 +45,26 @@
</div>
</div>
</div>
<a @click="sendAnnounce" href="javascript:void(0)" class="rounded-full">
<div class="flex text-gray-700 bg-gray-100 hover:bg-gray-200 px-2 py-1 rounded-full">
<div>
<button @click="startNewLXMFConversation" type="button" class="rounded-full">
<span class="flex text-gray-700 bg-gray-100 hover:bg-gray-200 px-2 py-1 rounded-full">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75" />
</svg>
</span>
<span class="my-auto mx-1 text-sm">Compose</span>
</span>
</button>
<button @click="sendAnnounce" type="button" class="rounded-full">
<span class="flex text-gray-700 bg-gray-100 hover:bg-gray-200 px-2 py-1 rounded-full">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.288 15.038a5.25 5.25 0 0 1 7.424 0M5.106 11.856c3.807-3.808 9.98-3.808 13.788 0M1.924 8.674c5.565-5.565 14.587-5.565 20.152 0M12.53 18.22l-.53.53-.53-.53a.75.75 0 0 1 1.06 0Z" />
</svg>
</div>
<div class="my-auto mx-1 text-sm">Announce</div>
</div>
</a>
</span>
<span class="my-auto mx-1 text-sm">Announce</span>
</span>
</button>
</div>
</div>
</div>
@ -967,6 +977,34 @@
"display_name": this.displayName,
});
},
async startNewLXMFConversation() {
// ask for destination address
const destinationHash = await this.prompt("Enter LXMF Address");
if(!destinationHash){
return;
}
// attempt to find existing peer so we can show their name
const existingPeer = this.peers[destinationHash];
if(existingPeer){
this.onPeerClick(existingPeer);
return;
}
// simple attempt to prevent garbage input
if(destinationHash.length !== 32){
alert("Invalid Address");
return;
}
// we didn't find an existing peer, so just use an unknown name
this.onPeerClick({
name: "Unknown Peer",
destination_hash: destinationHash,
});
},
downloadNomadNetFile(destinationHash, filePath, onSuccessCallback, onFailureCallback, onProgressCallback) {
// do nothing if not connected to websocket
@ -1659,6 +1697,15 @@
}
},
async prompt(message) {
if(window.electron){
// running inside electron, use ipc prompt
return await window.electron.prompt(message);
} else {
// running inside normal browser, use browser prompt
return window.prompt(message);
}
},
},
computed: {
isMobile() {