diff --git a/.env.example b/.env.example index 3edc37b..b179561 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,2 @@ VUE_APP_BASE_URL=https://staging.disfactory.tw/api +VUE_APP_IMGUR_FALLBACK_URL=https://api.disfactory.tw/imgur diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 662ce18..4e64fae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,6 +66,7 @@ jobs: run: | npm ci echo "VUE_APP_BASE_URL=https://staging.disfactory.tw/api" > .env + echo "VUE_APP_IMGUR_FALLBACK_URL=https://staging.disfactory.tw/imgur" >> .env npm run build - name: Deploy to GitHub Pages uses: JamesIves/github-pages-deploy-action@3.7.1 @@ -95,6 +96,7 @@ jobs: run: | npm ci echo "VUE_APP_BASE_URL=https://api.disfactory.tw/api" > .env.production + echo "VUE_APP_IMGUR_FALLBACK_URL=https://api.disfactory.tw/imgur" >> .env.production npm run build echo "disfactory.tw" > dist/CNAME - name: Deploy to GitHub Pages diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1672c35 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Disfactory Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/components/DisplaySettingBottomSheet.vue b/src/components/DisplaySettingBottomSheet.vue index a02d98b..af54d71 100644 --- a/src/components/DisplaySettingBottomSheet.vue +++ b/src/components/DisplaySettingBottomSheet.vue @@ -1,39 +1,94 @@ + + diff --git a/src/components/FactoryDetailPage.vue b/src/components/FactoryDetailPage.vue index cc0ffc0..4835ba4 100644 --- a/src/components/FactoryDetailPage.vue +++ b/src/components/FactoryDetailPage.vue @@ -56,7 +56,7 @@ - + @@ -145,9 +145,13 @@ import { getFactoryReportRecords } from '@/api' import { useAppState } from '../lib/appState' import { FactoryImage, getDisplayStatusText, ReportRecord } from '../types' +import ImgurFallbackImage from './ImgurFallbackImage.vue' export default createComponent({ name: 'FactoryDetailPage', + components: { + ImgurFallbackImage + }, setup () { const [appState, { pageTransition, expandFactoryDetail, collapseFactoryDetail, toggleFactoryDetail }] = useAppState() diff --git a/src/components/ImgurFallbackImage.vue b/src/components/ImgurFallbackImage.vue new file mode 100644 index 0000000..0897247 --- /dev/null +++ b/src/components/ImgurFallbackImage.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/lib/map.ts b/src/lib/map.ts index d394495..5119d0d 100644 --- a/src/lib/map.ts +++ b/src/lib/map.ts @@ -22,6 +22,7 @@ import MVT from 'ol/format/MVT' import VectorTileRenderType from 'ol/layer/VectorTileRenderType' import stylefunction from 'ol-mapbox-style/dist/stylefunction' import { baseStyle } from './layerStyle' +import FactoryPointCache from './utils/factoryPointCache' const getFactoryStatusImage = (status: FactoryDisplayStatusType) => `/images/marker-${status}.svg` export const getStatusBorderColor = (status: FactoryDisplayStatusType) => { @@ -140,10 +141,11 @@ export class MapFactoryController { style: (feature, resolution) => { const zoom = this.mapInstance.map.getView().getZoom()! + const clusterDistance = clusterSource.getDistance() if (zoom > 16) { - if (clusterSource.getDistance() !== 0) clusterSource.setDistance(0) + if (clusterDistance !== 0) clusterSource.setDistance(0) } else { - if (clusterSource.getDistance() !== CLUSTER_DISTANCE) clusterSource.setDistance(CLUSTER_DISTANCE) + if (clusterDistance !== CLUSTER_DISTANCE) clusterSource.setDistance(CLUSTER_DISTANCE) } const features = feature.get('features') @@ -218,7 +220,7 @@ export class MapFactoryController { } }) - const features = factoriesToAdd.map(createFactoryFeature) + const features = factoriesToAdd.map(createFactoryFeature).filter(Boolean) as Feature[] interface FeatureFactoryStatusMap { [key: string]: Feature[] } @@ -260,6 +262,11 @@ export class MapFactoryController { } private createFactoryFeature (factory: FactoryData) { + const existingFeature = FactoryPointCache.getFactoryCache(factory) + if (existingFeature) { + return null + } + const feature = new Feature({ geometry: new Point(transform([factory.lng, factory.lat], 'EPSG:4326', 'EPSG:3857')) }) @@ -272,6 +279,8 @@ export class MapFactoryController { this.factoryMap.set(factory.id, factory) + FactoryPointCache.setFactoryCache(factory, feature) + return feature } diff --git a/src/lib/utils/factoryPointCache.ts b/src/lib/utils/factoryPointCache.ts new file mode 100644 index 0000000..df0b372 --- /dev/null +++ b/src/lib/utils/factoryPointCache.ts @@ -0,0 +1,19 @@ +import { FactoryData } from '@/types' +import Feature from 'ol/Feature' + +const featurePointCachedByCoord = new Map() +export class FactoryPointCache { + static getFactoryCacheKey (factory: FactoryData) { + return `${factory.lat},${factory.lng}` + } + + static getFactoryCache (factory: FactoryData) { + return featurePointCachedByCoord.get(this.getFactoryCacheKey(factory)) + } + + static setFactoryCache (factory: FactoryData, feature: Feature) { + featurePointCachedByCoord.set(this.getFactoryCacheKey(factory), feature) + } +} + +export default FactoryPointCache