Use cordova plugins inside Ionic Vue.js Components - vue.js

I see I can use any cordova plugin within ionic capacitor. But how I can use it inside vue component for example.
Just for example:
I installed plugin cordova-plugin-prevent-screenshot-coffice with npm
npm i --save cordova-plugin-prevent-screenshot-coffice
I trying to import foo from "cordova-plugin-prevent-screenshot-coffice", but it says cannot find that module.
Is there a special way to import plugins like the above example plugin (or any other plugin which is not in #ionic-native namespace)?
I need usage example for the ionic vue community bacause it's very hard to found any info how we can use it.
This not working for cordova-plugin-prevent-screenshot-coffice
import PLUGIN_X from "PLUGIN_X"
export default defineComponent({
// ...
mounted() {
PLUGIN_X.doSomething()
}
// ...
}

You don't have to import the plugin, the plugin is available on window object.
You can do something like this:
// Enable
(<any>window).plugins.preventscreenshot.enable((a) => this.successCallback(a), (b) => this.errorCallback(b));
// Disable
(<any>window).plugins.preventscreenshot.disable((a) => this.successCallback(a), (b) => this.errorCallback(b));
successCallback(result) {
console.log(result); // true - enabled, false - disabled
}
errorCallback(error) {
console.log(error);
}
or like this if using javascript instead of typescript
document.addEventListener("deviceready", onDeviceReady, false);
// Enable
function onDeviceReady() {
window.plugins.preventscreenshot.enable(successCallback, errorCallback);
}
// Disable
function onDeviceReady() {
window.plugins.preventscreenshot.disable(successCallback, errorCallback);
}
function successCallback(result) {
console.log(result); // true - enabled, false - disabled
}
function errorCallback(error) {
console.log(error);
}
document.addEventListener("onTookScreenshot",function(){
// Receive notification when screenshot is ready;
});
document.addEventListener("onGoingBackground",function(){
// Receive notification when control center or app going in background.
});

Related

VUE2 + Electron + Flask -> Python not spawning on build

I've just finished my first vue+electron+flask project and I am having quite a hard time trying to package it. Everything is workig "perfectly" when using "npm run electron:serve" but when running "npm run electron:build" I do not get any error, but Flask is not launched at all. I do not really know how to fix the problem, my guess is that when building the dist folder the path to app.py is not correct, but I tried to fix it without luck.
Here is the background.js code:
'use strict'
import { app, protocol, BrowserWindow } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const isDevelopment = process.env.NODE_ENV !== 'production'
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
async function createWindow() {
// spawn flask app (https://medium.com/red-buffer/integrating-python-flask-backend-with-electron-nodejs-frontend-8ac621d13f72)
var python = require('child_process').spawn('py', ['../server/app.py']);
python.stdout.on('data', function (data) {
console.log("data: ", data.toString('utf8'));
});
python.stderr.on('data', (data) => {
console.log(`stderr: ${data}`); // when error
});
// Create the browser window.
const win = new BrowserWindow({
width: 1500,
height: 1200,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
}
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
try {
await installExtension(VUEJS_DEVTOOLS)
} catch (e) {
console.error('Vue Devtools failed to install:', e.toString())
}
}
createWindow()
})
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', (data) => {
if (data === 'graceful-exit') {
app.quit()
}
})
} else {
process.on('SIGTERM', () => {
app.quit()
})
}
}
The relevant part of the code calling app.py is the following:
async function createWindow() {
// spawn flask app (https://medium.com/red-buffer/integrating-python-flask-backend-with-electron-nodejs-frontend-8ac621d13f72)
var python = require('child_process').spawn('py', ['../server/app.py']);
python.stdout.on('data', function (data) {
console.log("data: ", data.toString('utf8'));
});
python.stderr.on('data', (data) => {
console.log(`stderr: ${data}`); // when error
});
// Create the browser window.
const win = new BrowserWindow({
width: 1500,
height: 1200,
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
}
})
I tried to put 3 dots insted of 2 in the app.py path ['.../server/app.py] just in case when creating the dist folder I need this extra dot to find the app.py file, but this is not working either.
My folder structure is the follwing:
Vue-Electron
client
dist_electron
node_modules
public
src
assets
components
router
views
App.vue
background.js
main.js
other config files
server
data
env
app.py
requirements.txt
other python scripts imported to app.py
sqlite_portofolio.db
As this program will only be used by me in my personal pc, I did not want to bother using pyInstaller (I thought it would be easier to not package the python side, but if I am wrong please let me know). I would like to have a electron .exe file that I can just doble click to open the electron build and then spawn the Flask server.
Also, my feeling is that I am not killing the Flask server correctly when closing the app. I think Flask is still running when closing electron. What should I do to ensure Flask server is properly closed.
There is not a lot of information of those topics that I can follow. Any help will be aprreaciated.
I´m having the same problem. I followed the link to this article (https://medium.com/red-buffer/integrating-python-flask-backend-with-electron-nodejs-frontend-8ac621d13f72), and it has the answer about killing the python flask server. And if you follow everything the article says, it's supposed to run the backend when opening the electron.exe, but this is not happening here on my end.
EDIT: I found the error, you need to change the path on your spawn. I sugest you to run the electron.exe on the cmd so you can see the error on it, so you will see the path that spawn is trying to run.
it´s probably:
var python = require('child_process').spawn('py', ['../resources/app/server/app.py']);
you will need to acess the app.py through [resources/app] as spawn start at the base dir of the electron build.
PS: I used electron-packeger that´s why mine need to add resources/app, and I used pyinstaller on my backend
Hope it will help you.

How to add included Pug files to Vite module graph

I wrote a Rollup plugin to import Pug as an HTML string:
// Rollup plugin imported to Vite config
import { render } from 'pug';
export default function pug() {
return {
name: 'rollup-plugin-pug-html',
transform(src, id) {
if (id.endsWith('.pug')) {
const html = render(src, { filename: id });
const code = `export default ${JSON.stringify(html)};`;
return { code };
}
},
};
}
I'm using it in Vite to create templates for Vue components, as in this reduced example:
// ProofOfConceptSFC.vue
<script>
import { compile } from 'vue/dist/vue.esm-bundler.js';
import template from './template.pug';
export default {
render: compile(template)
};
</script>
The HMR is working great when I edit template.pug. The new template appears and the latest reactive values persist.
My problem is that template.pug may depend on other Pug files with include:
//- template.pug
include ./header.pug
p Hello {{ name }}
include ./footer.pug
The Vite server doesn't know about those files, and nothing happens if I touch them. Ideally I could invalidate template.pug when any Pug file is changed.
I'm guessing I want my plugin to update the ViteDevServer's server.moduleGraph. Is there a supported way to do that?
Huge thanks to the friendly Vite chat on Discord for setting me in the right direction.
The two keys I was missing:
Use Pug compile to create a render method that has render.dependencies, as done by Parcel
Use virtual import statements to attach the dependencies to the transform hook result, as done by vite-plugin-svelte.
Here is the working plugin:
import { compile } from 'pug';
export default function pluginPug() {
return {
name: 'vite-plugin-pug',
transform(src, id) {
if (id.endsWith('.pug')) {
const render = compile(src, { filename: id });
const html = render();
let code = '';
for (let dep of render.dependencies) {
code += `import ${JSON.stringify(dep)};\n`;
}
code += `export default ${JSON.stringify(html)};`;
return { code };
}
},
};
}

Ionic program dont work in backgraund. How to fix that?

I need the app to run fully in the background and when I use other apps on my phone. The program transmits video from the camera. When I turn off the screen, I managed to get the program to transmit video, but when I turn on other programs on the phone, the program stops transmitting. Part of the code as I managed to omit in off mode.
i use library #ionic-native/background-mode
componentDidMount() {
document.addEventListener('deviceready', () => {
BackgroundMode.setEnabled(true);
BackgroundMode.disableBatteryOptimizations();
BatteryStatus.onChange().subscribe(status => {
this.batteryStatus = status;
this.signalCurrentStatus();
});
},false);
Use plugin Background Mode
ionic cordova plugin add cordova-plugin-background-mode
npm install #ionic-native/background-mode
Then use it like this:
import { BackgroundMode } from '#ionic-native/background-mode/ngx';
export class AppComponent {
constructor(private backgroundMode: BackgroundMode) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.backgroundMode.enable();
});
}
}

