Compare commits
No commits in common. "4c21600576a009024d5e179f6191212438b38e5f" and "407f45f7977ad535c7608a718bc7fbbec0c3186e" have entirely different histories.
4c21600576
...
407f45f797
1
apps/blakus-nativescript/.gitignore
vendored
1
apps/blakus-nativescript/.gitignore
vendored
@ -8,6 +8,7 @@ platforms/
|
|||||||
*.js
|
*.js
|
||||||
!eslint.config.js
|
!eslint.config.js
|
||||||
!webpack.config.js
|
!webpack.config.js
|
||||||
|
!tailwind.config.js
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
|
|||||||
@ -14,9 +14,6 @@
|
|||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="com.tns.NativeScriptApplication"
|
android:name="com.tns.NativeScriptApplication"
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="_amenity_restaurant_CYImm">"Restaurant"</string>
|
|
||||||
<string name="_amenity_pub_hVjSx">"Pub"</string>
|
|
||||||
<string name="_amenity_ice_cream_12K4Gu">"Ice Cream"</string>
|
|
||||||
<string name="_amenity_food_court_Z2qUk6P">"Food Court"</string>
|
|
||||||
<string name="_amenity_fast_food_Z1zDs8J">"Fast Food"</string>
|
|
||||||
<string name="_amenity_cafe_Z13hX6o">"Cafe"</string>
|
|
||||||
<string name="_amenity_biergarten_zXiC4">"Beer Garden"</string>
|
|
||||||
<string name="_amenity_bar_hVg75">"Bar"</string>
|
|
||||||
<string name="_app_name_1k3Sbz">"Blakus"</string>
|
|
||||||
<string name="app_name">"Blakus"</string>
|
|
||||||
<string name="title_activity_kimera">"Blakus"</string>
|
|
||||||
</resources>
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<string name="_amenity_restaurant_CYImm">"Restorāns"</string>
|
|
||||||
<string name="_amenity_pub_hVjSx">"Krogs"</string>
|
|
||||||
<string name="_amenity_ice_cream_12K4Gu">"Saldējums"</string>
|
|
||||||
<string name="_amenity_food_court_Z2qUk6P">"Ēdināšanas laukums"</string>
|
|
||||||
<string name="_amenity_fast_food_Z1zDs8J">"Ātras uzkodas"</string>
|
|
||||||
<string name="_amenity_cafe_Z13hX6o">"Kafejnīca"</string>
|
|
||||||
<string name="_amenity_biergarten_zXiC4">"Biergarten"</string>
|
|
||||||
<string name="_amenity_bar_hVg75">"Bārs"</string>
|
|
||||||
<string name="_app_name_1k3Sbz">"Blakus"</string>
|
|
||||||
<string name="app_name">"Blakus"</string>
|
|
||||||
<string name="title_activity_kimera">"Blakus"</string>
|
|
||||||
</resources>
|
|
||||||
@ -4,12 +4,11 @@
|
|||||||
"license": "SEE LICENSE IN <your-license-filename>",
|
"license": "SEE LICENSE IN <your-license-filename>",
|
||||||
"repository": "<fill-your-repository-here>",
|
"repository": "<fill-your-repository-here>",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nativescript/core": "*",
|
"@nativescript/core": "*"
|
||||||
"@nativescript/geolocation": "^9.0.0",
|
|
||||||
"@nativescript/localize": "^5.2.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nativescript/android": "~8.8.0",
|
"@nativescript/android": "~8.8.0",
|
||||||
"@nativescript/ios": "~8.8.0"
|
"@nativescript/ios": "~8.8.0",
|
||||||
|
"@nativescript/tailwind": "^2.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1 @@
|
|||||||
.ns-root {
|
|
||||||
--base-color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
background-color: var(--base-color);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,7 +1,3 @@
|
|||||||
import { Application } from '@nativescript/core';
|
import { Application } from '@nativescript/core';
|
||||||
import { localize } from '@nativescript/localize';
|
|
||||||
|
|
||||||
Application.setResources({ L: localize })
|
|
||||||
|
|
||||||
Application.run({ moduleName: 'app-root' });
|
Application.run({ moduleName: 'app-root' });
|
||||||
console.log(localize('app.name'));
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"app.name": "Blakus",
|
|
||||||
"amenity": {
|
|
||||||
"bar": "Bar",
|
|
||||||
"biergarten": "Beer Garden",
|
|
||||||
"cafe": "Cafe",
|
|
||||||
"fast_food": "Fast Food",
|
|
||||||
"food_court": "Food Court",
|
|
||||||
"ice_cream": "Ice Cream",
|
|
||||||
"pub": "Pub",
|
|
||||||
"restaurant": "Restaurant"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"app.name": "Blakus",
|
|
||||||
"amenity": {
|
|
||||||
"bar": "Bārs",
|
|
||||||
"biergarten": "Biergarten",
|
|
||||||
"cafe": "Kafejnīca",
|
|
||||||
"fast_food": "Ātras uzkodas",
|
|
||||||
"food_court": "Ēdināšanas laukums",
|
|
||||||
"ice_cream": "Saldējums",
|
|
||||||
"pub": "Krogs",
|
|
||||||
"restaurant": "Restorāns"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
import * as geolocation from '@nativescript/geolocation';
|
|
||||||
import { CoreTypes } from '@nativescript/core'
|
|
||||||
|
|
||||||
export class DeviceLocation {
|
|
||||||
static async getDeviceLocation() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
// Enable location services
|
|
||||||
await geolocation.enableLocationRequest(false, true);
|
|
||||||
|
|
||||||
const enabled = await geolocation.isEnabled();
|
|
||||||
|
|
||||||
console.log('what do we got?', enabled)
|
|
||||||
|
|
||||||
// Get the current location
|
|
||||||
const location = await geolocation.getCurrentLocation({
|
|
||||||
desiredAccuracy: CoreTypes.Accuracy.high,
|
|
||||||
maximumAge: 5000,
|
|
||||||
timeout: 20000,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (location) {
|
|
||||||
console.log(`Latitude: ${location.latitude}, Longitude: ${location.longitude}`);
|
|
||||||
return location;
|
|
||||||
} else {
|
|
||||||
throw new Error('Could not get the location.');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error obtaining location:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +1,11 @@
|
|||||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
||||||
<Page.actionBar>
|
<Page.actionBar>
|
||||||
<ActionBar title="Blakus" icon="" class="action-bar">
|
<ActionBar title="My App" icon="" class="action-bar">
|
||||||
</ActionBar>
|
</ActionBar>
|
||||||
</Page.actionBar>
|
</Page.actionBar>
|
||||||
<StackLayout class="p-20">
|
<StackLayout class="p-20">
|
||||||
<Label text="Tap the button" class="h1 text-center"/>
|
<Label text="Tap the button" class="h1 text-center"/>
|
||||||
<Button text="TAP" tap="{{ onTap }}" />
|
<Button text="TAP" tap="{{ onTap }}" class="btn btn-primary btn-active"/>
|
||||||
<Button text="Location" tap="{{ onLocationTap }}" />
|
|
||||||
<Label text="{{ message }}" class="h2 text-center" textWrap="true"/>
|
<Label text="{{ message }}" class="h2 text-center" textWrap="true"/>
|
||||||
<ListView items="{{ items }}" itemTap="{{ onItemTap }}">
|
|
||||||
<ListView.itemTemplate>
|
|
||||||
<!-- The item template can only have a single root element -->
|
|
||||||
<GridLayout padding="16" columns="20, *, *">
|
|
||||||
<ContentView width="20" height="20" borderRadius="20" backgroundColor="#65adf1" />
|
|
||||||
<Label text="{{ title }}" col="1" textWrap="true" marginLeft="8" />
|
|
||||||
<Label text="{{ L(`amenity.${amenity}`) }}" col="2" />
|
|
||||||
</GridLayout>
|
|
||||||
</ListView.itemTemplate>
|
|
||||||
</ListView>
|
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@ -1,53 +1,8 @@
|
|||||||
import { Observable, Http, type ItemEventData, ListView } from '@nativescript/core';
|
import { Observable } from '@nativescript/core';
|
||||||
import { DeviceLocation } from './location';
|
|
||||||
import type { Location } from '@nativescript/geolocation';
|
|
||||||
import { localize } from '@nativescript/localize';
|
|
||||||
|
|
||||||
type ReverseGeocodeResult = {
|
|
||||||
valsts: string;
|
|
||||||
admin_vien: string;
|
|
||||||
terit_vien: string;
|
|
||||||
apdz_vieta: string;
|
|
||||||
iela: string;
|
|
||||||
maja: string;
|
|
||||||
index: string;
|
|
||||||
korpus: string;
|
|
||||||
vzd_id: string;
|
|
||||||
distance: number;
|
|
||||||
x: string;
|
|
||||||
y: string;
|
|
||||||
lon: number;
|
|
||||||
lat: number;
|
|
||||||
adrese: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
type BlakusItem = {
|
|
||||||
title: string;
|
|
||||||
amenity: string;
|
|
||||||
tags: Record<string, string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
type OverpassResult = {
|
|
||||||
version: number;
|
|
||||||
generator: string;
|
|
||||||
osm3s: Record<string, string>;
|
|
||||||
elements: {
|
|
||||||
type: string,
|
|
||||||
id: number,
|
|
||||||
tags: Record<string, string>;
|
|
||||||
}[]
|
|
||||||
}
|
|
||||||
|
|
||||||
async function aWait(timeout: number) {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, timeout));
|
|
||||||
}
|
|
||||||
|
|
||||||
export class HelloWorldModel extends Observable {
|
export class HelloWorldModel extends Observable {
|
||||||
private _counter: number;
|
private _counter: number;
|
||||||
private _message: string;
|
private _message: string;
|
||||||
private _items: BlakusItem[];
|
|
||||||
private _locationServiceBaseURL = 'https://api.kartes.lv/v3/KVDM_mwwKi/'
|
|
||||||
private _overpassBaseURL = 'https://overpass-api.de/api/';
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -68,115 +23,17 @@ export class HelloWorldModel extends Observable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get items(): BlakusItem[] {
|
|
||||||
return this._items || [];
|
|
||||||
}
|
|
||||||
|
|
||||||
set items(value: BlakusItem[]) {
|
|
||||||
if (this._items !== value) {
|
|
||||||
this._items = value;
|
|
||||||
this.notifyPropertyChange('items', value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async reverseGeocode({latitude, longitude}: Location) {
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.set('lat', latitude.toString());
|
|
||||||
params.set('lon', longitude.toString());
|
|
||||||
|
|
||||||
this.message = [latitude, longitude].join(', ');
|
|
||||||
|
|
||||||
const url = new URL(`reverse_geocoding?${params}`, this._locationServiceBaseURL).toString();
|
|
||||||
const result = await Http.getJSON<ReverseGeocodeResult>(url);
|
|
||||||
console.log(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
overpassQuery(query: string) {
|
|
||||||
const url = new URL(`interpreter?data=${encodeURIComponent(query)}`, this._overpassBaseURL).toString();
|
|
||||||
console.log('overpass query', url)
|
|
||||||
return Http.getJSON<OverpassResult>(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
async getOverpassAmenities({latitude, longitude}: Location) {
|
|
||||||
const radius = 1000; // meters
|
|
||||||
const query = `
|
|
||||||
[out:json][timeout:25];
|
|
||||||
node["amenity"](around:${radius}, ${latitude}, ${longitude});
|
|
||||||
out tags;
|
|
||||||
`;
|
|
||||||
const result = await this.overpassQuery(query);
|
|
||||||
console.log('yep');
|
|
||||||
console.log(Array.from(new Set(result.elements.map(el => el.tags['amenity']))));
|
|
||||||
}
|
|
||||||
|
|
||||||
async getOverpassInfo({latitude, longitude}: Location) {
|
|
||||||
|
|
||||||
const radius = 1000; // meters
|
|
||||||
const amenities = ['restaurant', 'cafe', 'bar', 'pub', 'biergarten', 'fast_food', 'food_court', 'ice_cream'];
|
|
||||||
|
|
||||||
const query = `
|
|
||||||
[out:json];
|
|
||||||
node(around:${radius}, ${latitude}, ${longitude})["amenity"~"${amenities.join('|')}"];
|
|
||||||
out body;
|
|
||||||
>;
|
|
||||||
out skel qt;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await this.overpassQuery(query);
|
|
||||||
this.items = result.elements
|
|
||||||
.map(({ tags }) => ({ title: tags.name, amenity: tags.amenity, tags}))
|
|
||||||
.filter(i => amenities.includes(i.amenity)); // query returns some random results. need to look into this
|
|
||||||
|
|
||||||
console.log(localize('app.name'))
|
|
||||||
|
|
||||||
console.log(result.elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
async postalPolygons(country = 'LV', code: string, mode: 'isolate' | 'collect' | 'union' = 'union') {
|
|
||||||
await aWait(1000);
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
if (code.length === 4) params.set('search', `${country}-${code}`);
|
|
||||||
if (code.length == 2) params.set('groups', `${country}-${code}`)
|
|
||||||
params.set('union_mode', mode);
|
|
||||||
params.set('wgs84', '');
|
|
||||||
// params.set('wkt', '');
|
|
||||||
const url = new URL(`postal_codes?${params}`, this._locationServiceBaseURL).toString();
|
|
||||||
|
|
||||||
const result = await Http.getJSON(url);
|
|
||||||
console.log(url);
|
|
||||||
console.log(result);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async onLocationTap() {
|
|
||||||
const location = await DeviceLocation.getDeviceLocation();
|
|
||||||
await this.getOverpassInfo(location);
|
|
||||||
// await this.getOverpassAmenities(location);
|
|
||||||
// const { index } = await this.reverseGeocode(location);
|
|
||||||
// const [country, code] = index.split('-');
|
|
||||||
// await this.postalPolygons(country, code);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
onTap() {
|
onTap() {
|
||||||
this._counter--;
|
this._counter--;
|
||||||
|
this.updateMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateMessage() {
|
||||||
if (this._counter <= 0) {
|
if (this._counter <= 0) {
|
||||||
this.updateMessage('Hoorraaay! You unlocked the NativeScript clicker achievement!');
|
this.message =
|
||||||
|
'Hoorraaay! You unlocked the NativeScript clicker achievement!';
|
||||||
} else {
|
} else {
|
||||||
this.updateMessage(`${this._counter} taps left`);
|
this.message = `${this._counter} taps left`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onItemTap(args: ItemEventData) {
|
|
||||||
const listView = args.object as ListView
|
|
||||||
console.log('Tapped item', listView.items[args.index])
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateMessage(message = "") {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
apps/blakus-nativescript/tailwind.config.js
Normal file
13
apps/blakus-nativescript/tailwind.config.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: ['./src/**/*.{css,xml,html,vue,svelte,ts,tsx}'],
|
||||||
|
// use the .ns-dark class to control dark mode (applied by NativeScript) - since 'media' (default) is not supported.
|
||||||
|
darkMode: ['class', '.ns-dark'],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
corePlugins: {
|
||||||
|
preflight: false, // disables browser-specific resets
|
||||||
|
},
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user