How to find difference between time in moment.js in React Native - react-native

How can I find difference time in React Native (I'm using moment):
Like:
let end = endTime; // 10:10:05
let start = startTime; // 10:10:03
moment.utc(moment(end," hh:mm:ss").diff(moment(start," hh:mm:ss"))).format("mm:ss")
//expected output: 00:00:02

You would need to use moment.duration
function timeRemaining (start, end) {
// get unix seconds
const began = moment(start).unix();
const stopped = moment(end).unix();
// find difference between unix seconds
const difference = stopped - began;
// apply to moment.duration
const duration = moment.duration(difference, 'seconds');
// then format the duration
const h = duration.hours().toString();
const m = duration.minutes().toString().padStart(2, '0');
const s = duration.seconds().toString().padStart(2, '0');
return `${h}:${m}:${s}`;
}

Related

ethers.js, Swap on uniswapV3 failed tx

Im trying to use exactInput() function for UniV3 interface but when trying to execute the code the transactions fails https://goerli.etherscan.io/tx/0xb0d5e4b491610b9db8d98cc938008ba2a4e1a06e67b05ed87ac6c0ca3ad61dab
I know eth send shows 0 in this one but even especifying amount it fails, I dont know what to change..
I have checked many codes out there and cant see the mistake, please could someone give me some advice?
const {abi: V3SwapRouterABI} = require('#uniswap/v3-periphery/artifacts/contracts/interfaces/ISwapRouter.sol/ISwapRouter.json')
const { ethers } = require("ethers")
require("dotenv").config()
const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET
const PRIVATE_KEY = process.env.PRIVATE_KEY
const WALLET_ADDRESS = process.env.WALLET_ADDRESS
// now you can call sendTransaction
const wethToken= "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"
const Uni= "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
const UniswapRouter="0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
const UniV3Contract = new ethers.Contract(
UniswapRouter,
V3SwapRouterABI
)
const provider = new ethers.providers.JsonRpcProvider(INFURA_URL_TESTNET)
const wallet = new ethers.Wallet(PRIVATE_KEY)
const signer = wallet.connect(provider)
const FEE_SIZE = 3
function encodePath(path, fees) {
if (path.length != fees.length + 1) {
throw new Error('path/fee lengths do not match')
}
let encoded = '0x'
for (let i = 0; i < fees.length; i++) {
// 20 byte encoding of the address
encoded += path[i].slice(2)
// 3 byte encoding of the fee
encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0')
}
// encode the final token
encoded += path[path.length - 1].slice(2)
return encoded.toLowerCase()
}
async function getToken() {
const path = encodePath([wethToken, Uni], [3000])
const deadline = Math.floor(Date.now()/1000) + (60*10)
const params = {
path: path,
recipient: WALLET_ADDRESS,
deadline: deadline,
amountIn: ethers.utils.parseEther('0.01'),
amountOutMinimum: 0
}
const encodedData = UniV3Contract.interface.encodeFunctionData("exactInput", [params])
const txArg = {
to: UniswapRouter,
from: WALLET_ADDRESS,
data: encodedData,
gasLimit: ethers.utils.hexlify(1000000)
}
const tx = await signer.sendTransaction(txArg)
console.log('tx: ', tx)
const receipt = tx.wait()
console.log('receipt: ', receipt)
}
module.exports = { getToken
You will need to remove the Deadline.. The new router 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 moved deadline to the multi-call function (since the router is designed to be multi-call)

OfflineAudioContext processing takes increasingly longer in Safari

I am processing an audio buffer with an OfflineAudioContext with the following node layout:
[AudioBufferSourceNode] -> [AnalyserNode] -> [OfflineAudioContext]
This works very good on Chrome (106.0.5249.119) but on Safari 16 (17614.1.25.9.10, 17614) each time I run the analysis takes longer and longer. Both running on macOS.
What's curious is that I must quit Safari to "reset" the processing time.
I guess there's a memory leak?
Is there anything that I'm doing wrong in the JavaScript code that would cause Safari to not garbage collect?
async function processFrequencyData(
audioBuffer,
options
) {
const {
fps,
numberOfSamples,
maxDecibels,
minDecibels,
smoothingTimeConstant,
} = options;
const frameFrequencies = [];
const oc = new OfflineAudioContext({
length: audioBuffer.length,
sampleRate: audioBuffer.sampleRate,
numberOfChannels: audioBuffer.numberOfChannels,
});
const lengthInMillis = 1000 * (audioBuffer.length / audioBuffer.sampleRate);
const source = new AudioBufferSourceNode(oc);
source.buffer = audioBuffer;
const az = new AnalyserNode(oc, {
fftSize: numberOfSamples * 2,
smoothingTimeConstant,
minDecibels,
maxDecibels,
});
source.connect(az).connect(oc.destination);
const msPerFrame = 1000 / fps;
let currentFrame = 0;
function process() {
const frequencies = new Uint8Array(az.frequencyBinCount);
az.getByteFrequencyData(frequencies);
// const times = new number[](az.frequencyBinCount);
// az.getByteTimeDomainData(times);
frameFrequencies[currentFrame] = frequencies;
const nextTime = (currentFrame + 1) * msPerFrame;
if (nextTime < lengthInMillis) {
currentFrame++;
const nextTimeSeconds = (currentFrame * msPerFrame) / 1000;
oc.suspend(nextTimeSeconds).then(process);
}
oc.resume();
}
oc.suspend(0).then(process);
source.start(0);
await oc.startRendering();
return frameFrequencies;
}
const buttonsDiv = document.createElement('div');
document.body.appendChild(buttonsDiv);
const initButton = document.createElement('button');
initButton.onclick = init;
initButton.innerHTML = 'Load audio'
buttonsDiv.appendChild(initButton);
const processButton = document.createElement('button');
processButton.disabled = true;
processButton.innerHTML = 'Process'
buttonsDiv.appendChild(processButton);
const resultElement = document.createElement('pre');
document.body.appendChild(resultElement)
async function init() {
initButton.disabled = true;
resultElement.innerText += 'Loading audio... ';
const audioContext = new AudioContext();
const arrayBuffer = await fetch('https://gist.githubusercontent.com/marcusstenbeck/da36a5fc2eeeba14ae9f984a580db1da/raw/84c53582d3936ac78625a31029022c8fdb734b2a/base64audio.txt').then(r => r.text()).then(fetch).then(r => r.arrayBuffer())
resultElement.innerText += 'finished.';
resultElement.innerText += '\nDecoding audio... ';
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
resultElement.innerText += 'finished.';
processButton.onclick = async () => {
processButton.disabled = true;
resultElement.innerText += '\nStart processing... ';
const t0 = Date.now();
await processFrequencyData(audioBuffer, {
fps: 30,
numberOfSamples: 2 ** 13,
maxDecibels: -25,
minDecibels: -70,
smoothingTimeConstant: 0.2,
});
resultElement.innerText += `finished in ${Date.now() - t0} ms`;
processButton.disabled = false;
};
processButton.disabled = false;
}
I guess this is really a bug in Safari. I'm able to reproduce it by rendering an OfflineAudioContext without any nodes. As soon as I use suspend()/resume() every invocation takes a little longer.
I'm only speculating here but I think it's possible that there is some internal mechanism which tries to prevent the rapid back and forth between the audio thread and the main thread. It almost feels like one of those login forms which takes a bit longer to validate the password every time you try.
Anyway I think you can avoid using suspend()/resume() for your particular use case. It should be possible to create an OfflineAudioContext for each of the slices instead. In order to get the same effect you would only render the particular slice with each OfflineAudioContext.
const currentTime = 0;
while (currentTime < duration) {
const offlineAudioContext = new OfflineAudioContext({
length: LENGTH_OF_ONE_SLICE,
sampleRate
});
const audioBufferSourceNode = new AudioBufferSourceNode(
offlineAudioContext,
{
buffer
}
);
const analyserNode = new AnalyserNode(offlineAudioContext);
audioBufferSourceNode.start(0, currentTime);
audioBufferSourceNode
.connect(analyserNode)
.connect(offlineAudioContext.destination);
await offlineAudioContext.startRendering();
const frequencies = new Uint8Array(analyserNode.frequencyBinCount);
analyserNode.getByteFrequencyData(frequencies);
// do something with the frequencies ...
currentTime += LENGTH_OF_ONE_SLICE * sampleRate;
}
I think the only thing missing would be the smoothing since each of those slices will have it's own AnalyserNode.

React Native - Native module vs JS performance

We have need for faster price calculations in our app. Currently we iterate over product items in JS and calculate each product item’s price. I was thinking maybe native modules could be used for faster speeds. But it doesn’t seem like it?
When I test a simple C++ native module with performance.now() its slower than the JS equivalent. Its just a for loop of 20 iterations of a multiplication.
I guess there is some kind of overhead (JSON parsing?) when using native modules.
First I tried using the promise based RCT_EXPORT_METHOD way and the first execution would take about 15ms.
Then I tried RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD but it was still slower than JS. It took about 0.4ms first execution.
JS would take about 0.0025ms first execution.
Is native modules for just iterating and calculating prices a bad idea/will it not be faster than JS?
The code:
int multiply(float a, float b)
{
for (int i = 0; i < 100; i++)
{
int test = a * b;
}
return a * b;
}
// Native module
React.useEffect(() => {
const p1 = performance.now();
const test = multiply(3, 7);
const p2 = performance.now();
const result = p2 - p1;
console.log(`A: ${result}`, test);
}, []);
// JS
React.useEffect(() => {
const p1 = performance.now();
const test = 3 * 7;
for (let i = 0; i < 20; i++) {
const a = 3 * 7;
}
const p2 = performance.now();
const result = p2 - p1;
console.log(`B: ${result}`, test);
}, []);

Making a value dynamic in Spark AR via Script

Coming from this Question Tweening Colors on Spark AR via Script i now try to make start and end color dynamically bounded. I propably havn't swallowed the whole concept of reactive programming yet, but i tried to make a factory so the value is a function... yet its not working, or only with the initial values. Using the set function and restarting animation doesnt change a thing. What am i missing? Thank you and best regards!
const pink = [.99, .682, .721, 1];
const blue = [.0094, .0092, .501, 1];
const yellow = [0.9372, .7725, 0, 1];
function ColorFactory() {
this.sourceCol = pink;
this.targetCol = blue;
this.set = function (_col1, _col2) {
this.sourceCol = _col1;
this.targetCol = _col2;
}
this.get = function (id) {
switch (id) {
case 'source': return this.sourceCol;
default: return this.targetCol;
}
}
}
var colfac = new ColorFactory();
const timeDriver = Animation.timeDriver(timeDriverParameters);
const rotSampler = Animation.samplers.easeInQuad(0, 35);
const alphaSampler = Animation.samplers.linear(1, 0);
const colSampler = Animation.samplers.linear(colfac.get('source'), colfac.get('target'));
const colorAnimation = Animation.animate(timeDriver, colSampler);
timedriver.start();
//doesnt make change anything, same colors as before:
colfac.set(blue, yellow);
timedriver.reset();
timedriver.start();
So how could i make the set of colors dynamic? Anyone?
The only "good" option for you is to do something like this:
const colors = [];
const driver = A.timeDriver({ durationMilliseconds : 1000 });
// On NativeUI monitor selected index event
ui.selectedIndex.monitor.subscribe(
(val) => {
const sampler = A.samplers.linear(colors[val.oldValue, colors[val.newValue]);
const colorAnimation = A.animate(driver, sampler);
// bind here to shader
})

DataTables - filtering based on time span

I have a column with data, within the datatables, similar to the below:
0500-1300
0500-1430
0600-0915
0600-1000
0600-1100
0600-1115
0600-1130
0600-1200
0600-1215
0600-1300
0600-1315
I would like a filter not too dissimilar from http://yadcf-showcase.appspot.com/dom_bootstrap_time.html where someone can pick a FROM time and a TO time, which would then filter the data.
Let's say say someone chooses:
FROM: 0600
TO: 1100
Then only 3 would show. However if I chose:
FROM: 0500
TO: 1400
All would show. Is such a thing possible? Would the plugin from the site above be what I am after?
Try this:
const timeStringToInt = (time) => {
const hoursMinutes = time.split(/[.:]/);
const hours = parseInt(hoursMinutes[0], 10) * 60;
var minutes = parseInt(hoursMinutes[1], 10);
return hours + minutes;
}
$.fn.dataTable.ext.search.push(
(settings, data, dataIndex) => {
const min = timeStringToInt($('#timeFrom').val());
const max = timeStringToInt($('#timeTo').val());
const start = timeStringToInt(data[0]);
const end = timeStringToInt(data[1]);
return start >= min && end <= max;
}
);
You might need to alter your function depending upon the position of the hours columns. Working JSFiddle here.
EDIT
After looking at your data a little more I made a mistake in my initial answer, this should do it:
const timeStringToInt = (time) => {
const hoursMinutes = time.split(":");
const hours = parseInt(hoursMinutes[0], 10) * 60;
var minutes = parseInt(hoursMinutes[1], 10);
return hours + minutes;
}
const stringToInt = (time) => {
var minutes = parseInt(time.slice(-2), 10);
const hours = parseInt(time.slice(0, -2), 10) * 60;
return hours + minutes;
}
$.fn.dataTable.ext.search.push(
(settings, data, dataIndex) => {
const min = timeStringToInt($('#timeFrom').val());
const max = timeStringToInt($('#timeTo').val());
const timeParts = data[0].split("-");
const start = stringToInt(timeParts[0]);
const end = stringToInt(timeParts[1]);
return start >= min && end <= max;
}
);
Updated JSFiddle here.
Hope that helps :-)