Emit an event from electron main js into a vue component - javascript

I am currently building an electron app in electron version 5.0.0
I am using electron's power monitor functionality but this can only beaccess from the main electron js file but I need to let a vue component know. I tried using event bus
powerMonitor.on('lock-screen', () => {
console.log("locked")
EventBus.$emit('logout');
})
})
but it looks like evenbus only works within vue components. Anyone got any ideas on how i can just send an even from the electron main js file into a vue component

Okay I finally figured out how its done.
You have to use the ipcRenderer listener wil using webContents to send the event. It should look something like this.
//main.js
powerMonitor.on('unlock-screen', () => {
console.log("unlocked")
win.webContents.send('computer-unlock')
})
//Vue Component
require('electron').ipcRenderer.on('computer-unlock', () => {
console.log("logging in");
_this.computerLocked = false;
})

Related

Single-spa - Registering application

I'm fairly new with Javascript/Typescript and was developing a Single-Spa with Single SPA Router
Searching for info about registering applications I found different ways of doing that, one way is using the LayoutEngine that "automatically" register my applications this way:
const routes = constructRoutes(microfrontendLayout);
const applications = constructApplications({routes, loadApp({name}) {
return System.import(name);
}});
const layoutEngine = constructLayoutEngine({ routes, applications });
applications.forEach(registerApplication);
layoutEngine.activate();
From what I understood is, in microfrontend-layout.html we have to put something like an HTML tag in this way
<application name="#prueba-organizacion/micro-prueba-app1"></application>
with that and having an importmap in index.ejs the app was loading fine.
But then I found another way, the manually way:
A)
import { registerApplication, start } from "single-spa";
registerApplication({
name: '#prueba-organizacion/micro-prueba-app1',
app: () => System.import('#prueba-organizacion/micro-prueba-app1'),
activeWhen: (location) => location.pathname.startsWith('/app1')
});
start();
But that says: Promise\<System.Module\> is not assignable to type Application\<{}\>
Then I found ANOTHER WAY of doing the same as above:
B)
System.import('single-spa').then(({ registerApplication, start }) => {
registerApplication({
name: '#prueba-organizacion/micro-prueba-app1',
app: () => System.import('#prueba-organizacion/micro-prueba-app1'),
activeWhen: (location) => location.pathname.startsWith('/app1'),
});
start();
});
The thing here is, what's the difference between point A) and point B)?
I mean, they're importing the modules and registerApplication, start functions but one of them is throwing me an error.
I'm using "single-spa": "^5.9.3" from package.json
Thanks!
I've tried both ways, one of them is not working, the other one is working (B) as expected

handling the onclose event of electron app inside the webview app

I have an electron app in which the Ui is built using react js. inside the react js ui other web app is loaded using the webview.
my problem is i need to save the data of the webview app when the electron app is closed.
I want to know how to access the onClose event of the electron app inside the webview app.
Just came upon something similar. You could do something like this.
In the Main process:
const { ipcMain, app, webContents } = require('electron')
app.on('will-quit', event => {
event.preventDefault()
let readyCount = 0
ipcMain.on('ready-to-quit', () => {
readyCount++
if (readyCount === allWebContents.length) {
app.exit()
}
})
const allWebContents = webContents.getAllWebContents()
allWebContents.forEach(contents => contents.send('app-will-quit'))
})
In the Renderer process:
const { ipcRenderer } = require('electron')
ipcRenderer.once('app-will-quit', () => {
// do stuff
ipcRenderer.send('ready-to-quit')
})

Send ipcRenderer variable to vue3 page

