Change nativescript theme with nativescript-themes plugin in app launch - nativescript

How can I change the NativeScript app theme during the app launch using the nativescript-themes plugin?
JS
import application = require("application");
let themes = require("nativescript-themes");
themes.applyTheme('dark-theme.css');
// TODO: Check if user is logged in
application.start({ moduleName: "views/signin/signin" });
This isn't working, and yes, this is TS but the transpiled JS doesn't work.

Actually the proper code is:
import application = require("application");
let themes = require("nativescript-themes");
application.cssFile = themes.getAppliedTheme('dark-theme.css');
application.start({ moduleName: "views/signin/signin" });
The theming system replaces the currently running "app.css"; so you no longer are using the default "app.css". If you need app.css still; then you just import into your theme.css files using the #import statement.
Please note; the 'dark-theme.css' that you are using in getAppliedTheme('dark-theme.css') is the default theme, if the theme has been changed/chosen by the user in the app and the app is starting up again, then it will use the actual chosen theme, not the default theme. ;-)

You can change the theme using the *
import { Theme } from "#nativescript/theme";
#Component({
selector: 'ns-app',
templateUrl: 'app.component.html',
})
export class AppComponent implements OnInit {
constructor() {}
ngOnInit(): void {
Theme.setMode(Theme.Light);
}
}
plugin then make changes in the main app.component.ts file as per the below code.
You can also change the mode by putting conditions in the ngOnInit lifecycle.

Related

Is there a way to disable all caching in WebView (both iOS and Andriod), in a NativeScript Angular app?

I am making a NativeScript Angular app which uses WebView to display a remote web page, but as I am making changes on this page on a website, it doesn't get updated on Andriod nor on iOS devices I use for app development. Page is updated normally on regular browsers on these devices.
I've read what NativeScript Angular documentation has to say about the WebView control and it ain't very detailed.
I'd like to be able to do something like:
mWebView.getSettings().setAppCacheEnabled(false);
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
... as described here.
Here is how you could get a reference to the NativeScript WebView and from there access the native Android control (android.webkit.WebView)
import { Component } from "#angular/core";
import { EventData } from "tns-core-modules/data/observable";
import { WebView } from "tns-core-modules/ui/web-view";
import { isAndroid } from "tns-core-modules/platform";
declare let android: any; // or even better - use tns-platform-declarations for intelliSense for the native APis
#Component({
selector: "Home",
moduleId: module.id,
templateUrl: "./home.component.html",
styleUrls: ["./home.component.css"]
})
export class HomeComponent {
onWebViewLoaded(args: EventData) {
const webView = args.object as WebView;
const nativeWebView = webView.nativeView; // equal to webView.android or webView.ios (depending on the platform)
if (isAndroid) {
nativeWebView.getSettings().setAppCacheEnabled(false);
nativeWebView.getSettings().setCacheMode(android.webkit.WebSettings.LOAD_NO_CACHE);
}
}
}
Where onWebViewLoaded is used with the loaded event in the HTML
<WebView height="1200" src="https://www.nativescript.org" (loaded)="onWebViewLoaded($event)"></WebView>
A Playground app demonstrating the above here

What is the right way to hide the status bar in nativescript using angular template?

How can I hide the status bar for a specific activity?
I found this similar question, but none of the answers worked for me.
Ref # 1
Ref # 2
Ref # 3
Ref # 4
The app just crashed every time and shows me the error cannot read property getWindow while running my app on genymotion andriod VM. Below is the brief error screen shot
Below is my home.component.ts code
import { Component, OnInit } from "#angular/core";
import {Page} from "ui/page";
import * as app from "tns-core-modules/application";
#Component({
selector: "Home",
moduleId: module.id,
templateUrl: "./home.component.html",
styleUrls: ["./home.component.scss"]
})
export class HomeComponent implements OnInit {
constructor(page: Page) {
page.actionBarHidden = true;
this.statusBar('hide');
}
ngOnInit(): void {
// Init your component properties here.
}
statusBar(action: string){
var activity = app.android.startActivity;
//activity.runOnUiThread(function(){
var win = activity.getWindow();
if(action === 'hide'){
win.addFlags(app.android.nativeApp.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else if(action === 'show'){
win.clearFlags(app.android.nativeApp.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
}
Please help me on this. Thanks.
You might want to use nativescript-status-bar plugin.
import * as statusBar from 'nativescript-status-bar'
// Show
statusBar.show();
// Hide
statusBar.hide();
If you are looking for solution to view app full screen and hide status bar then use:
var activity = app.android.foregroundActivity || app.android.startActivity;
var window = activity.getWindow();
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN)
if(isAndroid){
Application.android.startActivity.getWindow().getDecorView().setSystemUiVisibility(android.view.View.SYSTEM_UI_FLAG_FULLSCREEN)
}
The code above would let you hide the statusbar on an android device, the snippet about works fine on Nativescript7 and above.
You can also implement this within onNgInit method, so as to hide the statusbar as you navigate to the page or component.

How to add vuetify to default vuepress theme

Is it possible to add vuetify to default vuepress theme ?
I just need to add few components to default theme however it would be nice to use the vuetify for handling forms within my components.
I have found a custom vuepress theme which uses a vuetify, however I would prefer to use default vuepress theme.
Another option is to eject the default theme and add the vuetify to it. However I would prefer not to eject the default theme just add vuetify to it.
The previous answer from oscarteg got me most of the way there. Here's what I had to do for the .vuepress/enhanceApp.js file (and yes, if you do not have one go ahead and create it).
import Vuetify from "vuetify";
import "vuetify/dist/vuetify.min.css";
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData // site metadata
}) => {
Vue.use(Vuetify);
options.vuetify = new Vuetify({})
};
Note that in the new Vuetify({}) passed to options.vuetify you can set your theming.
See https://github.com/vuejs/vuepress/issues/681#issuecomment-515704018
The easiest way would be to use the vuetify CDN. In your config.js add something like
module.exports = {
head: [
['link', { rel: 'stylesheet', href: `https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css` }],
['script', { src: `https://cdn.jsdelivr.net/npm/vue/dist/vue.js` }],
['script', { src: `https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js` }],
]
}
Something like that. See https://vuepress.vuejs.org/config/#head
Another way would be to install the vuetify package and add Vuetify to enhanceApp. It would look like this in your .vuepress/enhanceApp.js
import Vuetify from 'vuetify'
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData // site metadata
}) => {
Vue.use(Vuetify)
}
See https://vuepress.vuejs.org/guide/basic-config.html#theme-configuration

