Skip to content

Commit

Permalink
Merge branch 'feature/timeline-and-improvements' into feature/deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
wvandrunen authored Feb 26, 2024
2 parents 32fc253 + 1ac37a3 commit b17b2a5
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 42 deletions.
46 changes: 23 additions & 23 deletions src/common/apiSchema/present.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { BaseView, BaseDataEntity, BaseSliderEntry, ImageRef } from "./shared";
import { BaseView, BaseDataEntity, BaseSliderEntry, ImageRef } from './shared';

export type GeoLevel = "straat" | "buurt" | "wijk" | "stadsdeel";
export type GeoLevel = 'straat' | 'buurt' | 'wijk' | 'stadsdeel';

export type PresentEntityType =
| "outdoorArt"
| "cultureMulti"
| "musicVenue"
| "heritage"
| "dance"
| "visualArts"
| "photography"
| "cinema"
| "literary"
| "creativeIndustries"
| "theatre"
| "TVandRadio"
| "architecture"
| "newMedia"
| "debate"
| "aggregate_trees"
| "aggregate_tree_species"
| "aggregate_bees";
| 'outdoorArt'
| 'cultureMulti'
| 'musicVenue'
| 'heritage'
| 'dance'
| 'visualArts'
| 'photography'
| 'cinema'
| 'literary'
| 'creativeIndustries'
| 'theatre'
| 'TVandRadio'
| 'architecture'
| 'newMedia'
| 'debate'
| 'aggregate_trees'
| 'aggregate_tree_species'
| 'aggregate_bees';

