mirror of
https://github.com/nasa/openmct.git
synced 2025-05-03 09:12:51 +00:00
Imagery thumbnail regression fixes - 5327 (#5569)
* Add an active class to thumbnail to indicate current focused image * Differentiate bg color between real-time and fixed * scrollIntoView inline: center * Added watcher for bounds change to trigger thumbnail scroll * Resolve merge conflict with requestHistory change to telemetry collection * Split thumbnail into sub component * Monitor isFixed value to unpause playback status
This commit is contained in:
parent
f2ed518300
commit
f1c85933c3
68
src/plugins/imagery/components/ImageThumbnail.vue
Normal file
68
src/plugins/imagery/components/ImageThumbnail.vue
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<!--
|
||||||
|
Open MCT, Copyright (c) 2014-2022, United States Government
|
||||||
|
as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
Administration. All rights reserved.
|
||||||
|
|
||||||
|
Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
Open MCT includes source code licensed under additional open source
|
||||||
|
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
this source code distribution or the Licensing information page available
|
||||||
|
at runtime from the About dialog for additional information.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="c-imagery__thumb c-thumb"
|
||||||
|
:class="{
|
||||||
|
'active': active,
|
||||||
|
'selected': selected,
|
||||||
|
'real-time': realTime
|
||||||
|
}"
|
||||||
|
:title="image.formattedTime"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href=""
|
||||||
|
:download="image.imageDownloadName"
|
||||||
|
@click.prevent
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="c-thumb__image"
|
||||||
|
:src="image.url"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
<div class="c-thumb__timestamp">{{ image.formattedTime }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
image: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
realTime: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -166,26 +166,15 @@
|
|||||||
class="c-imagery__thumbs-scroll-area"
|
class="c-imagery__thumbs-scroll-area"
|
||||||
@scroll="handleScroll"
|
@scroll="handleScroll"
|
||||||
>
|
>
|
||||||
<div
|
<ImageThumbnail
|
||||||
v-for="(image, index) in imageHistory"
|
v-for="(image, index) in imageHistory"
|
||||||
:key="image.url + image.time"
|
:key="image.url + image.time"
|
||||||
class="c-imagery__thumb c-thumb"
|
:image="image"
|
||||||
:class="{ selected: focusedImageIndex === index && isPaused }"
|
:active="focusedImageIndex === index"
|
||||||
:title="image.formattedTime"
|
:selected="focusedImageIndex === index && isPaused"
|
||||||
@click="thumbnailClicked(index)"
|
:real-time="!isFixed"
|
||||||
>
|
@click.native="thumbnailClicked(index)"
|
||||||
<a
|
/>
|
||||||
href=""
|
|
||||||
:download="image.imageDownloadName"
|
|
||||||
@click.prevent
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
class="c-thumb__image"
|
|
||||||
:src="image.url"
|
|
||||||
>
|
|
||||||
</a>
|
|
||||||
<div class="c-thumb__timestamp">{{ image.formattedTime }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@ -205,6 +194,7 @@ import moment from 'moment';
|
|||||||
import RelatedTelemetry from './RelatedTelemetry/RelatedTelemetry';
|
import RelatedTelemetry from './RelatedTelemetry/RelatedTelemetry';
|
||||||
import Compass from './Compass/Compass.vue';
|
import Compass from './Compass/Compass.vue';
|
||||||
import ImageControls from './ImageControls.vue';
|
import ImageControls from './ImageControls.vue';
|
||||||
|
import ImageThumbnail from './ImageThumbnail.vue';
|
||||||
import imageryData from "../../imagery/mixins/imageryData";
|
import imageryData from "../../imagery/mixins/imageryData";
|
||||||
|
|
||||||
const REFRESH_CSS_MS = 500;
|
const REFRESH_CSS_MS = 500;
|
||||||
@ -229,9 +219,11 @@ const SHOW_THUMBS_THRESHOLD_HEIGHT = 200;
|
|||||||
const SHOW_THUMBS_FULLSIZE_THRESHOLD_HEIGHT = 600;
|
const SHOW_THUMBS_FULLSIZE_THRESHOLD_HEIGHT = 600;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'ImageryView',
|
||||||
components: {
|
components: {
|
||||||
Compass,
|
Compass,
|
||||||
ImageControls
|
ImageControls,
|
||||||
|
ImageThumbnail
|
||||||
},
|
},
|
||||||
mixins: [imageryData],
|
mixins: [imageryData],
|
||||||
inject: ['openmct', 'domainObject', 'objectPath', 'currentView', 'imageFreshnessOptions'],
|
inject: ['openmct', 'domainObject', 'objectPath', 'currentView', 'imageFreshnessOptions'],
|
||||||
@ -254,6 +246,7 @@ export default {
|
|||||||
visibleLayers: [],
|
visibleLayers: [],
|
||||||
durationFormatter: undefined,
|
durationFormatter: undefined,
|
||||||
imageHistory: [],
|
imageHistory: [],
|
||||||
|
bounds: {},
|
||||||
timeSystem: timeSystem,
|
timeSystem: timeSystem,
|
||||||
keyString: undefined,
|
keyString: undefined,
|
||||||
autoScroll: true,
|
autoScroll: true,
|
||||||
@ -569,6 +562,16 @@ export default {
|
|||||||
this.resetAgeCSS();
|
this.resetAgeCSS();
|
||||||
this.updateRelatedTelemetryForFocusedImage();
|
this.updateRelatedTelemetryForFocusedImage();
|
||||||
this.getImageNaturalDimensions();
|
this.getImageNaturalDimensions();
|
||||||
|
},
|
||||||
|
bounds() {
|
||||||
|
this.scrollToFocused();
|
||||||
|
},
|
||||||
|
isFixed(newValue) {
|
||||||
|
const isRealTime = !newValue;
|
||||||
|
// if realtime unpause which will focus on latest image
|
||||||
|
if (isRealTime) {
|
||||||
|
this.paused(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
@ -610,6 +613,7 @@ export default {
|
|||||||
this.handleScroll = _.debounce(this.handleScroll, SCROLL_LATENCY);
|
this.handleScroll = _.debounce(this.handleScroll, SCROLL_LATENCY);
|
||||||
this.handleThumbWindowResizeEnded = _.debounce(this.handleThumbWindowResizeEnded, SCROLL_LATENCY);
|
this.handleThumbWindowResizeEnded = _.debounce(this.handleThumbWindowResizeEnded, SCROLL_LATENCY);
|
||||||
this.handleThumbWindowResizeStart = _.debounce(this.handleThumbWindowResizeStart, SCROLL_LATENCY);
|
this.handleThumbWindowResizeStart = _.debounce(this.handleThumbWindowResizeStart, SCROLL_LATENCY);
|
||||||
|
this.scrollToFocused = _.debounce(this.scrollToFocused, 400);
|
||||||
|
|
||||||
if (this.$refs.thumbsWrapper) {
|
if (this.$refs.thumbsWrapper) {
|
||||||
this.thumbWrapperResizeObserver = new ResizeObserver(this.handleThumbWindowResizeStart);
|
this.thumbWrapperResizeObserver = new ResizeObserver(this.handleThumbWindowResizeStart);
|
||||||
@ -845,7 +849,8 @@ export default {
|
|||||||
if (domThumb) {
|
if (domThumb) {
|
||||||
domThumb.scrollIntoView({
|
domThumb.scrollIntoView({
|
||||||
behavior: 'smooth',
|
behavior: 'smooth',
|
||||||
block: 'center'
|
block: 'center',
|
||||||
|
inline: 'center'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -258,13 +258,22 @@
|
|||||||
min-width: $w;
|
min-width: $w;
|
||||||
width: $w;
|
width: $w;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: $colorSelectedBg;
|
||||||
|
color: $colorSelectedFg;
|
||||||
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $colorThumbHoverBg;
|
background: $colorThumbHoverBg;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
background: $colorPausedBg !important;
|
// fixed time - selected bg will match active bg color
|
||||||
color: $colorPausedFg !important;
|
background: $colorSelectedBg;
|
||||||
|
color: $colorSelectedFg;
|
||||||
|
&.real-time {
|
||||||
|
// real time - bg orange when selected
|
||||||
|
background: $colorPausedBg !important;
|
||||||
|
color: $colorPausedFg !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__image {
|
&__image {
|
||||||
|
@ -139,6 +139,7 @@ export default {
|
|||||||
// forcibly reset the imageContainer size to prevent an aspect ratio distortion
|
// forcibly reset the imageContainer size to prevent an aspect ratio distortion
|
||||||
delete this.imageContainerWidth;
|
delete this.imageContainerWidth;
|
||||||
delete this.imageContainerHeight;
|
delete this.imageContainerHeight;
|
||||||
|
this.bounds = bounds; // setting bounds for ImageryView watcher
|
||||||
},
|
},
|
||||||
timeSystemChange() {
|
timeSystemChange() {
|
||||||
this.timeSystem = this.timeContext.timeSystem();
|
this.timeSystem = this.timeContext.timeSystem();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user