How to get the initial device orientation in NativeScript with Angular 2

I am getting started with NativeScript + Angular 2 and I'd like to implement a component that activates different routes depending on the device orientation. After much search, I was able to get this working but I haven't yet figured out how to get the initial device orientation, which sounds like it should be easier.
Here's my AppComponent code. Look at ngAfterViewInit:
import {Component, OnInit, OnDestroy, AfterViewInit} from "#angular/core";
import {Router} from "#angular/router";
import _application = require('application');
#Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
constructor(private router: Router) {}
ngOnInit() {
_application.on(_application.orientationChangedEvent, this.setOrientation.bind(this));
}
ngAfterViewInit() {
// How do I get the initial orientation here instead of hardcoding to 'portrait'?
this.setOrientation({newValue: 'portrait'})
}
ngOnDestroy() {
_application.off(_application.orientationChangedEvent, this.setOrientation);
}
setOrientation(args) {
if (args.newValue === 'landscape') {
this.router.navigate(['/landscape']);
} else {
this.router.navigate(['/portrait']);
}
}
}
private activity:any = application.android.foregroundActivity;
this.activity.getResources().getConfiguration().orientation;
You could use this plugin. In order to get access to the up-to-date version, you will need to pay a monthly subscription to the developers that maintain ProPlugins.
You can installed the last free version of it using:
npm i nativescript-orientation
This comes with no guaranties that it will work, especially in {N} 6+.
Once installed, you can get the current screen orientation like this:
const orientation = require("nativescript-orientation");
console.log(orientation.getOrientation());
While there is no helper to determine the initial orientation that I know of, you can still get the current screen dimensions. You may import the screen module from the core library.
import { screen } from 'tns-core-modules/platform';
Then on application initialization determine the orientation by determining if the screen height is larger than the width:
this.orientation = screen.mainScreen.heightPixels > screen.mainScreen.widthPixels ? 'portrait' : 'landscape';
Edit: This may be inconsistent and is not fully tested (meaning the screen height might not always be the height of the screen in portrait mode). If this is the case, on page load, you may use the same strategy to measure the main Page element and compare the height and width of the view to determine orientation.

Mocha-Chai throws "navigator not defined" due to React-router component

I am writing a test for a React component that uses react-router. I am using Mocha with Chai and Chai-jQuery.
My tests work fine, until I import a component from react-router into a component (e.g. Link). At this point, I get the following error:
ReferenceError: navigator is not defined
at Object.supportsHistory (/Users/nico/google-drive/code/agathos/client/node_modules/history/lib/DOMUtils.js:61:12)
I used to get a similar error with react-bootstrap until I updated to react-bootstrap v0.29.3. I have the most recent version of react-router v2.4.0 (and history v2.1.1). But the problem persists.
The only solution I have found is to change node_modules/history/lib/DOMUtils: navigator into window.navigator. This is a hack though, and not a good solution.
I think the problem is with react-router, but I don't have a solution.
Just in case, here is my test-helper.js.
import jquery from 'jquery';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import jsdom from 'jsdom';
import chai, { expect } from 'chai';
import chaiJquery from 'chai-jquery';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from './reducers';
// set up a testing environment to run like a browser in the command line
// create a fake browser and html doc
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = global.document.defaultView;
// prevent jquery defaulting to the dom by giving it access to the global.window
const $ = jquery(window);
// build renderComponent function that should render a React class
function renderComponent(ComponentClass, props = {}, appState = {}) {
const componentInstance = TestUtils.renderIntoDocument(
<Provider store={createStore(reducers, appState)}>
<ComponentClass {...props} />
</Provider>
);
// produces html
return $(ReactDOM.findDOMNode(componentInstance));
}
//build a helper for simulating events
// $.fn allows you to add a custom function to your jquery library
$.fn.simulate = function(eventName, value) {
if (value) {
// `this` allows you to access the object appended to
// `val()` is a jquery function that sets the value of selected html element
this.val(value);
}
// the [] are object method selectors, which allow you to access e.g. Simulate.change
TestUtils.Simulate[eventName](this[0]);
};
// set up chai jquery
chaiJquery(chai, chai.util, $);
export {renderComponent, expect};
It seems that react-router assumes navigator is in the global scope.
To resolve this error, you should add navigator to the global scope in your test setup phase:
global.navigator = {
userAgent: 'node.js'
};

Resources