mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-15 00:03:28 +01:00
vueui: add highlighting for current snapshot and its parent period to both timeline and calendar full-view/linear-view
This commit is contained in:
parent
ed3ed1281d
commit
2ac83c61fd
File diff suppressed because one or more lines are too long
@ -38,7 +38,7 @@
|
||||
<div>{{ config.url }}</div>
|
||||
<div v-if="currentSnapshot && !showFullView">
|
||||
<span v-if="config.title">{{ config.title }}</span>
|
||||
{{currentSnapshot.getTimeDateFormatted()}}
|
||||
Current capture: {{currentSnapshot.getTimeDateFormatted()}}
|
||||
</div>
|
||||
</div>
|
||||
<CalendarYear v-if="showFullView"
|
||||
|
@ -17,6 +17,9 @@
|
||||
background-color: #fff7ce;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.calendar-month.contains-current-snapshot {
|
||||
border: solid 1px red;
|
||||
}
|
||||
.calendar-month > h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
@ -59,6 +62,10 @@
|
||||
background-color: rgba(166, 205, 245, .85);
|
||||
z-index: 10;
|
||||
}
|
||||
.calendar-month .day.contains-current-snapshot .size {
|
||||
background-color: rgba(255, 100, 100, .85);
|
||||
}
|
||||
|
||||
.calendar-month .day .day-id {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -83,19 +90,21 @@
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<div class="calendar-month" :class="{current: isCurrent}">
|
||||
<div class="calendar-month" :class="{current: isCurrent, 'contains-current-snapshot': containsCurrentSnapshot}">
|
||||
<h3>{{month.getReadableId()}} <span v-if="month.snapshotCount">({{ month.snapshotCount }})</span></h3>
|
||||
<div v-if="month.snapshotCount">
|
||||
<span v-for="(day) in ['S', 'M', 'T', 'W', 'H', 'F', 'S']" class="day" :style="dayStyle">{{day}}</span><br/>
|
||||
<span v-for="(day,i) in days"><br v-if="i && i % 7===0"/><span class="day" :class="{empty: !day || !day.snapshotCount}" :style="dayStyle" @click="gotoDay(day, $event)"><template v-if="day"><span class="size" v-if="day.snapshotCount" :style="getDayCountCircleStyle(day.snapshotCount)"> </span><span class="day-id">{{day.id}}</span><span v-if="day.snapshotCount" class="count">{{day.snapshotCount}} capture<span v-if="day.snapshotCount!==1">s</span></span></template><template v-else v-html="' '"></template></span></span>
|
||||
<span v-for="(day,i) in days"><br v-if="i && i % 7===0"/><span class="day" :class="{empty: !day || !day.snapshotCount, 'contains-current-snapshot':dayContainsCurrentSnapshot(day)}" :style="dayStyle" @click="gotoDay(day, $event)"><template v-if="day"><span class="size" v-if="day.snapshotCount" :style="getDayCountCircleStyle(day.snapshotCount)"> </span><span class="day-id">{{day.id}}</span><span v-if="day.snapshotCount" class="count">{{day.snapshotCount}} capture<span v-if="day.snapshotCount!==1">s</span></span></template><template v-else v-html="' '"></template></span></span>
|
||||
</div>
|
||||
<div v-else class="empty">no captures</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {PywbPeriod} from "../model";
|
||||
|
||||
export default {
|
||||
props: ["month", "year", "isCurrent", "hasCurrentSnapshot"],
|
||||
props: ["month", "year", "isCurrent", "yearContainsCurrentSnapshot", "currentSnapshot"],
|
||||
data: function() {
|
||||
return {
|
||||
maxInDay: 0,
|
||||
@ -127,6 +136,10 @@ export default {
|
||||
days.push(null);
|
||||
}
|
||||
return days;
|
||||
},
|
||||
containsCurrentSnapshot() {
|
||||
return this.currentSnapshot &&
|
||||
this.month.contains(this.currentSnapshot);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -150,6 +163,9 @@ export default {
|
||||
// background-color: hsl(${scaledColorHue}, 100%, 50%, .2)
|
||||
|
||||
return `width: ${scaledSize}px; height: ${scaledSize}px; top: ${margin}px; left: ${margin}px; border-radius: ${scaledSize/2}px;`;
|
||||
},
|
||||
dayContainsCurrentSnapshot(day) {
|
||||
return !!day && day.snapshotCount > 0 && this.containsCurrentSnapshot && day.contains(this.currentSnapshot);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -30,8 +30,8 @@
|
||||
:key="month.id"
|
||||
:month="month"
|
||||
:year="year"
|
||||
:current-snapshot="containsCurrentSnapshot ? currentSnapshot : null"
|
||||
:is-current="month === currentMonth"
|
||||
:has-current-snapshot="month === currentMonth"
|
||||
@goto-period="$emit('goto-period', $event)"
|
||||
@show-day-timeline="setCurrentTimeline"
|
||||
></CalendarMonth>
|
||||
@ -39,6 +39,7 @@
|
||||
<Tooltip :position="currentTimelinePos" v-if="currentTimelinePeriod" ref="timelineLinearTooltip">
|
||||
<TimelineLinear
|
||||
:period="currentTimelinePeriod"
|
||||
:current-snapshot="containsCurrentSnapshot ? currentSnapshot : null"
|
||||
@goto-period="gotoPeriod"
|
||||
></TimelineLinear>
|
||||
</Tooltip>
|
||||
@ -67,9 +68,14 @@ export default {
|
||||
computed: {
|
||||
year() { // the year that the timeline period is in
|
||||
let year = null;
|
||||
// if timeline is showing all year
|
||||
if (this.period.type === PywbPeriod.Type.all) {
|
||||
// if timeline is showing all year => pick the LAST YEAR
|
||||
year = this.period.children[this.period.children.length-1];
|
||||
// if no current snapshot => pick the LAST YEAR
|
||||
if (!this.currentSnapshot) {
|
||||
year = this.period.children[this.period.children.length-1];
|
||||
} else {
|
||||
year = this.period.findByFullId(String(this.currentSnapshot.year));
|
||||
}
|
||||
} else if (this.period.type === PywbPeriod.Type.year) {
|
||||
year = this.period;
|
||||
} else {
|
||||
@ -88,6 +94,10 @@ export default {
|
||||
month = this.period.getParents().filter(p => p.type === PywbPeriod.Type.month)[0];
|
||||
}
|
||||
return month;
|
||||
},
|
||||
containsCurrentSnapshot() {
|
||||
return this.currentSnapshot &&
|
||||
this.year.contains(this.currentSnapshot);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -21,14 +21,14 @@
|
||||
<div v-for="subPeriod in period.children"
|
||||
:key="subPeriod.id"
|
||||
class="period"
|
||||
:class="{empty: !subPeriod.snapshotCount, highlight: highlightPeriod === subPeriod, 'last-level': !canZoom}"
|
||||
:class="{empty: !subPeriod.snapshotCount, highlight: highlightPeriod === subPeriod, 'last-level': !canZoom, 'contains-current-snapshot': containsCurrentSnapshot(subPeriod) }"
|
||||
>
|
||||
<div class="histo">
|
||||
<div class="line"
|
||||
v-for="histoPeriod in subPeriod.children"
|
||||
:key="histoPeriod.id"
|
||||
:style="{height: getHistoLineHeight(histoPeriod.snapshotCount)}"
|
||||
:class="{'has-single-snapshot': histoPeriod.snapshotCount === 1}"
|
||||
:class="{'has-single-snapshot': histoPeriod.snapshotCount === 1, 'contains-current-snapshot': containsCurrentSnapshot(histoPeriod)}"
|
||||
@click="changePeriod(histoPeriod, $event)"
|
||||
@mouseover="setTooltipPeriod(histoPeriod, $event)"
|
||||
@mouseout="setTooltipPeriod(null, $event)"
|
||||
@ -93,12 +93,18 @@ export default{
|
||||
},
|
||||
isTooltipPeriodDayOrHour() {
|
||||
return this.tooltipPeriod.type >= PywbPeriod.Type.day;
|
||||
},
|
||||
iContainCurrentSnapshot() {
|
||||
return this.currentSnapshot && this.period.contains(this.currentSnapshot);
|
||||
}
|
||||
},
|
||||
updated() {
|
||||
// do something on update
|
||||
},
|
||||
methods: {
|
||||
containsCurrentSnapshot(period) {
|
||||
return this.iContainCurrentSnapshot && period.contains(this.currentSnapshot);
|
||||
},
|
||||
addEmptySubPeriods() {
|
||||
this.period.fillEmptyChildPeriods(true);
|
||||
},
|
||||
@ -315,6 +321,9 @@ export default{
|
||||
.timeline .period:hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.timeline .period.contains-current-snapshot, .timeline .period.contains-current-snapshot:hover {
|
||||
background-color: #f7def4;
|
||||
}
|
||||
|
||||
/* empty period */
|
||||
.timeline .period.empty {
|
||||
@ -399,6 +408,10 @@ export default{
|
||||
background-color: #f5a6eb;
|
||||
}
|
||||
|
||||
.timeline .period .histo .line.contains-current-snapshot {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
/* Period that contains ONE snapshot only will show snapshot info*/
|
||||
.timeline .period-tooltip {
|
||||
position: fixed;
|
||||
|
@ -7,7 +7,8 @@
|
||||
|
||||
<div class="list">
|
||||
<div v-for="period in snapshotPeriods">
|
||||
<span class="link" @click="gotoPeriod(period)">{{period.snapshot.getTimeFormatted()}}</span>
|
||||
<span class="link" @click="gotoPeriod(period)" >{{period.snapshot.getTimeFormatted()}}</span>
|
||||
<span v-if="currentSnapshot.id === period.snapshot.id" class="current">current</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -16,10 +17,14 @@
|
||||
<script>
|
||||
export default {
|
||||
name: "TimelineLinear",
|
||||
props: ['period'],
|
||||
props: ['period', 'currentSnapshot'],
|
||||
computed: {
|
||||
snapshotPeriods() {
|
||||
return this.period.getSnapshotPeriodsFlat();
|
||||
},
|
||||
containsCurrentSnapshot() {
|
||||
return this.currentSnapshot &&
|
||||
this.period.contains(this.currentSnapshot);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -56,4 +61,9 @@ export default {
|
||||
color: lightseagreen;
|
||||
cursor: pointer;
|
||||
}
|
||||
.timeline-linear .current {
|
||||
background-color: deeppink;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
@ -64,6 +64,17 @@ class CDXLoader {
|
||||
|
||||
app.$mount("#app");
|
||||
|
||||
// TODO (Ilya): make this work with in-page snapshot/capture/replay updates!
|
||||
// app.$on("show-snapshot", snapshot => {
|
||||
// const replayUrl = app.config.url;
|
||||
// const url = location.href.replace('/'+replayUrl, '').replace(/\d+$/, '') + snapshot.id + '/' + replayUrl;
|
||||
// window.history.pushState({url: replayUrl, timestamp: snapshot.id}, document.title, url);
|
||||
// if (!window.onpopstate) {
|
||||
// window.onpopstate = (ev) => {
|
||||
// updateSnapshot(ev.state.url, ev.state.timestamp);
|
||||
// };
|
||||
// }
|
||||
// });
|
||||
if (loadCallback) {
|
||||
app.$on("show-snapshot", loadCallback);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
const PywbMonthLabels = {1:"Jan", 2:"Feb",3:"Mar",4:"Apr",5:"May",6:"Jun",7:"Jul",8:"Aug",9:"Sep",10:"Oct",11:"Nov",12:"Dec"};
|
||||
|
||||
const PywbPeriodIdDelimiter = '-';
|
||||
export function PywbData(rawSnaps) {
|
||||
const allTimePeriod = new PywbPeriod({type: PywbPeriod.Type.all, id: "all"});
|
||||
const snapshots = [];
|
||||
@ -98,6 +98,14 @@ export class PywbSnapshot {
|
||||
getTimeFormatted() {
|
||||
return (this.hour < 13 ? this.hour : (this.hour % 12)) + ":" + ((this.minute < 10 ? "0":"")+this.minute) + ":" + ((this.second < 10 ? "0":"")+this.second) + " " + (this.hour < 12 ? "am":"pm");
|
||||
}
|
||||
|
||||
getParentIds() {
|
||||
return [this.year, this.month, this.day, Math.ceil((this.hour + .0001) / (24/8))];
|
||||
}
|
||||
|
||||
getFullId() {
|
||||
return [this.year, this.month, this.day, Math.ceil((this.hour + .0001) / (24/8)), this.id].join(PywbPeriodIdDelimiter);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------- PERIOD object ----------------- */
|
||||
@ -318,8 +326,17 @@ PywbPeriod.prototype.getParents = function(skipAllTime=false) {
|
||||
return parents;
|
||||
};
|
||||
|
||||
PywbPeriod.prototype.contains = function(period) {
|
||||
return !!period.getParents().find(p => p === this);
|
||||
PywbPeriod.prototype.contains = function(periodOrSnapshot) {
|
||||
if (this.type === 0) {
|
||||
return true; // all-time contains everything
|
||||
}
|
||||
if (periodOrSnapshot instanceof PywbPeriod) {
|
||||
return periodOrSnapshot.getParents(true).slice(0,this.type).join(PywbPeriodIdDelimiter) === this.fullId;
|
||||
}
|
||||
if (periodOrSnapshot instanceof PywbSnapshot) {
|
||||
return periodOrSnapshot.getParentIds(true).slice(0,this.type).join(PywbPeriodIdDelimiter) === this.fullId;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
PywbPeriod.prototype.snapshot = null;
|
||||
@ -376,13 +393,13 @@ PywbPeriod.prototype.getSnapshotPeriodsFlat = function(flatArray=false) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the "full" id, which includes all parents ID and self ID, delimited by a hyphen "-"
|
||||
* Return the "full" id, which includes all parents ID and self ID, delimited by a ${PywbPeriodIdDelimiter}
|
||||
* @returns {string}
|
||||
*/
|
||||
PywbPeriod.prototype.initFullId = function() {
|
||||
const ids = this.getParents(true).map(p => p.id);
|
||||
ids.push(this.id);
|
||||
this.fullId = ids.join("-");
|
||||
this.fullId = ids.join(PywbPeriodIdDelimiter);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -395,7 +412,7 @@ PywbPeriod.prototype.findByFullId = function(fullId) {
|
||||
if (this.type !== PywbPeriod.Type.all) {
|
||||
parent = this.getParents()[0];
|
||||
}
|
||||
const ids = fullId.split('-');
|
||||
const ids = fullId.split(PywbPeriodIdDelimiter);
|
||||
|
||||
let found = false;
|
||||
for(let i=0; i<ids.length; i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user