React Native - adjust scrollview as keyboard shows up (ios) - ios

In my chat application, I am having a trouble animating scrollview(chat view) to slide up/adjust as keyboard shows up from bottom of the view.
If you have used any major chatting apps such as Messengers, WeChat, Line, etc., you will see how your chat screen goes up smoothly as keyboard shows up. Right now, I have imitated KeyboardAvoidingView and implemented something similar to that:
// Triggered by Keyboard.addListener("keyboardWillChangeFrame", onKeyboardChange);
const onKeyboardChange = e => {
if (!e) {
//this is scroll view's contentInset.top
setSpacing(0);
return;
}
const { duration, easing, endCoordinates, startCoordinates } = e;
let offset;
if (startCoordinates) {
offset = startCoordinates.screenY - endCoordinates.screenY;
} else {
offset = endCoordinates.height;
}
const spacing = offset > 0 ? offset : 0;
if (duration && easing) {
LayoutAnimation.configureNext({
// We have to pass the duration equal to minimal accepted duration defined here: RCTLayoutAnimation.m
duration: duration > 10 ? duration : 10,
update: {
duration: duration > 10 ? duration : 10,
type: LayoutAnimation.Types[easing] || "keyboard"
}
});
}
//this is scroll view's contentInset.top
setSpacing(spacing);
};
As you can see, I am currently just calculating offset using event passed by KeyboardWillChangeFrame and using LayoutAnimation to animate scrollview slide up.
It works fairly well but I can still see a slight delay.
In native iOS development, it can be achieve by using animateKeyframes:
#objc func keyboardWillShow(notification: NSNotification){
let duration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt
let curFrame = (notification.userInfo![UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.origin.y - curFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.view.frame.origin.y += deltaY
})
}
But it seems like it is not available in react native.
Is there anyway I can adjust scrollview as keyboard shows up from bottom as smoothly as possible?

You have to do 2 things
1 : First use react-native-keyboard-spacer to make Textinput container scroll
2 : Set offset of ChatList when keyboard show/hide
Complete Code
import React from "react";
import { View, FlatList, Text, TextInput, Keyboard } from "react-native";
import KeyboardSpacer from "react-native-keyboard-spacer";
export default class App extends React.Component {
state = {
chat: [
{ id: 1, text: "Test1 1" },
{ id: 2, text: "Test1 2" },
{ id: 3, text: "Test1 3" },
{ id: 4, text: "Test1 4" },
{ id: 5, text: "Test1 5" },
{ id: 6, text: "Test1 6" },
{ id: 7, text: "Test1 7" },
{ id: 8, text: "Test1 8" },
{ id: 9, text: "Test1 9" },
{ id: 10, text: "Test1 10" },
{ id: 11, text: "Test1 11" },
{ id: 12, text: "Test1 12" },
{ id: 13, text: "Test1 13" },
{ id: 14, text: "Test1 14" },
{ id: 15, text: "Test1 15" },
{ id: 16, text: "Test1 16" },
{ id: 17, text: "Test1 17" },
{ id: 18, text: "Test1 18" },
{ id: 19, text: "Test1 19" },
{ id: 20, text: "Test1 20" },
{ id: 21, text: "Test1 21" },
{ id: 22, text: "Test1 22" },
{ id: 23, text: "Test1 23" },
{ id: 24, text: "Test1 24" }
]
};
scrollOffset = 0;
keyboardHeight = 0;
componentDidMount() {
this.keyboardWillShowListener = Keyboard.addListener(
"keyboardWillShow",
this._keyboardWillShow
);
this.keyboardWillHideListener = Keyboard.addListener(
"keyboardWillHide",
this._keyboardWillHide
);
}
componentWillUnmount() {
this.keyboardWillShowListener.remove();
this.keyboardWillHideListener.remove();
}
_keyboardWillShow = e => {
this.keyboardHeight = e.endCoordinates
? e.endCoordinates.height
: e.end.height;
const newOffset = this.scrollOffset + this.keyboardHeight;
this.chatList.scrollToOffset({ offset: newOffset, animated: true });
};
_keyboardWillHide = e => {
const newOffset = this.scrollOffset - this.keyboardHeight;
this.chatList.scrollToOffset({ offset: newOffset, animated: true });
};
handleScroll = e => {
this.scrollOffset = e.nativeEvent.contentOffset.y;
};
render() {
return (
<View style={{ flex: 1, marginTop: 30 }}>
<FlatList
style={{ flex: 1 }}
ref={ref => {
this.chatList = ref;
}}
data={this.state.chat}
renderItem={({ item }) => (
<Text style={{ padding: 20 }}>{item.text}</Text>
)}
onScroll={this.handleScroll}
/>
<TextInput
placeholder="Enter Message"
style={{ padding: 20, borderTopWidth: 1, borderColor: "black" }}
/>
<KeyboardSpacer />
</View>
);
}
}
App Preview

Related

I want to show tooltip on mouse hover of every coordinate in angular-highchart, it should show x and y axis value in tooltip or label

