Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/update grouped images #100

Merged
merged 14 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/components/ImageDisplay/ControlRoomImages.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<thumbnail-row
class="data-thumbs"
:images="recent_images"
:grouped_images="grouped_images"
:selected_image="current_image.image_id"
@thumbnailClicked="set_current_image"
/>
Expand Down
37 changes: 7 additions & 30 deletions src/components/ImageDisplay/ThumbnailRow.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
<template>
<div
v-if="grouped_images.imageGroups && Object.keys(grouped_images.imageGroups).length > 0"
class="images"
>
<div class="images">
<img
v-for="(item, SMARTSTK) in grouped_images.imageGroups"
:key="SMARTSTK"
v-for="(item, index) in images"
:key="index"
:src="thumbnailWithFallback(item)"
onerror="this.onerror=null;this.src='https://via.placeholder.com/60/FF0000/FFFFFF?text=jpg'"
:title="item[0].baseFilename"
:class="{'selected_thumbnail' : item[0].image_id == selected_image}"
:title="item.base_filename"
:class="{'selected_thumbnail' : item.image_id == selected_image}"
loading="lazy"
class="recent-image"
@click="setActiveImage(item[0])"
>
</div>
<div
v-else
class="placeholder"
>
<img
:src="'https://via.placeholder.com/768?text=no+jpg+preview+available'"
class="recent-image"
@click="setActiveImage(item)"
>
</div>
</template>
Expand All @@ -38,25 +26,14 @@ export default {
selected_image: {
type: Number,
required: false
},
grouped_images: {
type: Object,
default: () => {},
required: true
}
},