I have a vue3 app with electron and need to send a variable from the ipcRenderer to my Vue3 page. I cant figure out how to do it especially given vue strips away lots of js. What im trying to do is to save the path of a folder which so far works fine, then display it in the vue3 app either in a span or whatever. I successfully got the value i need to display to the ipcRenderer but cant access it using my vue app.
Vue3 page
<q-btn
id="showpath"
dark
flat
size="xl"
label="show Path"
type="submit"
#click="showpath"
/>
</div>
export default {
name: "Settings",
props: {},
methods: {
loader() {
window.postMessage({
type: "select-dirs",
});
},
showpath() {
const testa = window.postMessage({ type: "pathtf"})
console.log("Vue page says :"+ testa)
},
},
};
</script>
All I get here is "undefined
Preloader script
const { ipcRenderer } = require('electron');
const settings = require('./settings');
process.once('loaded', () => {
window.addEventListener('message', evt => {
if (evt.data.type === 'select-dirs') {
ipcRenderer.send('select-dirs')
}
}),
window.addEventListener('message', evt => {
if (evt.data.type === 'pathtf') {
const pathtf = settings.gettfpath("pathtf")
console.log(pathtf)
}
})
})
The console.log in the preload file works and displays the value, but i cant get that value to my vue3 page.
Any tip? Thank you
I would suggest that you use electron's contextBridge to expose certain methods (send/receive) to the renderer process.
I do not know what your gettfPath method does but if that variable is available to you in the preloadjs file you should be able to expose it as a variable like so:
const {contextBridge} = require("electron");
contextBridge.exposeInMainWorld("electronApi", {
pathtf: settings.gettfPath()
});
With this your path will be exposed to your renderer process as window.electronApi.pathtf
Here are two resources you may find helpful:
How to use preload.js properly in Electron
https://medium.com/swlh/how-to-safely-set-up-an-electron-app-with-vue-and-webpack-556fb491b83 (This one may not be exactly what you are looking for but it has a good explanation / example of how to use ipc with view and electron)

Vue 3 mobile event listeners and swipe

In Vue 3, I want to trigger a function when a user swipes left / right. (I made a calendar and interested in having months changed on swiping)
I found this package: https://github.com/robinrodricks/vue3-touch-events (npm install vue3-touch-events) but it's not working and I get the following errors:
and imported the relevant packages in main.js:
import Vue from "vue";
import Vue3TouchEvents from "vue3-touch-events";
and in public/index.html:
<script src="https://raw.githubusercontent.com/robinrodricks/vue3-touch-events/master/index.js"></script>
after that, in main.js
If registered as:
createApp(App)
.use(Vue3TouchEvents)
then I get the error: "Maximum recursive updates exceeded in component ..."
And the event won't be fired.
If registered as
Vue.use(Vue3TouchEvents);
then I get the error "export 'default' (imported as 'Vue') was not found in 'vue'"
And the event still won't be fired
What's wrong? How to implement it right or make a solution in another way?
(#starttouch and mobile event listeners seems to not be supported in Vue 3)
I Think You Installed It Wrong Way
npm cache clean --force
npm install vue3-touch-events
Also Remove That script src line from index.html.
I Hope This Will Help Your Query.
I solved the problem in this way, please note that only the function name needs to be passed
main.js
import Vue3TouchEvents from "vue3-touch-events";
const app = createApp(App);
app.use(Vue3TouchEvents);
Component.vue
// script setup
const doSwipeLeft = () => {
// some code
};
const doSwipeRight = () => {
// some code
};
//template
<Component
v-touch:swipe.left="doSwipeLeft"
v-touch:swipe.right="doSwipeRight"
>

Vue Composition API from outside of Vue

So, I've started using the Vue Composition API, and it's brilliant. I'm using it in a project that has Vue components, but also Vanilla JS. I'm building a notification system in Vue, as we are slowly moving everything that way.
I have the following code currently for adding a notification
export const useNotification = () => {
const notifications = ref([]);
const visibleNotifications = computed(() => {
return notifications.value.filter(notification => notification.visible === true).reverse();
});
const add = (notification: Notification) => {
notifications.value.push(notification);
};
};
I can get this adding perfectly from within Vue, but I want to also add a notification from the vanilla JS parts of the system. I've tried using useNotification().add() but I get the following error [vue-composition-api] must call Vue.use(plugin) before using any function. Basically, it wants me to use it inside Vue.
Any ideas on how I get this working?
Due to the shortcomings of using the vue-composition-api with vue2, and following the SO question here, I needed to add the following to type of my exported TS file
import Vue from 'vue';
import VueCompositionApi from '#vue/composition-api';
Vue.use(VueCompositionApi);

Categories

Resources