chart = new Chart({
chart: {
type: "line",
// height : 1000
// height: 55 + '%',
height: (9 / 16) * 100 + "%",
// width: 1200,
},
title: {
text: "",
},
credits: {
enabled: false,
},
legend: {
title: {
text: "OrderNumber",
style: {
fontStyle: BOLD,
},
},
layout: "vertical",
align: "right",
verticalAlign: "top",
borderWidth: 1,
floating: true,
backgroundColor: WHITE,
},
xAxis: {
startOnTick: true,
endOnTick: true,
title: {
text: this.xLabel,
style,
},
type: CTYPE,
gridLineColor: BLACK,
// min:
// this.chartData != undefined
// ? Math.log10(Math.ceil(Math.min(this.chartData.series) / 10) * 10)
// : this.xMin,
max: this.xMax,
gridLineWidth: 1,
lineColor: BLACK,
minorGridLineColor: BLACK,
lineWidth: 1,
tickLength: 20,
tickInterval: 1,
minorTickInterval: 0.1,
minorGridLineWidth: 0.5,
// animation: false,
labels: {
formatter: function () {
var raise = require("superscript-text");
let num = Math.log10(this.value as number).toPrecision(1);
let base = "10";
let final = base + raise(num.toString());
return final;
},
},
},
yAxis: {
startOnTick: true,
endOnTick: true,
title: {
text: this.yLabel,
style,
},
max: this.yMax,
min: this.yMin,
type: CTYPE,
lineColor: BLACK,
lineWidth: 1,
gridLineColor: BLACK,
minorGridLineColor: BLACK,
gridLineWidth: 1,
tickLength: 20,
tickInterval: 1,
minorTickInterval: 0.1,
minorGridLineWidth: 0.5,
labels: {
formatter: function () {
var raise = require("superscript-text");
let num = Math.log10(this.value as number);
let base = "10";
let final = base + raise(num.toString());
return final;
},
},
},
plotOptions: {
series: {
stickyTracking: false,
marker: {
enabled: false,
},
states: {
hover: {
enabled: false,
},
inactive: {
opacity: 1,
},
},
animation: false,
visible: true,
},
line: {
events: {
legendItemClick: function (event) {
this.selectedItemList.forEach((item) => {
if (event.target.options.id === item.product.index) {
item.product.toggleSlashEye = !item.product.toggleSlashEye;
let count = 0;
this.selectedItemList.forEach((item) => {
if (item.product.toggleSlashEye === false) count++;
});
if (count === this.selectedItemList.length) this.isSeriesVisible = true;
else this.isSeriesVisible = false;
}
});
}.bind(this),
},
},
// animation: false,
},
tooltip: {
enabled: true,
followPointer: true,
formatter: function () {
return `<b>x = ${this.y}</b> y = <b>${this.x} </b>`;
},
},
series: [],
});
currnet code status - currently I am showing tooltip on series only.
expected - I want to show the tooltip on the locations where the yaxis and xaxis graph lines cross.

Centering google-slides text

