mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-24 06:59:52 +01:00
app timeline: made periods with 1 snapshot only to navigate to snapshot itself (not to zoom in); moved "snapshot count" to be in the period label, so that histogram lines are more readily clickable/hoverable at any zoom level
This commit is contained in:
parent
ad6c816d4e
commit
c9f7f50c58
File diff suppressed because one or more lines are too long
@ -7,20 +7,23 @@
|
|||||||
:key="subPeriod.id"
|
:key="subPeriod.id"
|
||||||
class="period"
|
class="period"
|
||||||
:class="{empty: !subPeriod.snapshotCount, highlight: highlightPeriod === subPeriod, 'last-level': isLastZoomLevel}"
|
:class="{empty: !subPeriod.snapshotCount, highlight: highlightPeriod === subPeriod, 'last-level': isLastZoomLevel}"
|
||||||
v-on:click="changePeriod(subPeriod)">
|
v-on:click="changePeriod(subPeriod, $event)">
|
||||||
<div class="histo">
|
<div class="histo">
|
||||||
<div class="count" v-if="!subPeriod.snapshot && !isLastZoomLevel"><span class="count-inner">{{subPeriod.snapshotCount}}</span></div>
|
|
||||||
<div class="line"
|
<div class="line"
|
||||||
v-for="histoPeriod in subPeriod.children"
|
v-for="histoPeriod in subPeriod.children"
|
||||||
:key="histoPeriod.id"
|
:key="histoPeriod.id"
|
||||||
:style="{height: getHistoLineHeight(histoPeriod.snapshotCount)}"
|
:style="{height: getHistoLineHeight(histoPeriod.snapshotCount)}"
|
||||||
v-on:click="changePeriodFromHistogram(histoPeriod)"
|
:class="{'has-single-snap': !!histoPeriod.snapshotPeriod}"
|
||||||
|
v-on:click="changePeriod(histoPeriod, $event)"
|
||||||
>
|
>
|
||||||
<div class="snap-info" v-if="isLastZoomLevel">{{histoPeriod.snapshot.getTimeDateFormatted()}}</div>
|
<div class="snap-info" v-if="histoPeriod.snapshot">View capture from {{histoPeriod.snapshot.getTimeDateFormatted()}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="label">{{subPeriod.getReadableId()}}</div>
|
<div class="label">
|
||||||
|
{{subPeriod.getReadableId()}}
|
||||||
|
<div class="count" v-if="subPeriod.snapshotCount">({{subPeriod.snapshotCount}})</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -103,22 +106,32 @@ export default{
|
|||||||
return (percent ? (5 + Math.ceil(percent*.95)) : 0) + "%";
|
return (percent ? (5 + Math.ceil(percent*.95)) : 0) + "%";
|
||||||
// return percent + '%';
|
// return percent + '%';
|
||||||
},
|
},
|
||||||
changePeriod(period) {
|
changePeriod(period, $event) {
|
||||||
|
// if not empty
|
||||||
if (period.snapshotCount) {
|
if (period.snapshotCount) {
|
||||||
if (this.isLastZoomLevel) {
|
let periodToChangeTo = null;
|
||||||
|
// if contains a single snapshot only, navigate to snapshot (load snapshot in FRAME, do not ZOOM IN)
|
||||||
|
if (period.snapshot) {
|
||||||
|
// if period is at level "snapshot" (no more children), send period, else send the child period, a reference to which is stored (by data/model layer) in the current period; App event needs a period to be passed (cannot pass in snapshot object itself)
|
||||||
if (period.type === PywbPeriod.Type.snapshot) {
|
if (period.type === PywbPeriod.Type.snapshot) {
|
||||||
this.$emit("goto-period", period);
|
periodToChangeTo = period;
|
||||||
|
} else if (period.snapshotPeriod) {
|
||||||
|
periodToChangeTo = period.snapshotPeriod;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.$emit("goto-period", period);
|
// if contains mulitple snapshots, just ZOOM to period clicked itself
|
||||||
|
if (period.type <= PywbPeriod.Type.day) {
|
||||||
|
periodToChangeTo = period;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we selected a period to go to, emit event
|
||||||
|
if (periodToChangeTo) {
|
||||||
|
this.$emit("goto-period", periodToChangeTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
$event.stopPropagation();
|
||||||
// special "change period" from histogram lines
|
return false;
|
||||||
changePeriodFromHistogram(period) {
|
|
||||||
if (this.isLastZoomLevel && period.type === PywbPeriod.Type.snapshot) {
|
|
||||||
this.$emit("goto-period", period);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onPeriodChanged(newPeriod, oldPeriod) {
|
onPeriodChanged(newPeriod, oldPeriod) {
|
||||||
this.addEmptySubPeriods();
|
this.addEmptySubPeriods();
|
||||||
@ -249,32 +262,6 @@ export default{
|
|||||||
background-color: cyan;
|
background-color: cyan;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline .period .label {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 14px;
|
|
||||||
font-family: Baskerville, sans-serif;
|
|
||||||
}
|
|
||||||
.timeline .period .count {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: none;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 10px 0 0 0;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 25px;
|
|
||||||
}
|
|
||||||
.timeline .period .count .count-inner {
|
|
||||||
display: inline;
|
|
||||||
width: auto;
|
|
||||||
background-color: rgba(255,255,255,.85);
|
|
||||||
padding: 1px;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
.timeline .period:hover .count {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.timeline .period .inner {
|
.timeline .period .inner {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -284,9 +271,25 @@ export default{
|
|||||||
height: 16px;
|
height: 16px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border-top: 1px solid gray;
|
border-top: 1px solid gray;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.timeline .period.last-level .inner {
|
.timeline .period .label {
|
||||||
text-align: left;
|
width: 100%;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Baskerville, sans-serif;
|
||||||
|
transition: background-color 500ms ease-in;
|
||||||
|
}
|
||||||
|
.timeline .period:hover .label {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 20;
|
||||||
|
background-color: lightgrey;
|
||||||
|
}
|
||||||
|
.timeline .period .count {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.timeline .period:hover .count {
|
||||||
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline .period .histo {
|
.timeline .period .histo {
|
||||||
@ -302,6 +305,7 @@ export default{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.timeline .period .histo .line {
|
.timeline .period .histo .line {
|
||||||
|
position: relative;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: #a6cdf5;
|
background-color: #a6cdf5;
|
||||||
@ -319,17 +323,15 @@ export default{
|
|||||||
flex-grow: unset;
|
flex-grow: unset;
|
||||||
width: 5px;
|
width: 5px;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
|
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update line color on hover*/
|
/* update line color on hover*/
|
||||||
.timeline .period.last-level .histo .line:hover {
|
.timeline .period .histo .line:hover {
|
||||||
background-color: #f5a6eb;
|
background-color: #f5a6eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Last level period histogram line has extra info*/
|
/* Period that contains ONE snapshot only will show snapshot info*/
|
||||||
.timeline .period.last-level .histo .line .snap-info {
|
.timeline .period .histo .line .snap-info {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
top: 30%;
|
top: 30%;
|
||||||
@ -341,7 +343,7 @@ export default{
|
|||||||
white-space: nowrap; /*no wrapping allowed*/
|
white-space: nowrap; /*no wrapping allowed*/
|
||||||
}
|
}
|
||||||
/*show on hover*/
|
/*show on hover*/
|
||||||
.timeline .period.last-level .histo .line:hover .snap-info {
|
.timeline .period .histo .line.has-single-snap:hover .snap-info {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,25 +4,29 @@ export function PywbData(rawSnaps) {
|
|||||||
const allTimePeriod = new PywbPeriod({type: PywbPeriod.Type.all, id: "all"});
|
const allTimePeriod = new PywbPeriod({type: PywbPeriod.Type.all, id: "all"});
|
||||||
const snapshots = [];
|
const snapshots = [];
|
||||||
let lastSingle = null;
|
let lastSingle = null;
|
||||||
|
let lastYear, lastMonth, lastDay, lastHour;
|
||||||
rawSnaps.forEach((rawSnap, i) => {
|
rawSnaps.forEach((rawSnap, i) => {
|
||||||
const snap = new PywbSnapshot(rawSnap, i);
|
const snap = new PywbSnapshot(rawSnap, i);
|
||||||
let year, month, day, hour, single;
|
let year, month, day, hour, single;
|
||||||
if (!(year = allTimePeriod.getChildById(snap.year))) {
|
if (!(year = allTimePeriod.getChildById(snap.year))) {
|
||||||
year = new PywbPeriod({type: PywbPeriod.Type.year, id: snap.year});
|
if (lastYear) lastYear.checkIfSingleSnapshotOnly();
|
||||||
|
lastYear = year = new PywbPeriod({type: PywbPeriod.Type.year, id: snap.year});
|
||||||
allTimePeriod.addChild(year);
|
allTimePeriod.addChild(year);
|
||||||
}
|
}
|
||||||
if (!(month = year.getChildById(snap.month))) {
|
if (!(month = year.getChildById(snap.month))) {
|
||||||
month = new PywbPeriod({type: PywbPeriod.Type.month, id: snap.month});
|
if (lastMonth) lastMonth.checkIfSingleSnapshotOnly();
|
||||||
|
lastMonth = month = new PywbPeriod({type: PywbPeriod.Type.month, id: snap.month});
|
||||||
year.addChild(month);
|
year.addChild(month);
|
||||||
}
|
}
|
||||||
if (!(day = month.getChildById(snap.day))) {
|
if (!(day = month.getChildById(snap.day))) {
|
||||||
day = new PywbPeriod({type: PywbPeriod.Type.day, id: snap.day});
|
if (lastDay) lastDay.checkIfSingleSnapshotOnly();
|
||||||
|
lastDay = day = new PywbPeriod({type: PywbPeriod.Type.day, id: snap.day});
|
||||||
month.addChild(day);
|
month.addChild(day);
|
||||||
}
|
}
|
||||||
const hourValue = Math.ceil((snap.hour + .0001) / (24/8)); // divide day in 4 six-hour periods (aka quarters)
|
const hourValue = Math.ceil((snap.hour + .0001) / (24/8)); // divide day in 4 six-hour periods (aka quarters)
|
||||||
//const hourValue = snap.hour;
|
|
||||||
if (!(hour = day.getChildById(hourValue))) {
|
if (!(hour = day.getChildById(hourValue))) {
|
||||||
hour = new PywbPeriod({type: PywbPeriod.Type.hour, id: hourValue});
|
if (lastHour) lastHour.checkIfSingleSnapshotOnly();
|
||||||
|
lastHour = hour = new PywbPeriod({type: PywbPeriod.Type.hour, id: hourValue});
|
||||||
day.addChild(hour);
|
day.addChild(hour);
|
||||||
}
|
}
|
||||||
if (!(single = hour.getChildById(snap.id))) {
|
if (!(single = hour.getChildById(snap.id))) {
|
||||||
@ -313,6 +317,21 @@ PywbPeriod.prototype.getParents = function(skipAllTime=false) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PywbPeriod.prototype.snapshot = null;
|
PywbPeriod.prototype.snapshot = null;
|
||||||
|
PywbPeriod.prototype.snapshotPeriod = null;
|
||||||
|
|
||||||
|
PywbPeriod.prototype.checkIfSingleSnapshotOnly = function() {
|
||||||
|
if (this.snapshotCount === 1) {
|
||||||
|
let snapshotPeriod = this;
|
||||||
|
let failSafe = PywbPeriod.Type.snapshot;
|
||||||
|
while(!snapshotPeriod.snapshot) {
|
||||||
|
if (--failSafe <=0) break;
|
||||||
|
snapshotPeriod = snapshotPeriod.children[0];
|
||||||
|
}
|
||||||
|
this.snapshot = snapshotPeriod.snapshot;
|
||||||
|
this.snapshotPeriod = snapshotPeriod;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
PywbPeriod.prototype.setSnapshot = function(snap) {
|
PywbPeriod.prototype.setSnapshot = function(snap) {
|
||||||
this.snapshot = snap;
|
this.snapshot = snap;
|
||||||
this.snapshotCount++;
|
this.snapshotCount++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user