export interface PresentData extends BaseView {
slider: (DistanceViewEntry | DistanceViewAggregateEntry)[]; // The entries for on the slider
Expand All @@ -35,9 +35,9 @@ export interface DistanceViewEntry extends BaseSliderEntry {
}

export interface DistanceViewAggregateEntry
extends Omit<DistanceViewEntry, "image" | "visitUrl"> {
data: Record<string, number>; // The data for the aggregate, where the key is the name of the buurt, wijk, stadsdeel etc.
type: "aggregate_trees" | "aggregate_tree_species" | "aggregate_bees";
extends Omit<DistanceViewEntry, 'image' | 'visitUrl'> {
data: { areaName: string; count: number };
type: 'aggregate_trees' | 'aggregate_tree_species' | 'aggregate_bees';
}

export interface AgendaItem extends BaseDataEntity {
Expand Down
19 changes: 19 additions & 0 deletions src/frontend/components/UI/AnimatedView/AnimatedView.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Meta, StoryFn } from '@storybook/vue3'

import AnimatedView, { AnimatedViewProps } from './index.vue'

export default {
title: 'UI/Ui/AnimatedView',
component: AnimatedView,
} as Meta<typeof AnimatedView>

const Template: StoryFn<typeof AnimatedView> = (args: AnimatedViewProps) => ({
components: { AnimatedView },
setup() {
return { args }
},
template: '<AnimatedView v-bind="args" />',
})

export const AnimatedViewStory = Template.bind({})
AnimatedViewStory.args = {}
14 changes: 14 additions & 0 deletions src/frontend/components/UI/AnimatedView/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
// TODO
</template>

<script setup lang="ts">
export interface AnimatedViewProps {
// TODO
};
const props = defineProps<AnimatedViewProps>()
</script>

<style lang="less" scoped>
</style>
26 changes: 20 additions & 6 deletions src/frontend/components/UI/ListView/index.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<template>
<div v-if="entries" class="entry-list">
<div v-for="(entry, index) in entries" :key="index" class="entry-wrapper">
<div
v-for="(entry, index) in entries"
:id="getId(entry)"
:key="index"
class="entry-wrapper"
>
<div class="card-wrapper">
<SharedAggregateCard
v-if="entryIsAggregate(entry)"
:type="entry.type as AggregateType"
:count="getAggregateCount(entry as DistanceViewAggregateEntry)"
:count="(entry as DistanceViewAggregateEntry).data.count"
/>
</div>
<SharedImage
Expand Down Expand Up @@ -49,6 +54,19 @@ export interface ListViewProps {
const props = defineProps<ListViewProps>()
let lastId: number | null = null
const getId = (
entry: TimelineEntry | DistanceViewAggregateEntry | DistanceViewEntry,
) => {
if (entry.position === lastId) {
return undefined
} else {
lastId = entry.position
return lastId.toString()
}
}
const entryIsAggregate = (
entry: DistanceViewEntry | DistanceViewAggregateEntry | TimelineEntry,
) => {
Expand All @@ -58,10 +76,6 @@ const entryIsAggregate = (
entry.type === 'aggregate_bees'
)
}
const getAggregateCount = (entry: DistanceViewAggregateEntry) => {
return entry.data[Object.keys(entry.data)[0]]
}
</script>

<style lang="less" scoped>
Expand Down
7 changes: 6 additions & 1 deletion src/frontend/components/shared/Slider/Slider.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ const Template: StoryFn<typeof Slider> = (args: SliderProps) => ({
})

export const SliderStory = Template.bind({})
SliderStory.args = {}
SliderStory.args = {
positions: [100, 0],
rangeMax: 100,
rangeMin: 0,
isDistanceView: true,
}
82 changes: 73 additions & 9 deletions src/frontend/components/shared/Slider/index.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,84 @@
<template>
<div class="slider">
<div class="pointer">
<div class="pointer-label">
<SharedTypography variant="body-small" :compact="true">
1900
</SharedTypography>
<TransitionFade>
<div v-if="!loading" class="slider">
<div :style="cssProp" class="pointer">
<div class="pointer-label">
<SharedTypography variant="body-small" :compact="true">
{{ currentPosition + (isDistanceView ? 'm' : '') }}
</SharedTypography>
</div>
</div>
</div>
</div>
</TransitionFade>
</template>

<script setup lang="ts">
import gsap from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import { getPercentageInRange } from '@/utils/timelineUtils'
gsap.registerPlugin(ScrollTrigger)
const props = defineProps<SliderProps>()
export interface SliderProps {
// TODO
positions: number[] // the positions correspond with the ids of the entries
rangeMax: number
rangeMin: number
isDistanceView?: boolean
}
const props = defineProps<SliderProps>()
const currentPosition = ref(props.rangeMax)
const loading = ref(true)
const cssProp = computed(() => {
const percentage = getPercentageInRange(
props.rangeMax,
props.rangeMin,
currentPosition.value,
)
return `top: calc(${props.isDistanceView ? percentage : 100 - percentage}% - 12px)`
})
// TODO: implement this
// const areImagesLoaded = () => {
// const images = document.getElementsByTagName('img')
// for (let i = 0; i < images.length; i++) {
// if (!images[i].complete) {
// return false
// }
// }
// return true
// }
const setAnimation = () => {
// TODO: make this not timeout but event based
loading.value = true
ScrollTrigger.killAll()
currentPosition.value = props.rangeMax
setTimeout(() => {
props.positions.forEach((position, index) => {
ScrollTrigger.create({
trigger: `[id="${position}"]`,
start: 'top 10%',
end: 'top 10%',
onEnter: () => {
currentPosition.value = position
},
onLeaveBack: () => {
currentPosition.value = props.positions[index - 1]
},
})
})
loading.value = false
}, 1000)
}
onMounted(setAnimation)
watch(() => props.positions, setAnimation)
</script>

<style lang="less" scoped>
Expand All @@ -34,6 +97,7 @@ const props = defineProps<SliderProps>()
height: 12px;
background: @primary-black;
border-radius: 50%;
transition: top 0.5s;
transform: translateX(-50%);
}
Expand Down
1 change: 1 addition & 0 deletions src/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@pinia/nuxt": "^0.5.1",
"date-fns": "^3.3.1",
"gsap": "^3.12.5",
"lodash.uniq": "^4.5.0",
"nuxt": "^3.10.1",
"pinia": "^2.1.7",
"slugify": "^1.6.6",
Expand Down
15 changes: 13 additions & 2 deletions src/frontend/pages/[address].vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,19 @@
@click="() => (currentView = 'present')"
/>
</div>
<SharedSlider />
<SharedSlider
v-if="currentDataSet && entries"
:range-max="currentDataSet.rangeEnd"
:range-min="currentDataSet.rangeStart"
:positions="getEntryPositions(entries)"
:is-distance-view="currentView === 'present'"
/>
</div>
</template>

<script setup lang="ts">
import { getTranslationKey } from '@/translations'
import { useAddressStore } from '@/store/addressStore'
defineI18nRoute({
paths: {
Expand All @@ -53,14 +60,18 @@ defineI18nRoute({
const { params } = useRoute()
const { pastData, presentData } = useAddress(params.address as string)
const { pastData, presentData } = useAddressStore(params.address as string)
const currentView: Ref<'present' | 'past'> = ref('past')
const entries = computed(() => {
return currentView.value === 'past'
? pastData.value?.timeline
: presentData.value?.slider
})
const currentDataSet = computed(() => {
return currentView.value === 'past' ? pastData.value : presentData.value
})
</script>

<style lang="less" scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { AddressRecord } from '../../common/apiSchema/addressRecord'

import { PresentData } from '../../common/apiSchema/present'

export const useAddress = (address: string) => {
// TODO: make this a store to prevent lots of requests
export const useAddressStore = (address: string) => {
const addressService = useAddressService()

const addressData: Ref<AddressRecord | null> = ref(null)
Expand Down
25 changes: 25 additions & 0 deletions src/frontend/utils/timelineUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import uniq from 'lodash/uniq'
import { PastData } from '../../common/apiSchema/past'
import { PresentData } from '../../common/apiSchema/present'

export const getEntryPositions = (
entries: PastData['timeline'] | PresentData['slider'],
) => {
return uniq(entries.map((entry) => entry.position))
}

export const getPercentageInRange = (
rangeMax: number,
rangeMin: number,
value: number,
) => {
const result = ((value - rangeMin) / (rangeMax - rangeMin)) * 100

if (result > 100) {
return 100
} else if (result < 0) {
return 0
} else {
return result
}
}

0 comments on commit b17b2a5

Please sign in to comment.