I'm creating google slides from a csv upload via the browser. When I'm inserting text, how would I center that? They only show up on the right side for some reason.
const requests = [
{
createShape: {
objectId: `shape${csv.ID}`,
shapeType: "TEXT_BOX",
elementProperties: {
pageObjectId: `slide${index}`,
size: {
height: height,
width: width
},
transform: {
scaleX: 1,
scaleY: 1,
translateX: 350,
translateY: 100,
unit: "PT"
}
}
}
},
{
insertText: {
objectId: `shape${csv.ID}`,
insertionIndex: 0,
text: csv.text
}
}
];
```
You want to put the value of csv.text to the center of the object of shape${csv.ID} using the method of batchUpdate in Slides API.
If my understanding is correct, how about this modification? In this modification, UpdateParagraphStyleRequest is added to the request body of requests.
Modified script:
const requests = [
{
createShape: {
objectId: `shape${csv.ID}`,
shapeType: "TEXT_BOX",
elementProperties: {
pageObjectId: `slide${index}`,
size: {
height: height,
width: width
},
transform: {
scaleX: 1,
scaleY: 1,
translateX: 350,
translateY: 100,
unit: "PT"
}
}
}
},
{
insertText: {
objectId: `shape${csv.ID}`,
insertionIndex: 0,
text: csv.text
}
},
{
updateParagraphStyle: {
objectId: `shape${csv.ID}`,
textRange: {type: "ALL"},
style: {alignment: "CENTER"},
fields: "alignment"
}
}
];
Reference:
UpdateParagraphStyleRequest

cordova printer plugin is not printing t

I m trying to print a html file from my cordova app.
I have installed the cordova-plugin-printer.
In app.module.ts file imported the plugin and after that when i try to use this.printer.print('hello')
Noting happens at all
import { Printer, PrintOptions } from '#ionic-native/printer/ngx';
private printer: Printer
Print(){
console.log("Print Pressed");
var options = {
font: {
size: 22,
italic: true,
align: 'center'
},
header: {
height: '6cm',
label: {
text: "\n\nDie Freuden",
font: {
bold: true,
size: 37,
align: 'center'
}
}
},
footer: {
height: '4cm',
label: {
text: 'Johann Wolfgang von Goethe, 1749-1832, deutscher Dichter, Naturforscher',
font: { align: 'center' }
}
}
};
this.printer.print("hello",options);
console.log("Print Pressed>>>");
}
Try:
Print(){
let options: PrintOptions = {
name: 'MyDocument',
printerId: 'printer007',
duplex: true,
landscape: true,
grayscale: true
};
//Checks whether the device is capable of printing
this.printer.isAvailable().then(()=>{
console.log("printer available")
}).catch((error)=>{
console.log("printer not available"+error);
});
}

highstocks responsive styling not working in different devices

I'm trying to give my chart responsive styling in three different devices. i created rules iPad pro (max width 2048), iPad (max width 1024) and mobile (max width 480) but its not rendering properly. for iPad pro its rendering iPads styling and for iPad its showing mobile styling.
responsive: {
rules: [
{
condition: {
maxWidth:2048
},
chartOptions: {
series: [{
dataLabels: {
style: {
fontSize: '25px',
color: 'red'
},
}
},
{
dataLabels: {
style: {
fontSize: '15px',
},
}
}
]
}
},
{
condition: {
maxWidth: 1024
},
chartOptions: {
series: [{
dataLabels: {
style: {
fontSize: '35px',
color: 'green'
},
}
},
{
dataLabels: {
style: {
fontSize: '8px',
},
}
}
]
}
},
{
condition: {
maxWidth: 480
},
chartOptions: {
series: [{
dataLabels: {
style: {
fontSize: '20px',
},
}
},
{
dataLabels: {
style: {
fontSize: '8px',
},
}
}
]
}
}]
} `
Have you noticed that responsive rules like maxWidth and minWidth are applied to a chart width? This is not always equal to screen width.
Highcharts api description of maxWidth:
The responsive rule applies if the chart width is less than this.
So your code is probably working correctly. Check title on several screen widths in this example: https://jsfiddle.net/BlackLabel/3stawvum/.
responsive: {
rules: [{
condition: {
maxWidth: 2048,
minWidth: 931
},
chartOptions: {
title: {
text: '2048 title'
},
}
}, {
condition: {
maxWidth: 930,
minWidth: 401
},
chartOptions: {
title: {
text: '1024 title'
},
}
}, {
condition: {
maxWidth: 400
},
chartOptions: {
title: {
text: '480 title'
},
}
}]
}
API reference:
https://api.highcharts.com/highcharts/responsive.rules.condition.maxWidth

Highcharts: dynamic update stacked area with extra custom data

I want to display custom prompt info in stacked area chart using the technique referred in (jQuery Highchart) Is there any way to put extra custom data inside Tooltip Box?
The chart works fine on the initial data, but does not working when dynamic adding new Points.
The source code is in http://jsfiddle.net/ukNPz/1/
$(function () {
var clusterInfoChart;
var clusterOptions = {
chart: {
type: 'area',
renderTo: 'container',
events: {
load: function () {
S = this.series;
setInterval(function () {
var seconds = Math.round(new Date() / 1000);
seconds = seconds - 1397529601 + 1235;
console.log(seconds);
var shift = S[0].data.length > 10;
S[0].addPoint([seconds, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}], true, shift);
S[1].addPoint([seconds, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}], true, shift);
clusterInfoChart.redraw();
}, 3000);
}
}
},
title: {
text: 'clusterInfo'
},
xAxis: {
categories: [
'1205', '1210', '1215', '1220', '1225', '1230', '1235'],
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Events'
},
labels: {
formatter: function () {
return this.value.y;
}
}
},
tooltip: {
formatter: function () {
return this.point.yinfo.replace(";", "<br>");
}
},
plotOptions: {
area: {
stacking: 'normal',
lineColor: '#666666',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#666666'
}
}
},
series: [{
name: 'Alert',
data: [
{
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}, {
y: 2,
yinfo: '192.168.119.10:cpuwarn;192.168.119.11:memwarn'
}, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}, {
y: 2,
yinfo: '192.168.119.10:cpuwarn;192.168.119.11:memwarn'
}, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}, {
y: 2,
yinfo: '192.168.119.10:cpuwarn;192.168.119.11:memwarn'
}
]
}, {
name: 'Warn',
data: [
{
y: 0,
yinfo: ''
}, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}, {
y: 0,
yinfo: ''
}, {
y: 2,
yinfo: '192.168.119.10:cpuwarn;192.168.119.11:memwarn'
}, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}, {
y: 0,
yinfo: ''
}, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}
]
}]
};
Highcharts.setOptions({
global: {
useUTC: false
}
});
clusterInfoChart = new Highcharts.Chart(clusterOptions);
});
Just this format isn't proper:
[seconds, {
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}]
Should be:
{
x: seconds,
y: 1,
yinfo: '192.168.119.10:cpuwarn'
}

Resources