support showing geolocation on map

This commit is contained in:
MaysWind
2023-05-14 22:33:37 +08:00
parent bd542ac308
commit 2ba143d6ea
14 changed files with 257 additions and 8 deletions
+116
View File
@@ -0,0 +1,116 @@
<template>
<f7-sheet swipe-to-close swipe-handler=".swipe-handler" style="height:auto"
:opened="show" @sheet:open="onSheetOpen" @sheet:closed="onSheetClosed">
<f7-toolbar>
<div class="swipe-handler"></div>
<div class="left"></div>
<div class="right">
<f7-link :text="$t('Done')" @click="save"></f7-link>
</div>
</f7-toolbar>
<f7-page-content class="no-margin-vertical no-padding-vertical">
<div ref="map" style="height: 400px; width: 100%"></div>
</f7-page-content>
</f7-sheet>
</template>
<script>
export default {
props: [
'modelValue',
'show'
],
emits: [
'update:modelValue',
'update:show'
],
data() {
return {
leaflet: null,
tileLayer: null,
zoomControl: null,
attribution: null,
marker: null,
initCenter: [ 0, 0 ],
zoomLevel: 1
}
},
methods: {
save() {
this.$emit('update:show', false);
},
onSheetOpen() {
let isFirstInit = false;
let centerChanged = false;
if (this.modelValue && (this.modelValue.longitude || this.modelValue.latitude)) {
if (this.initCenter[0] !== this.modelValue.latitude || this.initCenter[1] !== this.modelValue.longitude) {
this.initCenter[0] = this.modelValue.latitude;
this.initCenter[1] = this.modelValue.longitude;
this.zoomLevel = 14;
centerChanged = true;
}
} else if (!this.modelValue || (!this.modelValue.longitude && !this.modelValue.latitude)) {
if (this.initCenter[0] || this.initCenter[1]) {
this.initCenter[0] = 0;
this.initCenter[1] = 0;
this.zoomLevel = 1;
centerChanged = true;
}
}
if (!this.leaflet) {
const mapContainer = this.$refs.map;
this.leaflet = this.$map.leaflet.map(mapContainer, {
attributionControl: false,
zoomControl: false
});
this.tileLayer = this.$map.leaflet.tileLayer(this.$map.generateOpenStreetMapTileImageUrl(), {
maxZoom: 19
});
this.tileLayer.addTo(this.leaflet);
this.zoomControl = this.$map.leaflet.control.zoom({
zoomInTitle: this.$t('Zoom in'),
zoomOutTitle: this.$t('Zoom out'),
});
this.zoomControl.addTo(this.leaflet);
this.attribution = this.$map.leaflet.control.attribution({
prefix: '&copy; <a href="http://www.openstreetmap.org/copyright" class="external" target="_blank">OpenStreetMap</a>'
});
this.attribution.addTo(this.leaflet);
isFirstInit = true;
}
if (isFirstInit || centerChanged) {
this.leaflet.setView(this.initCenter, this.zoomLevel);
}
if (centerChanged && this.zoomLevel > 1) {
if (!this.marker) {
this.marker = this.$map.leaflet.marker(this.initCenter).addTo(this.leaflet);
} else {
this.marker.setLatLng(this.initCenter);
}
} else if (centerChanged && this.zoomLevel <= 1) {
if (this.marker) {
this.marker.remove();
this.marker = null;
}
}
},
onSheetClosed() {
this.close();
},
close() {
this.$emit('update:show', false);
}
}
}
</script>
+5
View File
@@ -389,4 +389,9 @@ export default {
ignoreError: !!ignoreError
});
},
generateOpenStreetMapTileImageUrl: () => {
const token = userState.getToken();
return 'proxy/openstreetmap/tile/{z}/{x}/{y}.png?token=' + token;
},
};
+3
View File
@@ -703,6 +703,8 @@ export default {
'Back': 'Back',
'Load More': 'Load More',
'No data': 'No data',
'Zoom in': 'Zoom in',
'Zoom out': 'Zoom out',
'Change Language': 'Change Language',
'Date is too early': 'Date is too early',
'Unlock Application': 'Unlock Application',
@@ -833,6 +835,7 @@ export default {
'Geographic Location': 'Geographic Location',
'No Location': 'No Location',
'Getting Location...': 'Getting Location...',
'Show on the map': 'Show on the map',
'Update Geographic Location': 'Update Geographic Location',
'Clear Geographic Location': 'Clear Geographic Location',
'Unable to get current position': 'Unable to get current position',
+3
View File
@@ -703,6 +703,8 @@ export default {
'Back': '返回',
'Load More': '加载更多',
'No data': '没有数据',
'Zoom in': '放大',
'Zoom out': '缩小',
'Change Language': '修改语言',
'Date is too early': '日期过早',
'Unlock Application': '解锁应用',
@@ -833,6 +835,7 @@ export default {
'Geographic Location': '地理位置',
'No Location': '没有位置',
'Getting Location...': '正在获取位置...',
'Show on the map': '在地图上显示',
'Update Geographic Location': '更新地理位置',
'Clear Geographic Location': '清除地理位置',
'Unable to get current position': '无法获取当前地理位置',
+9
View File
@@ -73,6 +73,9 @@ import 'line-awesome/dist/line-awesome/css/line-awesome.css';
import VueDatePicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css';
import * as Leaflet from 'leaflet/dist/leaflet-src.esm.js';
import 'leaflet/dist/leaflet.css';
import api from './consts/api.js';
import datetime from './consts/datetime.js';
import currency from './consts/currency.js';
@@ -135,6 +138,7 @@ import IconSelectionSheet from './components/mobile/IconSelectionSheet.vue';
import ColorSelectionSheet from './components/mobile/ColorSelectionSheet.vue';
import InformationSheet from './components/mobile/InformationSheet.vue';
import NumberPadSheet from './components/mobile/NumberPadSheet.vue';
import MapSheet from './components/mobile/MapSheet.vue';
import TransactionTagSelectionSheet from './components/mobile/TransactionTagSelectionSheet.vue';
import TextareaAutoSize from "./directives/mobile/textareaAutoSize.js";
@@ -254,6 +258,7 @@ app.component('IconSelectionSheet', IconSelectionSheet);
app.component('ColorSelectionSheet', ColorSelectionSheet);
app.component('InformationSheet', InformationSheet);
app.component('NumberPadSheet', NumberPadSheet);
app.component('MapSheet', MapSheet);
app.component('TransactionTagSelectionSheet', TransactionTagSelectionSheet);
app.directive('TextareaAutoSize', TextareaAutoSize);
@@ -299,6 +304,10 @@ app.config.globalProperties.$locale = {
getDisplayCurrency: (value, currencyCode, notConvertValue) => getDisplayCurrency(value, currencyCode, notConvertValue, i18n.global.t),
initLocale: initLocale
};
app.config.globalProperties.$map = {
leaflet: Leaflet,
generateOpenStreetMapTileImageUrl: services.generateOpenStreetMapTileImageUrl
};
app.config.globalProperties.$tIf = (text, isTranslate) => transateIf(text, isTranslate, i18n.global.t);
app.config.globalProperties.$alert = (message, confirmCallback) => showAlert(message, confirmCallback, i18n.global.t);
+21 -7
View File
@@ -38,12 +38,12 @@
<f7-list-input type="textarea" label="Description" placeholder="Your transaction description (optional)"></f7-list-input>
</f7-list>
<f7-list form strong inset dividers class="margin-vertical" :class="{ 'readonly': mode === 'view' }"
<f7-list form strong inset dividers class="margin-vertical"
v-else-if="!loading">
<f7-list-item
class="transaction-edit-amount"
link="#" no-chevron
:class="{ 'color-teal': transaction.type === $constants.transaction.allTransactionTypes.Expense, 'color-red': transaction.type === $constants.transaction.allTransactionTypes.Income }"
:class="{ 'readonly': mode === 'view', 'color-teal': transaction.type === $constants.transaction.allTransactionTypes.Expense, 'color-red': transaction.type === $constants.transaction.allTransactionTypes.Income }"
:style="{ fontSize: sourceAmountFontSize + 'px' }"
:header="$t(sourceAmountName)"
:title="getDisplayAmount(transaction.sourceAmount, transaction.hideAmount)"
@@ -59,6 +59,7 @@
<f7-list-item
class="transaction-edit-amount"
link="#" no-chevron
:class="{ 'readonly': mode === 'view' }"
:style="{ fontSize: destinationAmountFontSize + 'px' }"
:header="$t('Transfer In Amount')"
:title="getDisplayAmount(transaction.destinationAmount, transaction.hideAmount)"
@@ -76,7 +77,7 @@
class="list-item-with-header-and-title list-item-title-hide-overflow"
key="expenseCategorySelection"
link="#" no-chevron
:class="{ 'disabled': !hasAvailableExpenseCategories }"
:class="{ 'disabled': !hasAvailableExpenseCategories, 'readonly': mode === 'view' }"
:header="$t('Category')"
@click="showCategorySheet = true"
v-if="transaction.type === $constants.transaction.allTransactionTypes.Expense"
@@ -106,7 +107,7 @@
class="list-item-with-header-and-title list-item-title-hide-overflow"
key="incomeCategorySelection"
link="#" no-chevron
:class="{ 'disabled': !hasAvailableIncomeCategories }"
:class="{ 'disabled': !hasAvailableIncomeCategories, 'readonly': mode === 'view' }"
:header="$t('Category')"
@click="showCategorySheet = true"
v-if="transaction.type === $constants.transaction.allTransactionTypes.Income"
@@ -136,7 +137,7 @@
class="list-item-with-header-and-title list-item-title-hide-overflow"
key="transferCategorySelection"
link="#" no-chevron
:class="{ 'disabled': !hasAvailableTransferCategories }"
:class="{ 'disabled': !hasAvailableTransferCategories, 'readonly': mode === 'view' }"
:header="$t('Category')"
@click="showCategorySheet = true"
v-if="transaction.type === $constants.transaction.allTransactionTypes.Transfer"
@@ -165,7 +166,7 @@
<f7-list-item
class="list-item-with-header-and-title"
link="#" no-chevron
:class="{ 'disabled': !allVisibleAccounts.length }"
:class="{ 'disabled': !allVisibleAccounts.length, 'readonly': mode === 'view' }"
:header="$t(sourceAccountName)"
:title="transaction.sourceAccountId ? $utilities.getNameByKeyValue(allAccounts, transaction.sourceAccountId, 'id', 'name') : $t('None')"
@click="showSourceAccountSheet = true"
@@ -187,7 +188,7 @@
<f7-list-item
class="list-item-with-header-and-title"
link="#" no-chevron
:class="{ 'disabled': !allVisibleAccounts.length }"
:class="{ 'disabled': !allVisibleAccounts.length, 'readonly': mode === 'view' }"
:header="$t('Destination Account')"
:title="transaction.destinationAccountId ? $utilities.getNameByKeyValue(allAccounts, transaction.destinationAccountId, 'id', 'name') : $t('None')"
v-if="transaction.type === $constants.transaction.allTransactionTypes.Transfer"
@@ -210,6 +211,7 @@
<f7-list-item
class="list-item-with-header-and-title"
link="#" no-chevron
:class="{ 'readonly': mode === 'view' }"
:header="$t('Transaction Time')"
:title="$utilities.formatUnixTime($utilities.getActualUnixTimeForStore(transaction.time, $utilities.getTimezoneOffsetMinutes(), $utilities.getBrowserTimezoneOffsetMinutes()), this.$t('format.datetime.long'))"
@click="showTransactionDateTimeSheet = true"
@@ -222,6 +224,7 @@
<f7-list-item
:no-chevron="mode === 'view'"
class="list-item-with-header-and-title list-item-title-hide-overflow list-item-no-item-after"
:class="{ 'readonly': mode === 'view' }"
:header="$t('Transaction Time Zone')"
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Timezone'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), pageTitle: $t('Transaction Time Zone'), popupCloseLinkText: $t('Done') }">
<select v-model="transaction.timeZone">
@@ -240,6 +243,7 @@
<f7-list-item
link="#" no-chevron
class="list-item-with-header-and-title list-item-title-hide-overflow"
:class="{ 'readonly': mode === 'view' && !transaction.geoLocation }"
:header="$t('Geographic Location')"
@click="showGeoLocationActionSheet = true"
>
@@ -249,10 +253,15 @@
<span v-else-if="!transaction.geoLocation">{{ geoLocationStatusInfo }}</span>
</f7-block>
</template>
<map-sheet v-model="transaction.geoLocation"
v-model:show="showGeoLocationMapSheet">
</map-sheet>
</f7-list-item>
<f7-list-item
link="#" no-chevron
:class="{ 'readonly': mode === 'view' }"
:header="$t('Tags')"
@click="showTransactionTagSheet = true"
>
@@ -283,6 +292,7 @@
type="textarea"
class="transaction-edit-comment"
style="height: auto"
:class="{ 'readonly': mode === 'view' }"
:label="$t('Description')"
:placeholder="mode !== 'view' ? $t('Your transaction description (optional)') : ''"
v-textarea-auto-size
@@ -295,6 +305,9 @@
<f7-actions-button v-if="mode !== 'view'" @click="updateGeoLocation(true)">{{ $t('Update Geographic Location') }}</f7-actions-button>
<f7-actions-button v-if="mode !== 'view'" @click="clearGeoLocation">{{ $t('Clear Geographic Location') }}</f7-actions-button>
</f7-actions-group>
<f7-actions-group>
<f7-actions-button :class="{ 'disabled': !transaction.geoLocation }" @click="showGeoLocationMapSheet = true">{{ $t('Show on the map') }}</f7-actions-button>
</f7-actions-group>
<f7-actions-group>
<f7-actions-button bold close>{{ $t('Cancel') }}</f7-actions-button>
</f7-actions-group>
@@ -372,6 +385,7 @@ export default {
showSourceAccountSheet: false,
showDestinationAccountSheet: false,
showTransactionDateTimeSheet: false,
showGeoLocationMapSheet: false,
showTransactionTagSheet: false
};
},