Linting some ui components.

This commit is contained in:
2021-02-18 21:53:56 +01:00
parent 8bd41cc691
commit 6968ccf389
9 changed files with 122 additions and 158 deletions

View File

@@ -21,8 +21,9 @@
<div class="clock"> <div class="clock">
<h2 v-if="!fiveMinutesLeft || !tenMinutesOver"> <h2 v-if="!fiveMinutesLeft || !tenMinutesOver">
<span v-if="days > 0">{{ pad(days) }}:</span> <span v-if="days > 0">{{ pad(days) }}:</span>
<span>{{ pad(hours) }}</span>: <span>{{ pad(hours) }}</span
<span>{{ pad(minutes) }}</span>: >: <span>{{ pad(minutes) }}</span
>:
<span>{{ pad(seconds) }}</span> <span>{{ pad(seconds) }}</span>
</h2> </h2>
<h2 v-if="twoMinutesLeft || tenMinutesOver">Lotteriet er i gang!</h2> <h2 v-if="twoMinutesLeft || tenMinutesOver">Lotteriet er i gang!</h2>
@@ -41,7 +42,7 @@ export default {
minutes: 0, minutes: 0,
seconds: 0, seconds: 0,
distance: 0, distance: 0,
interval: null, interval: null
}; };
}, },
props: { props: {
@@ -91,10 +92,7 @@ export default {
let nowDate = new Date(); let nowDate = new Date();
let now = nowDate.getTime(); let now = nowDate.getTime();
if (nextDayOfLottery.getTimezoneOffset() != nowDate.getTimezoneOffset()) { if (nextDayOfLottery.getTimezoneOffset() != nowDate.getTimezoneOffset()) {
let _diff = let _diff = (nextDayOfLottery.getTimezoneOffset() - nowDate.getTimezoneOffset()) * 60 * -1;
(nextDayOfLottery.getTimezoneOffset() - nowDate.getTimezoneOffset()) *
60 *
-1;
nextDayOfLottery.setSeconds(nextDayOfLottery.getSeconds() + _diff); nextDayOfLottery.setSeconds(nextDayOfLottery.getSeconds() + _diff);
} }
this.nextLottery = nextDayOfLottery; this.nextLottery = nextDayOfLottery;
@@ -110,12 +108,8 @@ export default {
// Time calculations for days, hours, minutes and seconds // Time calculations for days, hours, minutes and seconds
this.days = Math.floor(this.distance / (1000 * 60 * 60 * 24)); this.days = Math.floor(this.distance / (1000 * 60 * 60 * 24));
this.hours = Math.floor( this.hours = Math.floor((this.distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
(this.distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) this.minutes = Math.floor((this.distance % (1000 * 60 * 60)) / (1000 * 60));
);
this.minutes = Math.floor(
(this.distance % (1000 * 60 * 60)) / (1000 * 60)
);
this.seconds = Math.floor((this.distance % (1000 * 60)) / 1000); this.seconds = Math.floor((this.distance % (1000 * 60)) / 1000);
if (this.days == 7) { if (this.days == 7) {
this.days = 0; this.days = 0;
@@ -124,7 +118,7 @@ export default {
this.initialize(); this.initialize();
} }
this.interval = setTimeout(this.countdown, 500); this.interval = setTimeout(this.countdown, 500);
}, }
} }
}; };
</script> </script>

View File

@@ -1,6 +1,9 @@
<template> <template>
<div class="chat-container"> <div class="chat-container">
<span class="logged-in-username" v-if="username">Logget inn som: <span class="username">{{ username }}</span> <button @click="removeUsername">Logg ut</button></span> <span class="logged-in-username" v-if="username"
>Logget inn som: <span class="username">{{ username }}</span>
<button @click="removeUsername">Logg ut</button></span
>
<div class="history" ref="history" v-if="chatHistory.length > 0"> <div class="history" ref="history" v-if="chatHistory.length > 0">
<div class="opaque-skirt"></div> <div class="opaque-skirt"></div>
@@ -8,7 +11,8 @@
<button @click="loadMoreHistory">Hent eldre meldinger</button> <button @click="loadMoreHistory">Hent eldre meldinger</button>
</div> </div>
<div class="history-message" <div
class="history-message"
v-for="(history, index) in chatHistory" v-for="(history, index) in chatHistory"
:key="`${history.username}-${history.timestamp}-${index}`" :key="`${history.username}-${history.timestamp}-${index}`"
> >
@@ -61,12 +65,11 @@ export default {
}; };
}, },
created() { created() {
getChatHistory(1, this.pageSize) getChatHistory(1, this.pageSize).then(resp => {
.then(resp => {
this.chatHistory = resp.messages; this.chatHistory = resp.messages;
this.hasMorePages = resp.total != resp.messages.length; this.hasMorePages = resp.total != resp.messages.length;
}); });
const username = window.localStorage.getItem('username'); const username = window.localStorage.getItem("username");
if (username) { if (username) {
this.username = username; this.username = username;
this.emitUsernameOnConnect = true; this.emitUsernameOnConnect = true;
@@ -77,8 +80,7 @@ export default {
handler: function(newVal, oldVal) { handler: function(newVal, oldVal) {
if (oldVal.length == 0) { if (oldVal.length == 0) {
this.scrollToBottomOfHistory(); this.scrollToBottomOfHistory();
} } else if (newVal && newVal.length == oldVal.length) {
else if (newVal && newVal.length == oldVal.length) {
if (this.isScrollPositionAtBottom()) { if (this.isScrollPositionAtBottom()) {
this.scrollToBottomOfHistory(); this.scrollToBottomOfHistory();
} }
@@ -105,10 +107,7 @@ export default {
}); });
this.socket.on("connect", msg => { this.socket.on("connect", msg => {
if ( if (this.emitUsernameOnConnect || (this.wasDisconnected && this.username != null)) {
this.emitUsernameOnConnect ||
(this.wasDisconnected && this.username != null)
) {
this.setUsername(this.username); this.setUsername(this.username);
} }
}); });
@@ -133,8 +132,7 @@ export default {
let { page, pageSize } = this; let { page, pageSize } = this;
page = page + 1; page = page + 1;
getChatHistory(page, pageSize) getChatHistory(page, pageSize).then(resp => {
.then(resp => {
this.chatHistory = resp.messages.concat(this.chatHistory); this.chatHistory = resp.messages.concat(this.chatHistory);
this.page = page; this.page = page;
this.hasMorePages = resp.total != this.chatHistory.length; this.hasMorePages = resp.total != this.chatHistory.length;
@@ -146,9 +144,7 @@ export default {
}, },
getTime(timestamp) { getTime(timestamp) {
let date = new Date(timestamp); let date = new Date(timestamp);
const timeString = `${this.pad(date.getHours())}:${this.pad( const timeString = `${this.pad(date.getHours())}:${this.pad(date.getMinutes())}:${this.pad(date.getSeconds())}`;
date.getMinutes()
)}:${this.pad(date.getSeconds())}`;
if (date.getDate() == new Date().getDate()) { if (date.getDate() == new Date().getDate()) {
return timeString; return timeString;
@@ -158,7 +154,7 @@ export default {
sendMessage() { sendMessage() {
const message = { message: this.message }; const message = { message: this.message };
this.socket.emit("chat", message); this.socket.emit("chat", message);
this.message = ''; this.message = "";
this.scrollToBottomOfHistory(); this.scrollToBottomOfHistory();
}, },
setUsername(username = undefined) { setUsername(username = undefined) {
@@ -178,7 +174,7 @@ export default {
if (history) { if (history) {
return history.offsetHeight + history.scrollTop >= history.scrollHeight; return history.offsetHeight + history.scrollTop >= history.scrollHeight;
} }
return false return false;
}, },
scrollToBottomOfHistory() { scrollToBottomOfHistory() {
setTimeout(() => { setTimeout(() => {
@@ -189,15 +185,15 @@ export default {
scrollToMessageElement(message) { scrollToMessageElement(message) {
const elemTimestamp = this.getTime(message.timestamp); const elemTimestamp = this.getTime(message.timestamp);
const self = this; const self = this;
const getTimeStamp = (elem) => elem.getElementsByClassName('timestamp')[0].innerText; const getTimeStamp = elem => elem.getElementsByClassName("timestamp")[0].innerText;
const prevOldestMessageInNewList = (elem) => getTimeStamp(elem) == elemTimestamp; const prevOldestMessageInNewList = elem => getTimeStamp(elem) == elemTimestamp;
setTimeout(() => { setTimeout(() => {
const { history } = self.$refs; const { history } = self.$refs;
const childrenElements = Array.from(history.getElementsByClassName('history-message')); const childrenElements = Array.from(history.getElementsByClassName("history-message"));
const elemInNewList = childrenElements.find(prevOldestMessageInNewList); const elemInNewList = childrenElements.find(prevOldestMessageInNewList);
history.scrollTop = elemInNewList.offsetTop - 70 history.scrollTop = elemInNewList.offsetTop - 70;
}, 1); }, 1);
} }
} }
@@ -241,7 +237,6 @@ input {
display: flex; display: flex;
} }
.history { .history {
height: 75%; height: 75%;
overflow-y: scroll; overflow-y: scroll;
@@ -276,11 +271,7 @@ input {
position: fixed; position: fixed;
height: 2rem; height: 2rem;
z-index: 1; z-index: 1;
background: linear-gradient( background: linear-gradient(to bottom, white, rgba(255, 255, 255, 0));
to bottom,
white,
rgba(255, 255, 255, 0)
);
} }
& .fetch-older-history { & .fetch-older-history {
@@ -310,7 +301,7 @@ input {
border-radius: 4px; border-radius: 4px;
&::before { &::before {
content: ''; content: "";
position: absolute; position: absolute;
top: 2.1rem; top: 2.1rem;
left: 2rem; left: 2rem;

View File

@@ -4,7 +4,7 @@
<div class="flex justify-end"> <div class="flex justify-end">
<div class="requested-count cursor-pointer" @click="request"> <div class="requested-count cursor-pointer" @click="request">
<span>{{ requestedElement.count }}</span> <span>{{ requestedElement.count }}</span>
<i class="icon icon--heart" :class="{ 'active': locallyRequested }" /> <i class="icon icon--heart" :class="{ active: locallyRequested }" />
</div> </div>
</div> </div>
</template> </template>
@@ -17,10 +17,9 @@
<template v-slot:bottom> <template v-slot:bottom>
<div class="float-left request"> <div class="float-left request">
<i class="icon icon--heart request-icon" :class="{ 'active': locallyRequested }"></i> <i class="icon icon--heart request-icon" :class="{ active: locallyRequested }"></i>
<a aria-role="button" tabindex="0" class="link" @click="request" <a aria-role="button" tabindex="0" class="link" @click="request" :class="{ active: locallyRequested }">
:class="{ 'active': locallyRequested }"> {{ locallyRequested ? "Anbefalt" : "Anbefal" }}
{{ locallyRequested ? 'Anbefalt' : 'Anbefal' }}
</a> </a>
</div> </div>
</template> </template>
@@ -39,10 +38,10 @@ export default {
return { return {
wine: this.requestedElement.wine, wine: this.requestedElement.wine,
locallyRequested: false locallyRequested: false
} };
}, },
props: { props: {
requestedElement: { requestedElement: {
required: true, required: true,
type: Object type: Object
}, },
@@ -54,26 +53,25 @@ export default {
}, },
methods: { methods: {
request() { request() {
if (this.locallyRequested) if (this.locallyRequested) return;
return
console.log("requesting", this.wine) this.locallyRequested = true;
this.locallyRequested = true this.requestedElement.count = this.requestedElement.count + 1;
this.requestedElement.count = this.requestedElement.count +1 requestNewWine(this.wine);
requestNewWine(this.wine)
}, },
async deleteWine() { async deleteWine() {
const wine = this.wine const wine = this.wine;
if (window.confirm("Er du sikker på at du vil slette vinen?")) { if (window.confirm("Er du sikker på at du vil slette vinen?")) {
let response = await deleteRequestedWine(wine); let response = await deleteRequestedWine(wine);
if (response['success'] == true) { if (response["success"] == true) {
this.$emit('wineDeleted', wine); this.$emit("wineDeleted", wine);
} else { } else {
alert("Klarte ikke slette vinen"); alert("Klarte ikke slette vinen");
} }
} }
},
},
} }
}
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -100,7 +98,7 @@ export default {
.active { .active {
&.link { &.link {
border-color: $link-color border-color: $link-color;
} }
&.icon--heart { &.icon--heart {

View File

@@ -1,5 +1,5 @@
<template> <template>
<div> <div id="camera-stream">
<h2 v-if="errorMessage">{{ errorMessage }}</h2> <h2 v-if="errorMessage">{{ errorMessage }}</h2>
<video playsinline autoplay class="hidden"></video> <video playsinline autoplay class="hidden"></video>
</div> </div>
@@ -47,13 +47,8 @@ export default {
this.searchVideoForBarcode(this.video); this.searchVideoForBarcode(this.video);
}, },
handleError(error) { handleError(error) {
console.log( console.log("navigator.MediaDevices.getUserMedia error: ", error.message, error.name);
"navigator.MediaDevices.getUserMedia error: ", this.errorMessage = "Feil ved oppstart av kamera! Feilmelding: " + error.message;
error.message,
error.name
);
this.errorMessage =
"Feil ved oppstart av kamera! Feilmelding: " + error.message;
}, },
searchVideoForBarcode(video) { searchVideoForBarcode(video) {
const codeReader = new BrowserBarcodeReader(); const codeReader = new BrowserBarcodeReader();
@@ -84,10 +79,7 @@ export default {
this.errorMessage = "Feil! " + error.message || error; this.errorMessage = "Feil! " + error.message || error;
}, },
scrollIntoView() { scrollIntoView() {
window.scrollTo( window.scrollTo(0, document.getElementById("camera-stream").offsetTop - 10);
0,
document.getElementById("addwine-title").offsetTop - 10
);
} }
} }
}; };

View File

@@ -2,10 +2,7 @@
<div class="wine"> <div class="wine">
<slot name="top"></slot> <slot name="top"></slot>
<div class="wine-image"> <div class="wine-image">
<img <img v-if="wine.image && loadImage" :src="wine.image" />
v-if="wine.image && loadImage"
:src="wine.image"
/>
<img v-else class="wine-placeholder" alt="Wine image" /> <img v-else class="wine-placeholder" alt="Wine image" />
</div> </div>
@@ -38,7 +35,7 @@ export default {
data() { data() {
return { return {
loadImage: false loadImage: false
} };
}, },
methods: { methods: {
setImage(entries) { setImage(entries) {
@@ -53,7 +50,7 @@ export default {
this.observer = new IntersectionObserver(this.setImage, { this.observer = new IntersectionObserver(this.setImage, {
root: this.$el, root: this.$el,
threshold: 0 threshold: 0
}) });
}, },
mounted() { mounted() {
this.observer.observe(this.$el); this.observer.observe(this.$el);
@@ -66,16 +63,17 @@ export default {
@import "@/styles/variables"; @import "@/styles/variables";
.wine { .wine {
align-self: flex-start;
padding: 1rem; padding: 1rem;
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
-webkit-box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.15); -webkit-box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.15);
box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.15); box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.15);
width: 100%;
@include tablet { @include tablet {
width: 250px; max-width: 280px;
height: 100%;
} }
} }
@@ -85,19 +83,18 @@ export default {
margin-top: 10px; margin-top: 10px;
img { img {
height: 250px; height: 280px;
@include mobile { @include mobile {
object-fit: cover; object-fit: cover;
max-width: 90px; max-width: 90px;
} }
} }
.wine-placeholder { .wine-placeholder {
height: 250px; height: 280px;
width: 70px; width: 70px;
} }
} }
.wine-details { .wine-details {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -120,6 +117,7 @@ export default {
.bottom-section { .bottom-section {
width: 100%; width: 100%;
margin-top: 1rem; margin-top: 1rem;
align-self: flex-end;
.link { .link {
color: $matte-text-color; color: $matte-text-color;

View File

@@ -85,9 +85,7 @@ export default {
this.startConfetti(this.currentName); this.startConfetti(this.currentName);
return; return;
} }
this.currentName = this.attendees[ this.currentName = this.attendees[this.nameRounds % this.attendees.length].name;
this.nameRounds % this.attendees.length
].name;
this.nameRounds += 1; this.nameRounds += 1;
clearTimeout(this.nameTimeout); clearTimeout(this.nameTimeout);
this.nameTimeout = setTimeout(() => { this.nameTimeout = setTimeout(() => {
@@ -137,7 +135,7 @@ export default {
var duration = 7 * 1000; var duration = 7 * 1000;
var animationEnd = Date.now() + duration; var animationEnd = Date.now() + duration;
var defaults = { startVelocity: 50, spread: 160, ticks: 50, zIndex: 0, particleCount: 20 }; var defaults = { startVelocity: 50, spread: 160, ticks: 50, zIndex: 0, particleCount: 20 };
var uberDefaults = { startVelocity: 65, spread: 75, zIndex: 0, particleCount: 35} var uberDefaults = { startVelocity: 65, spread: 75, zIndex: 0, particleCount: 35 };
function randomInRange(min, max) { function randomInRange(min, max) {
return Math.random() * (max - min) + min; return Math.random() * (max - min) + min;
@@ -148,7 +146,7 @@ export default {
var timeLeft = animationEnd - Date.now(); var timeLeft = animationEnd - Date.now();
if (timeLeft <= 0) { if (timeLeft <= 0) {
self.drawing = false; self.drawing = false;
console.time("drawing finished") console.time("drawing finished");
return clearInterval(interval); return clearInterval(interval);
} }
if (currentName == "Amund Brandsrud") { if (currentName == "Amund Brandsrud") {
@@ -165,7 +163,7 @@ export default {
}, 250); }, 250);
function runCannon(confettiDefaultValues, originPoint, launchAngle) { function runCannon(confettiDefaultValues, originPoint, launchAngle) {
confetti(Object.assign({}, confettiDefaultValues, {origin: originPoint }, launchAngle)) confetti(Object.assign({}, confettiDefaultValues, { origin: originPoint }, launchAngle));
} }
}, },
ordinalNumber(number = this.currentWinnerLocal.winnerCount) { ordinalNumber(number = this.currentWinnerLocal.winnerCount) {
@@ -187,7 +185,6 @@ export default {
} }
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -1,9 +1,9 @@
<template> <template>
<section> <section>
<h2>{{ title ? title : 'Vinnere' }}</h2> <h2>{{ title ? title : "Vinnere" }}</h2>
<div class="winning-raffles" v-if="winners.length > 0"> <div class="winning-raffles" v-if="winners.length > 0">
<div v-for="(winner, index) in winners" :key="index"> <div v-for="(winner, index) in winners" :key="index">
<router-link :to="`/highscore/${ encodeURIComponent(winner.name) }`"> <router-link :to="`/highscore/${winner.name}`">
<div :class="winner.color + '-raffle'" class="raffle-element">{{ winner.name }}</div> <div :class="winner.color + '-raffle'" class="raffle-element">{{ winner.name }}</div>
</router-link> </router-link>
</div> </div>
@@ -26,7 +26,7 @@ export default {
type: Array type: Array
}, },
drawing: { drawing: {
type: Boolean, type: Boolean
}, },
title: { title: {
type: String, type: String,

View File

@@ -1,17 +1,16 @@
const dateString = date => {
const dateString = (date) => { if (typeof date == "string") {
if (typeof(date) == "string") {
date = new Date(date); date = new Date(date);
} }
const ye = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(date) const ye = new Intl.DateTimeFormat("en", { year: "numeric" }).format(date);
const mo = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(date) const mo = new Intl.DateTimeFormat("en", { month: "2-digit" }).format(date);
const da = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date) const da = new Intl.DateTimeFormat("en", { day: "2-digit" }).format(date);
return `${ye}-${mo}-${da}` return `${ye}-${mo}-${da}`;
} };
function humanReadableDate(date) { function humanReadableDate(date) {
const options = { year: 'numeric', month: 'long', day: 'numeric' }; const options = { year: "numeric", month: "long", day: "numeric" };
return new Date(date).toLocaleDateString(undefined, options); return new Date(date).toLocaleDateString(undefined, options);
} }
@@ -20,8 +19,4 @@ function daysAgo(date) {
return Math.round(Math.abs((new Date() - new Date(date)) / day)); return Math.round(Math.abs((new Date() - new Date(date)) / day));
} }
export { export { dateString, humanReadableDate, daysAgo };
dateString,
humanReadableDate,
daysAgo
}

View File

@@ -12,34 +12,33 @@ const ENV = window.location.href.includes("localhost") ? "development" : "produc
if (ENV !== "development") { if (ENV !== "development") {
Sentry.init({ Sentry.init({
dsn: "https://7debc951f0074fb68d7a76a1e3ace6fa@o364834.ingest.sentry.io/4905091", dsn: "https://7debc951f0074fb68d7a76a1e3ace6fa@o364834.ingest.sentry.io/4905091",
integrations: [ integrations: [new VueIntegration({ Vue })],
new VueIntegration({ Vue })
],
beforeSend: event => { beforeSend: event => {
console.error(event); console.error(event);
return event; return event;
} }
}) });
} }
// Add global GA variables // Add global GA variables
window.ga = window.ga || function(){ window.ga =
window.ga ||
function() {
window.ga.q = window.ga.q || []; window.ga.q = window.ga.q || [];
window.ga.q.push(arguments); window.ga.q.push(arguments);
}; };
ga.l = 1 * new Date(); ga.l = 1 * new Date();
// Initiate // Initiate
ga('create', __GA_TRACKINGID__, { ga("create", __GA_TRACKINGID__, {
'allowAnchor': false, allowAnchor: false,
'cookieExpires': __GA_COOKIELIFETIME__, // Time in seconds cookieExpires: __GA_COOKIELIFETIME__, // Time in seconds
'cookieFlags': 'SameSite=Strict; Secure' cookieFlags: "SameSite=Strict; Secure"
}); });
ga('set', 'anonymizeIp', true); // Enable IP Anonymization/IP masking ga("set", "anonymizeIp", true); // Enable IP Anonymization/IP masking
ga('send', 'pageview'); ga("send", "pageview");
if (ENV == 'development') if (ENV == "development") window[`ga-disable-${__GA_TRACKINGID__}`] = true;
window[`ga-disable-${__GA_TRACKINGID__}`] = true;
const router = new VueRouter({ const router = new VueRouter({
routes: routes routes: routes