1
0
mirror of https://github.com/webrecorder/pywb.git synced 2025-03-15 00:03:28 +01:00

misc vue + i18n fixes:

- make calendar tooltips into real links and clickable and ctrl+clickable
- ensure advanced view uses old ui (not supported in new ui)
- add language popup on frame_insert for vueui
- i18n: consolidate loc strings for vueui into vue_loc.html
- spinner: for replay, only show over banner
- spinner: show after 500ms delay
- i18n: add one more string ('no captures')
- make calendar popup links regular links to support cmd+click
- i18n: implement lang switcher in vue as well (for query and framed_insert), don't include non-vue language switcher in header
This commit is contained in:
Ilya Kreymer 2022-02-08 21:49:08 -08:00 committed by Tessa Walsh
parent 72cb588936
commit 19032e4512
13 changed files with 233 additions and 172 deletions

View File

@ -33,5 +33,4 @@ redirect_to_exact: true
# uncomment to set available locales # uncomment to set available locales
locales: locales:
- en - en
- fr - ru

View File

@ -2,7 +2,7 @@ from io import BytesIO
import requests import requests
from fakeredis import FakeStrictRedis from fakeredis import FakeStrictRedis
from six.moves.urllib.parse import unquote, urlencode, urlsplit, urlunsplit from six.moves.urllib.parse import unquote, urlencode, urlsplit, urlunsplit, parse_qsl
from warcio.bufferedreaders import BufferedReader from warcio.bufferedreaders import BufferedReader
from warcio.recordloader import ArcWarcRecordLoader from warcio.recordloader import ArcWarcRecordLoader
from warcio.timeutils import http_date_to_timestamp, timestamp_to_http_date from warcio.timeutils import http_date_to_timestamp, timestamp_to_http_date
@ -802,9 +802,17 @@ class RewriterApp(object):
def handle_query(self, environ, wb_url, kwargs, full_prefix): def handle_query(self, environ, wb_url, kwargs, full_prefix):
prefix = self.get_full_prefix(environ) prefix = self.get_full_prefix(environ)
res = dict(parse_qsl(environ.get("QUERY_STRING")))
is_advanced = res.get("matchType", "exact") != "exact" or res.get("url", "").endswith("*")
# vue ui not supported for advanced search for now
ui = kwargs.get("ui", {})
if is_advanced:
ui["vue_calendar_ui"] = False
params = dict(url=wb_url.url, params = dict(url=wb_url.url,
prefix=prefix, prefix=prefix,
ui=kwargs.get('ui', {})) ui=ui)
return self.query_view.render_to_string(environ, **params) return self.query_view.render_to_string(environ, **params)

View File