methods: {
setActiveImage (item) {
this.$emit('thumbnailClicked', item)
},

thumbnailWithFallback (item) {
let thumbnailCover = item && item[0] && item[0].jpg_thumbnail_url
if (!thumbnailCover) {
thumbnailCover = item && item[0] && item[0].jpg_url
}
return thumbnailCover || 'https://via.placeholder.com/768?text=no+jpg+preview+available'
return item.jpg_thumbnail_url || item.jpg_url
}
}
}
Expand Down
6 changes: 2 additions & 4 deletions src/components/sitepages/SiteData.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
/>
<thumbnail-row
class="data-thumbs"
:images="recent_images"
:grouped_images="grouped_images"
:images="$store.getters['images/recent_images_condensed']"
:selected_image="current_image.image_id"
@thumbnailClicked="setActiveImage"
/>
Expand Down Expand Up @@ -385,8 +384,7 @@ export default {

...mapState('images', [
'recent_images',
'current_image',
'grouped_images'
'current_image'
]),

...mapGetters('images', [
Expand Down
99 changes: 23 additions & 76 deletions src/store/modules/images.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ const state = {
// TODO: Write an action that will update a user's image list when images are added to their account
user_images: [],

// grouped_images: object where images are grouped based on their SMARTSTK value
// Before the action group_images, there's an example of what this object looks like after being populated
grouped_images: {},

show_user_data_only: false,

// determines whether 'current_images' is set to show the most recent images with live updates.
Expand All @@ -59,7 +55,29 @@ const getters = {
current_image: state => state.current_image,
recent_images: state => state.recent_images,
user_images: state => state.user_images,
grouped_images: state => state.grouped_images,
// Uses recent_images but removes any intermediate smartstack frames, so you only see the latest version of each smart stack
recent_images_condensed: state => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be helpful to include a comment describing an overview of what this getter is doing, something along the lines of 'Same as recent_images but removes any intermediate smartstack frames, so you only see the latest version of each smart stack'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Added comment!

// First, generate a map of maximum SSTKNUM for each SMARTSTK
const maxSSTKNUMs = state.recent_images.reduce((acc, cur) => {
if (!cur.header || !cur.header.SMARTSTK || !cur.header.SSTKNUM) return acc // Skip if missing header, SMARTSTK or SSTKNUM

const num = parseInt(cur.header.SSTKNUM) // convert string to number
if (!acc[cur.header.SMARTSTK] || num > acc[cur.header.SMARTSTK]) {
acc[cur.header.SMARTSTK] = num
}
return acc
}, {})

// Now, filter the original array
const filteredArr = state.recent_images.filter(el => {
// Keep if missing header, SMARTSTK or SSTKNUM
if (!el.header || !el.header.SMARTSTK || !el.header.SSTKNUM) return true

// Keep if SSTKNUM is the maximum for its SMARTSTK
return el.header.SSTKNUM >= maxSSTKNUMs[el.header.SMARTSTK]
})
return filteredArr
},
show_user_data_only: state => state.show_user_data_only,

current_image_fits_header: state => state.current_image.fits_header,
Expand All @@ -85,7 +103,6 @@ const getters = {
const mutations = {
setCurrentImage (state, the_current_image) { state.current_image = the_current_image },
setRecentImages (state, recent_image_list) { state.recent_images = recent_image_list },
setGroupedImages (state, grouped_images) { state.grouped_images = grouped_images },
setUserImages (state, user_images_list) { state.user_images = user_images_list },
show_user_data_only (state, val) { state.show_user_data_only = val },
live_data (state, val) { state.live_data = val },
Expand Down Expand Up @@ -173,16 +190,12 @@ const actions = {

// If it doesn't already exist, just add it to the array (front).
if (old_image_index == -1) {
console.log('old')
const updated_recent_images = [new_image, ...recent_images]
commit('setRecentImages', updated_recent_images)
dispatch('group_images')
}
// Otherwise, replace the old version with the new one we fetched.
else {
console.log('new image')
recent_images[old_image_index] = new_image
dispatch('group_images')
}

// We don't have a toggle implemented yet.
Expand Down Expand Up @@ -251,7 +264,6 @@ const actions = {
}

commit('setRecentImages', response)
dispatch('group_images')
}).catch(error => {
console.warn(error)
})
Expand All @@ -262,64 +274,7 @@ const actions = {
@param {boolean} user_data_only: whether or not to filter by images
Taken the active user or not.

Grouping images as they load and we group them based on their SMARTSTK value
After the for loop, the grouped_images_local looks something like this:
grouped_images_local: {
site: 'tst',
imageGroups: {
1234: [...grouped images...],
5678: [...grouped images...],
9012: [...grouped images...]
}
}
*/
group_images ({ commit, state, rootState, dispatch }) {
const currentSite = rootState.site_config.selected_site
let grouped_images_local = JSON.parse(JSON.stringify(state.grouped_images))
if (!grouped_images_local.imageGroups) {
grouped_images_local.imageGroups = {}
}
const recent_images = state.recent_images

// Resetting grouped_images to an empty object when selecting a different site
// This prevents accumulation of thumbnails from previous sites selected by user
if (grouped_images_local.site && grouped_images_local.site !== currentSite) {
dispatch('reset_grouped_images')
grouped_images_local = { site: currentSite }

// If grouped_images_local object doesn't have a key of site (i.e. when page first loads and when user selects
// a different site), assign the value of currentSite to the new key of site
} else if (!grouped_images_local.site) {
grouped_images_local.site = currentSite
}

for (const img of recent_images) {
const header = img && img.header
let SMARTSTK = header && header.SMARTSTK
// Creating a unique key (i.e. base_filename) for images where SMARTSK is 'no' while also avoiding grouping them as one stack
// We need this in order to display these images as thumbnails
if (SMARTSTK === 'no') {
SMARTSTK = img && img.base_filename
grouped_images_local.imageGroups[SMARTSTK] = []
grouped_images_local.imageGroups[SMARTSTK].push(img)
}

// Grouping images based on SMARTSTK
if (!grouped_images_local.imageGroups[SMARTSTK]) {
grouped_images_local.imageGroups[SMARTSTK] = []
grouped_images_local.imageGroups[SMARTSTK].push(img)
} else {
grouped_images_local.imageGroups[SMARTSTK].push(img)
}
}
commit('setGroupedImages', { ...grouped_images_local })
},

// Resets grouped_images to an empty object
// Dispatched when a different site is selected
reset_grouped_images ({ commit }) {
commit('setGroupedImages', {})
},

async load_latest_x_images ({ dispatch, commit, state, rootState }, num_images) {
// Old method of loading only a certain amount of images
Expand Down Expand Up @@ -356,7 +311,6 @@ const actions = {

commit('setCurrentImage', response[0])
commit('setRecentImages', response)
dispatch('group_images')
}).catch(error => {
console.error(error)
})
Expand Down Expand Up @@ -486,7 +440,6 @@ const actions = {

commit('setCurrentImage', response[0])
commit('setRecentImages', response)
dispatch('group_images')
}).catch(error => {
console.error(error)
})
Expand Down Expand Up @@ -563,7 +516,6 @@ const actions = {
}
commit('setRecentImages', [placeholder_image])
commit('setCurrentImage', placeholder_image)
dispatch('reset_grouped_images')
},

// Set this_image as the current displayed image
Expand Down Expand Up @@ -602,11 +554,6 @@ const actions = {
commit('setCurrentImage', first_image)
},

set_grouped_images ({ commit, state }) {
const grouped_images_local = state.grouped_images
commit('setGroupedImages', { ...grouped_images_local })
},

async get_fits_url ({ rootState }, { base_filename, data_type, reduction_level }) {
// Get the global configuration for all sites from an api call.
const apiName = rootState.api_endpoints.active_api
Expand Down
Loading