React Native: easily scroll to a specific element in a list on the page

If you need to scroll to a specific View on a page, specified by a prop scrollToId to that page, do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
render() {
const { entities, scrollToId } = this.props;

return (
<ScrollView ref={ref => {this.scrollerRef = ref; }}>
{entities.map((entity) => {
const scrollThis = scrollToId != null && scrollToId === entity.id;

return (
<View
key={entity.id}
ref={scrollThis ? (ref) => { this.scrollToRef = ref; } : undefined}
onLayout={scrollThis ? this.onLayout : undefined}
>
<Text>Some stuff to show from entity</Text>
</View>
);
})}
</ScrollView>
);
}

onLayout = () => {
this.scrollToRef.measure((x, y, width, height, pageX, pageY) => {
if (this.scrollerRef) this.scrollerRef.scrollTo({ x: pageX, y: pageY });
});
}

entities is assumed to be a list of something you want to render, with a unique prop id.

Install Java JDK on Mac OSX from dmg/pkg without admin/root

Oracle no longer provides compressed versions of JDK 😡 and require root to install (probably they also install an auto updater nagging you all the time)

Download .dmg from Oracle and put in a directory

cd directory-with-dmg

7z x jdk-8u181-macosx-x64.dmg

(alternatively, if you don’t have 7zip mount dmg and copy out .pkg)

pkgutil --expand "JDK 8 Update 181/JDK 8 Update 181.pkg" jdk-pkg-unpacked

tar xvf jdk-pkg-unpacked/jdk180181.pkg/Payload

Contents/Home is now the JDK root

mv Contents/Home ~/jdk180181

Now you can put JAVA_HOME="$HOME/jdk180181" and PATH="$PATH:$JAVA_HOME/bin" and start using it

Use Apple HomeKit to control cheap 433 MHz devices

homebridge-telldus is a plugin for homebridge which allows you to control cheap 433MHz devices like wireless light switches and dimmers from Apple’s Home integration. This is done through Telldus Live, which provides a free service and API integration for people who bought their devices like TellStick Net and TellStick ZNet Lite. It provides a very cheap way to control your house with Siri and Apple Home.

See compatible hardware here:
https://old.telldus.com/products/compability

v1 of the homebridge-telldus plugin now also supports local communiation directly with devices that support this, like the TellStick ZNet Lite.

For instructions on how to set up the system, see:
https://github.com/jchnlemon/homebridge-telldus

Hidden hot spring behind Seljavallalaug in Iceland

Seljavallalaug pool

Most people have heard about the Seljavallalaug pool. Its temperature is lukewarm and some people advise against swimming there because of bacteria/algae in the pool. However if you go a couple hundred meters up the river, you will find a pretty cool makeshift hot pool right next to the river where you can do cold dipping in the glacial river followed by 42C of pleasure.

Hidden hot spring

GPS coordinates 🗺 63.567221, -19.606444

Migrate WordPress URLs to nginx (hexo)

I have migrated my blog from WordPress to hexo, but the old URLs need to be permanently redirected.
I’m using NGINX as my web server, so I set up some rules for redirecting the old posts to the new URLs. It’s a bit tricky because WordPress used query string param for identifying the page, but it can be sorted out using if and the NGINX $arg_ variable. In order to generate these rules, I wrote a simple node script that runs through the exported Markdown files from WordPress. Markdown files were exported using Jekyll Exporter plugin.)

index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const fm = require('front-matter');
const fs = require('fs');
const moment = require('moment');
const path = require('path');

const dir = 'blog.mifi.no/source/_posts';
const baseUrl = 'https://blog.mifi.no/';

const files = fs.readdirSync(dir);

files.forEach((file) => {
var doc = fm(fs.readFileSync(path.join(dir, file), 'utf8'));

const id = doc.attributes['id'];
if (!id) return;

const date = moment(doc.attributes.date).utc()
const url = `${baseUrl}${date.format('YYYY/MM/DD')}/${file.split('.md')[0]}`;

console.log(`if ($arg_p = ${id}) { return 301 ${url}; }`);
});

1
2
3
npm i front-matter
npm i moment
node .

Then insert output from the script to the nginx server block of the old blog:

1
2
3
4
5
6
location /blog {
<output from index.js cmd>

# default redirect
return 301 https://blog.mifi.no/;
}

Now that all pages have been redirected 301 to their new paths, a simple comment export from WordPress and import to Disqus was automatically able to crawl the old URL 301 redirects and update the URL of the Disqus comments. (Using the crawl migration tool in Disqus admin.)

Reverse engineering DNB VIPPS API by injecting Charles cert as pinned SSL certificate

charles

The VIPPS app is using API SSL certificate pinning to prevent MITM attacks, and the pinned certificate(s) is stored in the APK itself, so it can easily be replaced by our own generated Charles certificate. This allows sniffing the data going from the app to VIPPS servers.

Instructions

First download the APK from somewhere (google it)

Debuild APK
apktool d no.dnb.vipps-1.6.5.apk

Export Charles MITM SSL certificate by going to Help -> SSL Proxying -> Save Charles Root Certificate

Inject Charles certificate into app
cp charles-ssl-proxying-certificate.cer no.dnb.vipps-1.6.5.apk.out/res/raw/prod_priority_1.cer

Put APK back together
apktool b no.dnb.vipps-1.6.5.apk.out -o vipps-modified.apk

Generate debug keystore for signing the new app
echo y | keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "cn=Mark Jones, ou=JavaSoft, o=Sun, c=US"

Sign app with keystore
apksigner sign --ks debug.keystore --out vipps-modified-signed.apk vipps-modified.apk

Enter pw android

Verify signing
apksigner verify vipps-modified-signed.apk

Install new APK to device
adb install vipps-modified-signed.apk

Now just start Charles with SSL proxying enabled and set Charles (your computer’s IP) as the proxy under WIFI settings on the Android device.

Going further - decompiling

brew install dex2jar

d2j-dex2jar -f -o vipps.jar no.dnb.vipps-1.6.5.apk

Use one of the following GUI tools for decompiling and looking at the code:

None of them are perfect, and some code seems to fail decompiling in both.