@ -1,5 +1,9 @@
const smallSize = "75px";
class LoadingSpinner { class LoadingSpinner {
static #instanceCount = 0; static #instanceCount = 0;
constructor(config={}) { constructor(config={}) {
this.config = {initialState:true, animationDuration:500, text:'Loading...', ...config}; this.config = {initialState:true, animationDuration:500, text:'Loading...', ...config};
@ -75,7 +79,7 @@ class LoadingSpinner {
top: 0; top: 0;
left: 0; left: 0;
width: 100vw; width: 100vw;
height: 100vh; height: ${this.config.isSmall ? smallSize : "100vh"};
z-index: 900; z-index: 900;
display: flex; display: flex;
@ -98,8 +102,8 @@ class LoadingSpinner {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 200px; width: ${this.config.isSmall ? smallSize : "200px"};
height: 200px; height: ${this.config.isSmall ? smallSize : "200px"};
}`,` }`,`
[data-loading-spinner^=circle] { [data-loading-spinner^=circle] {
position: absolute; position: absolute;
@ -153,4 +157,4 @@ class LoadingSpinner {
}`]; }`];
rules.forEach(rule => stylesheetEl.sheet.insertRule(rule)); rules.forEach(rule => stylesheetEl.sheet.insertRule(rule));
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -18,64 +18,11 @@ html, body
{{ banner_html }} {{ banner_html }}
<script> {% if ui.vue_timeline_banner %}
var i18nStrings = {
jan_long: "{{ _Q('January') }}", {% include 'vue_loc.html' %}
feb_long: "{{ _Q('February') }}",
mar_long: "{{ _Q('March') }}", {% endif %}
apr_long: "{{ _Q('April') }}",
may_long: "{{ _Q('May') }}",
jun_long: "{{ _Q('June') }}",
jul_long: "{{ _Q('July') }}",
aug_long: "{{ _Q('August') }}",
sep_long: "{{ _Q('September') }}",
oct_long: "{{ _Q('October') }}",
nov_long: "{{ _Q('November') }}",
dec_long: "{{ _Q('December') }}",
jan_short: "{{ _Q('Jan') }}",
feb_short: "{{ _Q('Feb') }}",
mar_short: "{{ _Q('Mar') }}",
apr_short: "{{ _Q('Apr') }}",
may_short: "{{ _Q('May') }}",
jun_short: "{{ _Q('Jun') }}",
jul_short: "{{ _Q('Jul') }}",
aug_short: "{{ _Q('Aug') }}",
sep_short: "{{ _Q('Sep') }}",
oct_short: "{{ _Q('Oct') }}",
nov_short: "{{ _Q('Nov') }}",
dec_short: "{{ _Q('Dec') }}",
mon_short: "{{ _Q('Mon') }}",
tue_short: "{{ _Q('Tue') }}",
wed_short: "{{ _Q('Wed') }}",
thu_short: "{{ _Q('Thu') }}",
fri_short: "{{ _Q('Fri') }}",
sat_short: "{{ _Q('Sat') }}",
sun_short: "{{ _Q('Sun') }}",
mon_long: "{{ _Q('Monday') }}",
tue_long: "{{ _Q('Tuesday') }}",
wed_long: "{{ _Q('Wednesday') }}",
thu_long: "{{ _Q('Thursday') }}",
fri_long: "{{ _Q('Friday') }}",
sat_long: "{{ _Q('Saturday') }}",
sun_long: "{{ _Q('Sunday') }}",
"All-time": "{{ _Q('All-time') }}",
"show timeline":"{{ _Q('show timeline') }}",
"hide timeline":"{{ _Q('hide timeline') }}",
"show calendar":"{{ _Q('show calendar') }}",
"hide calendar":"{{ _Q('hide calendar') }}",
"View capture on {date}":"{{ _Q('View capture on {date}') }}",
"{count} capture":"{{ _Q('{count} capture') }}",
"{count} captures":"{{ _Q('{count} captures') }}",
"{capture_text} on {date}":"{{ _Q('{capture_text} on {date}') }}",
"{capture_text} in {month}":"{{ _Q('{capture_text} in {month}') }}",
"current":"{{ _Q('current') }}",
"Loading...": "{{ _Q('Loading...') }}",
"Current Capture": "{{ _Q('Current Capture') }}",
"capture": "{{ _Q('capture') }}",
"captures": "{{ _Q('captures') }}",
"from {hour1} to {hour2}": "{{ _Q('from {hour1} to {hour2}') }}",
};
</script>
</head> </head>
<body style="margin: 0px; padding: 0px;"> <body style="margin: 0px; padding: 0px;">
@ -83,7 +30,8 @@ html, body
{% if ui.vue_timeline_banner %} {% if ui.vue_timeline_banner %}
<div id="app" style="width: 100%; height: 200px"></div> <div id="app" style="width: 100%; height: 200px"></div>
<script> <script>
VueUI.main("{{ static_prefix }}", "{{ url }}", "{{ wb_prefix }}", "{{ timestamp }}", "{{ ui.logo }}", "{{ env.pywb_lang | default('en') }}", i18nStrings); VueUI.main("{{ static_prefix }}", "{{ url }}", "{{ wb_prefix }}", "{{ timestamp }}", "{{ ui.logo }}", "{{ env.pywb_lang | default('en') }}",
allLocales, i18nStrings);
</script> </script>
{% endif %} {% endif %}

View File

@ -1,6 +1,6 @@
{# place content to be added at the very beginning of the <body> tag in this file below #} {# place content to be added at the very beginning of the <body> tag in this file below #}
<header> <header>
{% if not err_msg and locales|length > 1 %} {% if not err_msg and locales|length > 1 and (not ui or not ui.vue_calendar_ui) %}
<div class="language-select"> <div class="language-select">
{{ _('Language:') }} {{ _('Language:') }}
<ul role="listbox" aria-activedescendant="{{ env.pywb_lang | default(default_locale) }}" aria-labelledby="{{ _('Language select') }}"> <ul role="listbox" aria-activedescendant="{{ env.pywb_lang | default(default_locale) }}" aria-labelledby="{{ _('Language select') }}">

View File

@ -16,66 +16,9 @@
<script src="{{ static_prefix }}/loading-spinner/loading-spinner.js"></script> <script src="{{ static_prefix }}/loading-spinner/loading-spinner.js"></script>
<script src="{{ static_prefix }}/vue/vueui.js"></script> <script src="{{ static_prefix }}/vue/vueui.js"></script>
{% endif %} {% include 'vue_loc.html' %}
<script> {% endif %}
var i18nStrings = {
jan_long: "{{ _Q('January') }}",
feb_long: "{{ _Q('February') }}",
mar_long: "{{ _Q('March') }}",
apr_long: "{{ _Q('April') }}",
may_long: "{{ _Q('May') }}",
jun_long: "{{ _Q('June') }}",
jul_long: "{{ _Q('July') }}",
aug_long: "{{ _Q('August') }}",
sep_long: "{{ _Q('September') }}",
oct_long: "{{ _Q('October') }}",
nov_long: "{{ _Q('November') }}",
dec_long: "{{ _Q('December') }}",
jan_short: "{{ _Q('Jan') }}",
feb_short: "{{ _Q('Feb') }}",
mar_short: "{{ _Q('Mar') }}",
apr_short: "{{ _Q('Apr') }}",
may_short: "{{ _Q('May') }}",
jun_short: "{{ _Q('Jun') }}",
jul_short: "{{ _Q('Jul') }}",
aug_short: "{{ _Q('Aug') }}",
sep_short: "{{ _Q('Sep') }}",
oct_short: "{{ _Q('Oct') }}",
nov_short: "{{ _Q('Nov') }}",
dec_short: "{{ _Q('Dec') }}",
mon_short: "{{ _Q('Mon') }}",
tue_short: "{{ _Q('Tue') }}",
wed_short: "{{ _Q('Wed') }}",
thu_short: "{{ _Q('Thu') }}",
fri_short: "{{ _Q('Fri') }}",
sat_short: "{{ _Q('Sat') }}",
sun_short: "{{ _Q('Sun') }}",
mon_long: "{{ _Q('Monday') }}",
tue_long: "{{ _Q('Tuesday') }}",
wed_long: "{{ _Q('Wednesday') }}",
thu_long: "{{ _Q('Thursday') }}",
fri_long: "{{ _Q('Friday') }}",
sat_long: "{{ _Q('Saturday') }}",
sun_long: "{{ _Q('Sunday') }}",
"All-time": "{{ _Q('All-time') }}",
"show timeline":"{{ _Q('show timeline') }}",
"hide timeline":"{{ _Q('hide timeline') }}",
"show calendar":"{{ _Q('show calendar') }}",
"hide calendar":"{{ _Q('hide calendar') }}",
"View capture on {date}":"{{ _Q('View capture on {date}') }}",
"{count} capture":"{{ _Q('{count} capture') }}",
"{count} captures":"{{ _Q('{count} captures') }}",
"{capture_text} on {date}":"{{ _Q('{capture_text} on {date}') }}",
"{capture_text} in {month}":"{{ _Q('{capture_text} in {month}') }}",
"current":"{{ _Q('current') }}", // translators: current capture in list of captures
"Loading...": "{{ _Q('Loading...') }}",
"Current Capture": "{{ _Q('Current Capture') }}",
"capture": "{{ _Q('capture') }}",
"captures": "{{ _Q('captures') }}",
"from {hour1} to {hour2}": "{{ _Q('from {hour1} to {hour2}') }}",
};
</script>
{% endblock %} {% endblock %}
@ -138,7 +81,8 @@
renderCal.init(); renderCal.init();
{% else %} {% else %}
VueUI.main("{{ static_prefix }}", "{{ url }}", "{{ prefix }}", undefined, "{{ ui.logo }}", "{{ env.pywb_lang | default('en') }}", i18nStrings); VueUI.main("{{ static_prefix }}", "{{ url }}", "{{ prefix }}", undefined, "{{ ui.logo }}", "{{ env.pywb_lang | default('en') }}",
allLocales, i18nStrings);
{% endif %} {% endif %}

View File

@ -0,0 +1,63 @@
<script>
{% autoescape false %}
var allLocales = {{ get_locale_prefixes() }};
{% endautoescape %}
var i18nStrings = {
jan_long: "{{ _Q('January') }}",
feb_long: "{{ _Q('February') }}",
mar_long: "{{ _Q('March') }}",
apr_long: "{{ _Q('April') }}",
may_long: "{{ _Q('May') }}",
jun_long: "{{ _Q('June') }}",
jul_long: "{{ _Q('July') }}",
aug_long: "{{ _Q('August') }}",
sep_long: "{{ _Q('September') }}",
oct_long: "{{ _Q('October') }}",
nov_long: "{{ _Q('November') }}",
dec_long: "{{ _Q('December') }}",
jan_short: "{{ _Q('Jan') }}",
feb_short: "{{ _Q('Feb') }}",
mar_short: "{{ _Q('Mar') }}",
apr_short: "{{ _Q('Apr') }}",
may_short: "{{ _Q('May') }}",
jun_short: "{{ _Q('Jun') }}",
jul_short: "{{ _Q('Jul') }}",
aug_short: "{{ _Q('Aug') }}",
sep_short: "{{ _Q('Sep') }}",
oct_short: "{{ _Q('Oct') }}",
nov_short: "{{ _Q('Nov') }}",
dec_short: "{{ _Q('Dec') }}",
mon_short: "{{ _Q('Mon') }}",
tue_short: "{{ _Q('Tue') }}",
wed_short: "{{ _Q('Wed') }}",
thu_short: "{{ _Q('Thu') }}",
fri_short: "{{ _Q('Fri') }}",
sat_short: "{{ _Q('Sat') }}",
sun_short: "{{ _Q('Sun') }}",
mon_long: "{{ _Q('Monday') }}",
tue_long: "{{ _Q('Tuesday') }}",
wed_long: "{{ _Q('Wednesday') }}",
thu_long: "{{ _Q('Thursday') }}",
fri_long: "{{ _Q('Friday') }}",
sat_long: "{{ _Q('Saturday') }}",
sun_long: "{{ _Q('Sunday') }}",
"All-time": "{{ _Q('All-time') }}",
"show timeline":"{{ _Q('show timeline') }}",
"hide timeline":"{{ _Q('hide timeline') }}",
"show calendar":"{{ _Q('show calendar') }}",
"hide calendar":"{{ _Q('hide calendar') }}",
"View capture on {date}":"{{ _Q('View capture on {date}') }}",
"{count} capture":"{{ _Q('{count} capture') }}",
"{count} captures":"{{ _Q('{count} captures') }}",
"{capture_text} on {date}":"{{ _Q('{capture_text} on {date}') }}",
"{capture_text} in {month}":"{{ _Q('{capture_text} in {month}') }}",
"current":"{{ _Q('current') }}", // translators: current capture in list of captures
"Loading...": "{{ _Q('Loading...') }}",
"Current Capture": "{{ _Q('Current Capture') }}",
"capture": "{{ _Q('capture') }}",
"captures": "{{ _Q('captures') }}",
"from {hour1} to {hour2}": "{{ _Q('from {hour1} to {hour2}') }}",
"no captures": "{{ _Q('no captures') }}"
}
</script>

View File

@ -2,7 +2,7 @@
<div class="app" :class="{expanded: showTimelineView}" data-app="webrecorder-replay-app"> <div class="app" :class="{expanded: showTimelineView}" data-app="webrecorder-replay-app">
<div class="banner"> <div class="banner">
<div class="line"> <div class="line">
<div class="logo"><a href="/"><img :src="config.logoImg" style="max-width: 80px" /></a></div> <div class="logo"><a href="/"><img :src="config.logoImg"/></a></div>
<div class="timeline-wrap"> <div class="timeline-wrap">
<div class="line"> <div class="line">
<div class="breadcrumbs-wrap"> <div class="breadcrumbs-wrap">
@ -21,6 +21,12 @@
<span class="toggle" :class="{expanded: showTimelineView}" @click="showTimelineView = !showTimelineView" :title="(showTimelineView ? _('show timeline'):_('hide timeline'))"> <span class="toggle" :class="{expanded: showTimelineView}" @click="showTimelineView = !showTimelineView" :title="(showTimelineView ? _('show timeline'):_('hide timeline'))">
<img src="/static/timeline-icon.png" /> <img src="/static/timeline-icon.png" />
</span> </span>
<ul class="lang-select" role="listbox" :aria-activedescendant="config.locale"
:aria-labelledby="_('Language select')">
<li v-for="(locPath, key) in config.allLocales" role="option" :id="key">
<a :href="locPath + (currentSnapshot ? currentSnapshot.id : '*') + '/' + config.url">{{ key }}</a>
</li>
</ul>
</div> </div>
</div> </div>
<Timeline <Timeline
@ -76,6 +82,7 @@ export default {
initialView: {} initialView: {}
}, },
timelineHighlight: false, timelineHighlight: false,
locales: [],
}; };
}, },
components: {Timeline, TimelineBreadcrumbs, CalendarYear}, components: {Timeline, TimelineBreadcrumbs, CalendarYear},
@ -262,4 +269,33 @@ export default {
#theurl { #theurl {
width: 400px; width: 400px;
} }
ul.lang-select {
display: inline-block;
list-style-type: none;
margin: 0;
padding: 0 24px 0 8px;
}
ul.lang-select li {
display: inline-block;
padding-left: 6px;
font-weight: bold;
font-size: smaller;
}
ul.lang-select li:not(:last-child):after {
content: ' / ';
}
ul.lang-select a:link,
ul.lang-select a:visited,
ul.lang-select a:active {
text-decoration: none;
}
ul.lang-select a:hover {
text-decoration: underline;
}
</style> </style>

