using ionic cordova plugin didn't work on open camera or gallery on android
Ionic:
ionic (Ionic CLI) : 4.12.0
Ionic Framework : ionic-angular 3.9.2
#ionic/app-scripts : not installed
Cordova:
cordova (Cordova CLI) : 8.1.2 (cordova-lib#8.1.1)
System:
NodeJS : v10.15.3
npm : 6.9.0
OS : Windows 10
takePicture() {
const options: CameraOptions = {
quality: 75,
destinationType: this.camera.DestinationType.NATIVE_URI ,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: this.camera.PictureSourceType.CAMERA,
allowEdit: true,
correctOrientation: true,
targetWidth: 300,
targetHeight: 300,
saveToPhotoAlbum: true
}
alert("1");
this.camera.getPicture(options).then(imageData => {
let base64Image = 'data:image/jpeg;base64,' + imageData;
this.image = base64Image;
alert("done");
}, error => {
// Utils.showToast( null,JSON.stringify(error));
});
}
u're missing the most important step,
Make sure you introduce a camera in providers in app.module.ts
u should create a PictureProvider file like this
import { Injectable } from '#angular/core';
import { Defer } from '../../common/Defer';
import { Camera } from '#ionic-native/camera';
export enum PictureSource {
PhotoLibrary,
Camera,
Local,
Remote,
}
#Injectable()
export class PictureProvider {
constructor(private camera: Camera, ) {
console.log('Hello PictureProvider Provider');
}
fromCamera(source: PictureSource, options?, ) {
let mergedOtions = this.getOptions(source, options);
if (options)
for (let k in options)
mergedOtions[k] = options[k];
let defer = Defer.create();
navigator['camera'].getPicture(
imageUri => defer.resolve(imageUri),
(message: string) => {
console.log(message);
defer.reject();
},
mergedOtions,
);
return defer.promise;
}
private getOptions(source, options?) {
return {
sourceType: source == PictureSource.PhotoLibrary ? this.camera.PictureSourceType.PHOTOLIBRARY : this.camera.PictureSourceType.CAMERA,
destinationType: this.camera.DestinationType.NATIVE_URI,
quality: 50,
mediaType: this.camera.MediaType.PICTURE,
allowEdit: options.allowEdit,
correctOrientation: true,
targetWidth: options.targetWidth,
targetHeight: options.targetHeight
}
}
}
Execute as needed
this.picture.fromCamera(1, {
allowEdit: true,
targetWidth: 256,
targetHeight: 256,
destinationType: this.camera.DestinationType.DATA_URL, //直接返回base64
}).then(base64Img => {
this.headImg = this.encodeBase64Img(base64Img);
}).catch(Defer.NoOP);
Related
I have this monorepo js setup with yarn workspaces and lerna
/package.json
/packages
/common (js shared code)
/package.json
/mobile (react native - metro)
/package.json
/web (CRA)
/package.json
Mobile and web packages are importing common package inside package.json as follow
"dependencies": {
"common": "*",
}
I had to add noHoist option in root package.json so that mobile native dependencies don't get hoisted so build scripts still run fine
"workspaces": {
"packages": [
"packages/*"
],
"nohoist": [
"**/react-native",
"**/react-native/**"
]
}
Web did work fine before and after adding noHoist option
React native metro bundling start failing after adding noHoist .. it shows
"Error: Unable to resolve module .. could not be found within the project or in these directories:
node_modules
../../node_modules"
However common package does actually exists under root node_modules ?
Looks like some kind of a linking issue ! (did try to link it manually/ same issue) .. note that I didn't add common package under noHoist
here how my metro config looks like
const path= require('path');
const watchFolders = [
path.resolve(`${__dirname}`), // Relative path to package node_modules
path.resolve(`${__dirname}/../../node_modules`), // Relative path to root node_modules ];
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),},
maxWorkers: 2,
watchFolders, };
ANY IDEA ? 🧐
Turns out the issue was in bundling, fixed by editing metro.config.js to include blocklist and extraNodeModules
const path = require('path');
const exclusionList = require('metro-config/src/defaults/exclusionList');
const getWorkspaces = require('get-yarn-workspaces');
function generateAssetsPath(depth, subpath) {
return `/assets`.concat(
Array.from({ length: depth })
// eslint-disable-next-line no-unused-vars
.map((_, i) => `/${subpath}`)
.join(''),
);
}
function getMetroAndroidAssetsResolutionFix(params = {}) {
const { depth = 3 } = params;
let publicPath = generateAssetsPath(depth, 'dir');
const applyMiddleware = (middleware) => (req, res, next) => {
// eslint-disable-next-line no-plusplus
for (let currentDepth = depth; currentDepth >= 0; currentDepth--) {
const pathToReplace = generateAssetsPath(currentDepth, 'dir');
const replacementPath = generateAssetsPath(depth - currentDepth, '..');
if (currentDepth === depth) {
publicPath = pathToReplace;
}
if (req.url.startsWith(pathToReplace)) {
req.url = req.url.replace(pathToReplace, replacementPath);
break;
}
}
return middleware(req, res, next);
};
return {
publicPath,
applyMiddleware,
};
}
function getNohoistedPackages() {
// eslint-disable-next-line global-require
const monorepoRootPackageJson = require('../../package.json');
const nohoistedPackages = monorepoRootPackageJson.workspaces.nohoist
.filter((packageNameGlob) => !packageNameGlob.endsWith('**'))
.map((packageNameGlob) => packageNameGlob.substring(3));
return nohoistedPackages;
}
function getMetroNohoistSettings({
dir,
workspaceName,
reactNativeAlias,
} = {}) {
const nohoistedPackages = getNohoistedPackages();
const blockList = [];
const extraNodeModules = {};
nohoistedPackages.forEach((packageName) => {
extraNodeModules[packageName] =
reactNativeAlias && packageName === 'react-native'
? path.resolve(dir, `./node_modules/${reactNativeAlias}`)
: path.resolve(dir, `./node_modules/${packageName}`);
const regexSafePackageName = packageName.replace('/', '\\/');
blockList.push(
new RegExp(
`^((?!${workspaceName}).)*\\/node_modules\\/${regexSafePackageName}\\/.*$`,
),
);
});
return { extraNodeModules, blockList };
}
const workspaces = getWorkspaces(__dirname);
const androidAssetsResolutionFix = getMetroAndroidAssetsResolutionFix({
depth: 3,
});
const nohoistSettings = getMetroNohoistSettings({
dir: __dirname,
workspaceName: 'mobile',
});
module.exports = {
transformer: {
// Apply the Android assets resolution fix to the public path...
// publicPath: androidAssetsResolutionFix.publicPath,
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
// server: {
// // ...and to the server middleware.
// enhanceMiddleware: (middleware) =>
// androidAssetsResolutionFix.applyMiddleware(middleware),
// },
// Add additional Yarn workspace package roots to the module map.
// This allows importing importing from all the project's packages.
watchFolders: [
path.resolve(__dirname, '../../node_modules'),
...workspaces.filter((workspaceDir) => !(workspaceDir === __dirname)),
],
maxWorkers: 2,
resolver: {
// Ensure we resolve nohoisted packages from this directory.
blockList: exclusionList(nohoistSettings.blockList),
extraNodeModules: nohoistSettings.extraNodeModules,
},
};
You can check this universal CRA/RN mono-repo that uses such metro configs
I am trying to use vite in one of my existing project. After long hard work I finally managed to make everything work in development mode. But, when I tried to test the app after building scripts with vite build, all dynamic imports failed for me. The issue was, all the import statements were being converted to __import__. If I manually replace __import__ with import on built bundles, then everything works. I tried removing #vitejs/plugin-legacy but, it still did not work.
Here is my vite.config.ts file
import { UserConfigFn } from 'vite';
import RubyPlugin from 'vite-plugin-ruby';
import FullReload from 'vite-plugin-full-reload';
import styleLint from '#amatlash/vite-plugin-stylelint';
import eslintPlugin from 'vite-plugin-eslint';
import legacy from '#vitejs/plugin-legacy';
import { resolve as _resolve, join } from 'path';
import * as tsconfig from './tsconfig.json';
const paths = tsconfig.compilerOptions.paths;
const defaultAlias = Object.keys(paths).reduce((acc, key) => {
// eslint-disable-next-line #typescript-eslint/ban-ts-comment
// #ts-ignore
const value = paths[key][0];
const path: string = key.replace('/*', '/');
acc.push({
find: path,
replacement: _resolve(__dirname, value.replace('/*', '/').replace('.//', './')) + '/',
});
return acc;
}, [] as any[]);
const configFn: UserConfigFn = ({ mode, command }) => {
const plugins =
mode === 'development' && command === 'serve'
? [
styleLint({
exclude: ['node_modules', 'public', 'plyr.css'],
}),
eslintPlugin({
fix: true,
exclude: ['node_modules', '**/legacy.js'],
}),
FullReload(['config/routes.rb', 'app/views/**/*']),
]
: [];
return {
plugins: [...plugins, legacy({}), RubyPlugin()],
css: {
postcss: '',
},
resolve: {
alias: [
...defaultAlias,
{
find: /~(.+)/,
replacement: join(process.cwd(), 'node_modules/$1'),
},
],
},
build: {
sourcemap: process.env.RAILS_ENV !== 'production',
polyfillDynamicImport: true,
rollupOptions: {
output: {
manualChunks: (id) => {
if (id.includes('node_modules')) {
if (id.includes('jquery')) {
return 'jquery';
}
if (
/creditcards|snabbdom-form|email-validator|format-numbe|form-serialize|phone-regex|email-regex|currency-regex|format-number|snake-case|number-format|superagent/.test(
id
)
) {
return 'formHelpers';
}
if (id.includes('chart.js')) {
return 'chartJs';
}
if (id.includes('moment')) {
return 'momentJs';
}
if (id.includes('imagesloaded')) {
return 'imagesLoaded';
}
if (id.includes('uuid')) {
return 'uuid';
}
if (id.includes('flimflam')) {
return 'flimflam';
}
if (/cropperjs|guillotine/.test(id)) {
return 'imageHelpers';
}
if (/ff-dashboard|ff-file-uploader/.test(id)) {
return 'ffDashboard';
}
return 'vendor';
}
},
},
},
},
clearScreen: false,
};
};
export default configFn;
Turns out it was because polyfillDynamicImport to true.
I am trying to display a remote streaming video using janus gateway in my react native project.
I am using this package: https://github.com/oney/react-native-webrtc to display the streaming video in my component and janus library (janus.mobile.js file) from here https://github.com/atyenoria/react-native-webrtc-janus-gateway/blob/master/src/janus.mobile.js
My onremotestream function is triggered but i keep receiving a black screen instead of my streaming video.( both android and ios )
I am using react-native-webrtc v : 1.75.3
react-native : 0.60.5
I call Janus this way in my component:
Here's my code:
`export default class VideoExample extends Component {
componentDidMount() {
containerStreaming = this;
Janus.init({debug: "all", callback: function() {
if(started)
return;
started = true;
}});
this.janusStart();
}
janusStart = () => {
containerStreaming.setState({ visible: true });
let janus = new Janus({
server: containerStreaming.props.server,
iceServers: containerStreaming.props.iceServers,
token: containerStreaming.props.token,
success: function() {
janus.attach({
plugin: "janus.plugin.streaming",
success: function(pluginHandle) {
streaming = pluginHandle;
Janus.log(`Janus Plugin Attached : ${pluginHandle.getId()}`);
streaming.send({ "message": {"request": "watch", id: containerStreaming.props.id } });
},
error: function(error) {
Janus.error(`Error Attaching Janus Plugin ${error}`)
},
mediaState: function(medium, on) {
containerStreaming.setState({status: 'stopped', info: 'Stopped'});
Janus.log("Janus " + (on ? "started" : "stopped") + " receiving our " + medium);
},
webrtcState: function(on) {
console.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
// $("#videolocal").parent().parent().unblock();
},
onmessage: function(msg, jsep) {
console.log("jsep" ,jsep.sdp);
Janus.log(`Janus Message received : ${JSON.stringify(msg)} and jsep ${jsep}`);
var result = msg['result'];
if (!!result && result['status'] == 'stopped') {
janus.destroy();
return;
}
if (jsep !== null && jsep !== undefined) {
Janus.log(`JANUS : Handling SDP as well : ${jsep}`);
streaming.createAnswer({
jsep: jsep,
media: { audioSend: false, videoSend: false }, // recvonly
success: function(jsep){
Janus.debug(`Janus Got SDP : ${jsep}`);
streaming.send({ message: { request: 'start' }, jsep: jsep });
},
error: function(error) {
Janus.error(`Janus WebRTC error : ${error}`)
}
});
}
},
onremotestream: function(stream) {
Janus.log('Janus Remote stream detected');
Janus.log(stream);
containerStreaming.setState({status: 'streaming', info: 'Streaming'});
containerStreaming.setState({selfViewSrc: stream.toURL()});
},
oncleanup: function() {
Janus.log('Janus clean up notification')
}
})
},
error: function(error) {
Janus.error('Janus -- ' + error);
Janus.error('Destroying Janus');
janus.destroy();
},
destroyed: function() {
window.location.reload();
},
});
};
`
render() {
return (
<RTCView
zOrder={0}
streamURL={this.state.selfViewSrc}
style={styles.streamingStyle} />
);};
}
The same story with desktop chromium app with cefsharp.Net
I am using https://github.com/zeit/next.js/ and had a look at the examples:
https://github.com/zeit/next.js/tree/canary/examples/with-ant-design-less
https://github.com/zeit/next.js/tree/canary/examples/with-redux
https://github.com/zeit/next.js/tree/canary/examples/with-polyfills
I merged the three projects, so that I can use ant design and redux together with polyfill.
Works so far in Chrome, but it seems that the polyfills are not loaded correctly now.
My next.config.js looks like this:
/* eslint-disable */
const withLess = require("#zeit/next-less");
const lessToJS = require("less-vars-to-js");
const fs = require("fs");
const path = require("path");
// Where your antd-custom.less file lives
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, "./assets/antd-custom.less"), "utf8")
);
module.exports = withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables // make your antd custom effective
},
webpack: (config, {
isServer,
defaultLoaders
}) => {
const originalEntry = config.entry;
config.entry = async() => {
const entries = await originalEntry();
if (
entries["main.js"] &&
!entries["main.js"].includes("./polyfills.js")
) {
entries["main.js"].unshift("./polyfills.js");
}
return entries;
};
config.module.rules.push({
test: /\.scss$/,
use: [
defaultLoaders.babel,
{
loader: require("styled-jsx/webpack").loader,
options: {
type: "scoped",
javascriptEnabled: true
}
},
"sass-loader"
]
});
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
const origExternals = [...config.externals];
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback();
if (typeof origExternals[0] === "function") {
origExternals[0](context, request, callback);
} else {
callback();
}
},
...(typeof origExternals[0] === "function" ? [] : origExternals)
];
config.module.rules.unshift({
test: antStyles,
use: "null-loader"
});
}
return config;
}
});
My .eslintrc.js looks like this:
module.exports = {
extends: ["airbnb"],
env: {
browser: true
},
parser: "babel-eslint",
rules: {
indent: 0,
"comma-dangle": [
2,
{
arrays: "always-multiline",
objects: "always-multiline",
imports: "always-multiline",
exports: "always-multiline",
functions: "ignore"
}
],
"max-len": 1,
"arrow-parens": 0,
"import/no-named-as-default": 0,
"import/no-extraneous-dependencies": 0,
"no-nested-ternary": 0,
"no-use-before-define": 0,
"react/jsx-props-no-spreading": 0,
"react/prop-types": 1,
"react/no-array-index-key": 1,
"react/no-did-mount-set-state": 0,
"jsx-a11y/label-has-for": [
2,
{
components: ["Label"],
required: {
some: ["nesting", "id"]
},
allowChildren: true
}
],
"jsx-a11y/click-events-have-key-events": 1,
"jsx-a11y/no-noninteractive-element-interactions": 1,
"jsx-a11y/anchor-is-valid": 1,
"jsx-a11y/no-static-element-interactions": 1
}
};
My polyfills.js:
/* eslint no-extend-native: 0 */
// core-js comes with Next.js. So, you can import it like below
import includes from 'core-js/library/fn/string/virtual/includes';
import repeat from 'core-js/library/fn/string/virtual/repeat';
import assign from 'core-js/library/fn/object/assign';
// Add your polyfills (from IE10 is supported by default)
// This files runs at the very beginning (even before React and Next.js core)
String.prototype.includes = includes;
String.prototype.repeat = repeat;
Object.assign = assign;
In IE11 I get:
Object doesn't support property or method 'includes'
Can someone help here ?
I think the one you are missing is actually Array.includes.
I am using nextjs, with core-js#3, and in my polyfills I had to add
import 'core-js/features/object/values';
import 'core-js/features/object/entries';
import 'core-js/features/object/get-own-property-symbols';
import 'core-js/features/array/includes';
after these, I was able to make it work on IE11.
i'm trying to use background geolocation , i found this link :
[a link] https://www.joshmorony.com/adding-background-geolocation-t…/ .
"Geoposition is not knwon " type script error .
ionic version :2.2.1 , node version :6.10.0 , cordova version:6.5.0 .any suggestion for ionic2 geoloca
location-tracker :
import { Injectable, NgZone } from '#angular/core';
import { Geolocation,Geoposition, BackgroundGeolocation } from 'ionic-native';
import 'rxjs/add/operator/filter';
#Injectable()
export class LocationTracker {
public watch: any;
public lat: number = 0;
public lng: number = 0;
constructor(public zone: NgZone) {
}
startTracking() {
// Background Tracking
let config = {
desiredAccuracy: 0,
stationaryRadius: 20,
distanceFilter: 10,
debug: true,
interval: 2000
};
BackgroundGeolocation.configure((location) => {
console.log('BackgroundGeolocation: ' + location.latitude + ',' + location.longitude);
// Run update inside of Angular's zone
this.zone.run(() => {
this.lat = location.latitude;
this.lng = location.longitude;
});
}, (err) => {
console.log(err);
}, config);
// Turn ON the background-geolocation system.
BackgroundGeolocation.start();
// Foreground Tracking
let options = {
frequency: 3000,
enableHighAccuracy: true
};
this.watch = Geolocation.watchPosition(options).filter((p: any) => p.code === undefined).subscribe((position: Geoposition ) => {
console.log(position);
// Run update inside of Angular's zone
this.zone.run(() => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
});
});
}
stopTracking() {
console.log('stopTracking');
BackgroundGeolocation.finish();
this.watch.unsubscribe();
}
}
tion
Assuming that you have already run the following commands;
ionic plugin add cordova-plugin-geolocation
npm install --save #ionic-native/geolocation
ionic plugin add cordova-plugin-mauron85-background-geolocation
npm install --save #ionic-native/background-geolocation
try importing the plugins as follows:
import { BackgroundGeolocation } from '#ionic-native/background-geolocation';
import { Geolocation, Geoposition } from '#ionic-native/geolocation';