Nuxt custom module hooks not called

I want to pass some extra data from the ssr server that's present after the middleware has run, and use that on client side middleware. A bit similar to what nuxt already does with vuex.
Documentation at the render:context hook:
Every time a route is server-rendered and before render:route hook. Called before serializing Nuxt context into window.__NUXT__, useful to add some data that you can fetch on client-side.
Now my custom plugin defines some hooks as stated in the documentation, but not all seem to be called properly:
module.exports = function() {
this.nuxt.hook('render:route', (url, result, context) => {
console.log('This one is called on every server side rendering')
}
this.nuxt.hook('renderer', renderer => {
console.log('This is never called')
}
this.nuxt.hook('render:context', context => {
console.log('This is only called once, when it starts loading the module')
}
}
What am I doing wrong and how can I pass custom ssr data to the client side renderer?
Ok, just found the solution to the core problem of passing custom data from the (ssr) server to the client:
Create a plugin: plugins/my-plugin.js
export default ({ beforeNuxtRender, nuxtState }) => {
if (process.server) {
beforeNuxtRender(({ nuxtState }) => {
nuxtState.myCustomData = true
})
} else {
console.log('My cystom data on the client side:', nuxtState.myCustomData)
}
}
Then register the plugin in your nuxt.config.js:
module.exports = {
plugins: ['~/plugins/my-plugin']
}
Docs here.

Load aurelia-validation plugin during Jasmine unit tests - with webpack

I am using Aurelia with Webpack. Based on the ESNext Skeleton Webpack.
https://github.com/aurelia/skeleton-navigation/tree/master/skeleton-esnext-webpack
I have some plain JS model classes like:
import {ValidationRules} from 'aurelia-validation';
export class Address {
street = '';
}
ValidationRules
.ensure('street').required()
.on(Address);
As soon as I run my Jasmine tests (via Karma) and also with Wallaby, I get the error:
'Message: Did you forget to add ".plugin('aurelia-validation)" to your main.js?'
OK - I've not got a main.js when running tests, so how to load the plugin?
I've tried doing something like this - using aurelia-testing:
import {StageComponent} from 'aurelia-testing';
import {bootstrap} from 'aurelia-bootstrapper-webpack';
...
let component;
beforeEach(done => {
component = StageComponent
.withResources();
component.bootstrap(aurelia => {
aurelia.use.plugin('aurelia-validation')
});
done();
});
But that does not work with Webpack - open issue with aurelia-bootstrapper-webpack. Or maybe I am doing it wrongly.
Is there some other way to load the validation plugin during the tests? Or get aurelia-testing working with webpack?
At the moment, I am completely blocked from doing any unit tests if I have the validation plugin, or attempt to use aurelia-testing.
I have it working using the aurelia-cli and wallaby. You were very close which I guess makes it even more frustrating. The secret for me is that the validation plugin had to be bootstrapped first with the beforeAll method in the spec file and then the system under test created in the beforeEach method. The following spec file worked for me and resolved the Message: Did you forget to add ".plugin('aurelia-validation') to your main.js" error.
import { SourceSystemEntity } from '../../../src/entities/sourceSystemEntity';
import { StageComponent } from 'aurelia-testing';
import { bootstrap } from 'aurelia-bootstrapper';
describe('SourceSystem class', () => {
let component;
let sut: SourceSystemEntity;
beforeAll(done => {
component = StageComponent.withResources().inView('<div></div>').boundTo({});
component.configure = (aurelia: Aurelia) => {
aurelia.use
.standardConfiguration()
.plugin('aurelia-validation');
};
component.create(bootstrap).then(() => {
done();
});
});
afterAll(() => {
component.dispose();
});
beforeEach(() => {
sut = new SourceSystemEntity();
});
it('has Validation enabled', () => {
expect(sut.hasValidation()).toBeTruthy();
});
});
From what I've found the ValidationRules are run during the import process. Since they haven't been put into the actual class. What worked for me was to put the ValidationRules into the constructor or another method and call them after the bootstrap has run. Still hasn't fixed the functionality of Validation during tests but it does let you run the unit tests
import {ValidationRules} from 'aurelia-validation';
export class Address {
street = '';
constructor() {
ValidationRules
.ensure('street').required()
.on(Address);
}
}