View File

@ -8,6 +8,7 @@
width: 220px; width: 220px;
text-align: center; text-align: center;
vertical-align: top; vertical-align: top;
box-sizing: content-box;
} }
.calendar-month:hover { .calendar-month:hover {
background-color: #eeeeee; background-color: #eeeeee;
@ -96,7 +97,7 @@
<span v-for="(dayInitial) in dayInitials" class="day" :style="dayStyle">{{dayInitial}}</span><br/> <span v-for="(dayInitial) in dayInitials" class="day" :style="dayStyle">{{dayInitial}}</span><br/>
<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">{{ $root._(day.snapshotCount !== 1 ? '{count} captures':'{count} capture', {count: day.snapshotCount}) }}</span></template><template v-else v-html="'&nbsp;'"></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">{{ $root._(day.snapshotCount !== 1 ? '{count} captures':'{count} capture', {count: day.snapshotCount}) }}</span></template><template v-else v-html="'&nbsp;'"></template></span></span>
</div> </div>
<div v-else class="empty">no captures</div> <div v-else class="empty">{{ _('no captures') }}</div>
</div> </div>
</template> </template>
@ -146,6 +147,9 @@ export default {
} }
}, },
methods: { methods: {
_(id, embeddedVariableStrings=null) {
return PywbI18N.instance.getText(id, embeddedVariableStrings);
},
getLongMonthName(id) { getLongMonthName(id) {
return PywbI18N.instance.getMonth(id); return PywbI18N.instance.getMonth(id);
}, },

View File

@ -56,7 +56,7 @@ export default {
font-size: inherit; font-size: inherit;
} }
.breadcrumbs .count { .breadcrumbs .count {
vertical-align: middle; /*vertical-align: middle;*/
font-size: inherit; font-size: inherit;
} }
@ -79,4 +79,4 @@ export default {
display: block; display: block;
} }
</style> </style>

View File

@ -7,7 +7,7 @@
<div class="list"> <div class="list">
<div v-for="period in snapshotPeriods"> <div v-for="period in snapshotPeriods">
<span class="link" @click="gotoPeriod(period)" >{{period.snapshot.getTimeFormatted()}}</span> <a :href="$root.config.prefix + period.id + '/' + $root.config.url" class="link" >{{period.snapshot.getTimeFormatted()}}</a>
<span v-if="isCurrentSnapshot(period)" class="current">{{$root._('current')}}</span> <span v-if="isCurrentSnapshot(period)" class="current">{{$root._('current')}}</span>
</div> </div>
</div> </div>
@ -28,9 +28,6 @@ export default {
} }
}, },
methods: { methods: {
gotoPeriod(period) {
this.$emit('goto-period', period);
},
isCurrentSnapshot(period) { isCurrentSnapshot(period) {
return this.currentSnapshot && this.currentSnapshot.id === period.snapshot.id; return this.currentSnapshot && this.currentSnapshot.id === period.snapshot.id;
} }
@ -69,4 +66,4 @@ export default {
color: white; color: white;
border-radius: 5px; border-radius: 5px;
} }
</style> </style>

View File

@ -7,16 +7,16 @@ import Vue from "vue/dist/vue.esm.browser";
// =========================================================================== // ===========================================================================
export function main(staticPrefix, url, prefix, timestamp, logoUrl, locale, i18nStrings) { export function main(staticPrefix, url, prefix, timestamp, logoUrl, locale, allLocales, i18nStrings) {
PywbI18N.init(locale, i18nStrings); PywbI18N.init(locale, i18nStrings);
const loadingSpinner = new LoadingSpinner({text: PywbI18N.instance?.getText('Loading...')}); // bootstrap loading-spinner EARLY ON new CDXLoader(staticPrefix, url, prefix, timestamp, logoUrl, allLocales);
new CDXLoader(staticPrefix, url, prefix, timestamp, logoUrl, loadingSpinner);
} }
// =========================================================================== // ===========================================================================
class CDXLoader { class CDXLoader {
constructor(staticPrefix, url, prefix, timestamp, logoUrl, loadingSpinner) { constructor(staticPrefix, url, prefix, timestamp, logoUrl, allLocales) {
this.loadingSpinner = loadingSpinner; this.loadingSpinner = null;
this.loaded = false;
this.opts = {}; this.opts = {};
this.prefix = prefix; this.prefix = prefix;
this.staticPrefix = staticPrefix; this.staticPrefix = staticPrefix;
@ -24,6 +24,13 @@ class CDXLoader {
this.isReplay = (timestamp !== undefined); this.isReplay = (timestamp !== undefined);
setTimeout(() => {
if (!this.loaded) {
this.loadingSpinner = new LoadingSpinner({text: PywbI18N.instance?.getText('Loading...'), isSmall: !!timestamp}); // bootstrap loading-spinner EARLY ON
this.loadingSpinner.setOn();
}
}, 500);
if (this.isReplay) { if (this.isReplay) {
window.WBBanner = new VueBannerWrapper(this, url); window.WBBanner = new VueBannerWrapper(this, url);
} }
@ -49,7 +56,7 @@ class CDXLoader {
const logoImg = this.staticPrefix + "/" + (this.logoUrl ? this.logoUrl : "pywb-logo-sm.png"); const logoImg = this.staticPrefix + "/" + (this.logoUrl ? this.logoUrl : "pywb-logo-sm.png");
this.app = this.initApp({logoImg, url}); this.app = this.initApp({logoImg, url, allLocales});
this.loadCDX(queryURL).then((cdxList) => { this.loadCDX(queryURL).then((cdxList) => {
this.setAppData(cdxList, timestamp ? {url, timestamp}:null); this.setAppData(cdxList, timestamp ? {url, timestamp}:null);
}); });
@ -75,7 +82,12 @@ class CDXLoader {
// }); // });
app.$on("show-snapshot", this.loadSnapshot.bind(this)); app.$on("show-snapshot", this.loadSnapshot.bind(this));
app.$on("data-set-and-render-completed", () => this.loadingSpinner.setOff()); // only turn off loading-spinner AFTER app has told us it is DONE DONE app.$on("data-set-and-render-completed", () => {
if (this.loadingSpinner) {
this.loadingSpinner.setOff(); // only turn off loading-spinner AFTER app has told us it is DONE DONE
}
this.loaded = true;
});
return app; return app;
} }
@ -100,7 +112,7 @@ class CDXLoader {
} }
async loadCDX(queryURL) { async loadCDX(queryURL) {
this.loadingSpinner.setOn(); // start loading-spinner when CDX loading begins // this.loadingSpinner.setOn(); // start loading-spinner when CDX loading begins
const queryWorker = new Worker(this.staticPrefix + "/queryWorker.js"); const queryWorker = new Worker(this.staticPrefix + "/queryWorker.js");
const p = new Promise((resolve) => { const p = new Promise((resolve) => {