Skip to content

Commit

Permalink
Add translations
Browse files Browse the repository at this point in the history
  • Loading branch information
bloomlive authored Jul 4, 2023
2 parents e1b2711 + 211a779 commit 0385212
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 118 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

Actually only adds a select field to choose calendar type (ICS by default) and a small "+" anchor link to every concert in the schedule that allows you to add the concert to your calendar. Fills in all the details I deemed needed, but you can always edit the event in your calendar afterwards.

Supports both Estonian and English versions of the schedule (based on user's preference on the website).

## Installation
1. Clone the repository
2. `pnpm install` (or yarn or npm)
Expand All @@ -14,7 +16,7 @@ Actually only adds a select field to choose calendar type (ICS by default) and a
5. Go to `chrome://extensions/`
6. Enable "Developer mode"
7. Click "Load unpacked extension..."
8. Select the folder where you cloned the repository
8. Select the `dist` folder in the root of the project (ignored on Git)
9. Go to [Viljandi Folk schedule](https://www.viljandifolk.ee/en/schedule/) and see a "+" on the top left of every concert

If you use watch, changes will be reloaded only when you press "Update" in Google Chrome.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"webpack-cli": "^5.1.4"
},
"dependencies": {
"calendar-link": "^2.4.0"
"calendar-link": "^2.4.0",
"i18n-js": "^4.2.3"
}
}
22 changes: 22 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

234 changes: 118 additions & 116 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -1,155 +1,157 @@
import { CalendarEvent, google, ics, office365, outlook, yahoo } from "calendar-link";
import { IEventFileType } from "../types/IEventFileType";
import { CalendarEvent, google, ics, office365, outlook, yahoo } from 'calendar-link'
import useI18n from './usei18n'

const rows = document.querySelectorAll(".event-row");
import type { IEventFileType } from '../types/IEventFileType'
import type { ILanguage } from '../types/ILanguage'
import usei18n from './usei18n'

let currentType: IEventFileType = "ics";
const rows = document.querySelectorAll('.event-row')

const locations = new Map<number, string>()
.set(4936143, "Kaevumägi")
.set(4936141, "I Kirsimägi")
.set(4936142, "II Kirsimägi")
.set(4936144, "Laululava")
.set(4936145, "Aida suur saal")
.set(4936147, "Jaani kirik")
.set(4936149, "Babtistikirik")
.set(4938876, "Jaak Johansoni Kultra lava");
let currentType: IEventFileType = 'ics'

const currentLanguage: ILanguage = document.querySelector('html')!.getAttribute('lang')! as ILanguage

useI18n.locale = currentLanguage

const linkType = new Map<IEventFileType, string>()
.set("ics", "iCal")
.set("google", "Google Calendar")
.set("yahoo", "Yahoo Calendar")
.set("outlook", "Outlook.com")
.set("office365", "Office 365");
.set('ics', useI18n.t('formats.ics'))
.set('google', 'Google Calendar')
.set('yahoo', 'Yahoo Calendar')
.set('outlook', 'Outlook.com')
.set('office365', 'Office 365')

function createButton(): HTMLElement {
const button = document.createElement("a");
const button = document.createElement('a')

button.style.position = "absolute";
button.style.fontWeight = "medium";
button.style.background = "none";
button.style.border = "none";
button.style.padding = "4px";
button.style.fontSize = "1rem";
button.style.cursor = "pointer";
button.innerText = "+";
button.style.position = 'absolute'
button.style.fontWeight = 'medium'
button.style.background = 'none'
button.style.border = 'none'
button.style.padding = '4px'
button.style.fontSize = '1rem'
button.style.cursor = 'pointer'
button.innerText = '+'

styleButtonResponsive(isMobile(), button);
styleButtonResponsive(isMobile(), button)

return button;
return button
}

function isMobile(): boolean {
return window.innerWidth < 993;
return window.innerWidth < 993
}

function getEventData(row: Element): CalendarEvent {
const start = row.getAttribute("data-box-start");
const duration = Number((row as HTMLElement).style.height?.replace("px", "")) / 80;

const startTime = new Date(Number(start) * 1000);
const endTime = new Date(Number(start) * 1000 + duration * 60 * 60 * 1000);

if (startTime.getHours() < 6) {
startTime.setDate(startTime.getDate() + 1);
endTime.setDate(endTime.getDate() + 1);
}

return {
title: row.querySelector(".title")?.querySelector("div")?.textContent?.trim() ?? "Something went wrong.",
description: "Vaata rohkem siit: " + row.querySelector("a")?.href ?? "https://www.viljandifolk.ee/",
start: startTime,
end: endTime,
location: location
? locations.get(Number(row.parentElement?.parentElement?.parentElement?.getAttribute("data-id")))
: "Viljandi Pärimusmuusika Festival"
};
const start = row.getAttribute('data-box-start')
const duration = Number((row as HTMLElement).style.height?.replace('px', '')) / 80

const startTime = new Date(Number(start) * 1000)
const endTime = new Date(Number(start) * 1000 + duration * 60 * 60 * 1000)

if (startTime.getHours() < 6) {
startTime.setDate(startTime.getDate() + 1)
endTime.setDate(endTime.getDate() + 1)
}

return {
title: row.querySelector('.title')?.querySelector('div')?.textContent?.trim() ?? useI18n.t('error'),
description:
useI18n.t('description.prefix') + ': ' + row.querySelector('a')?.href ?? 'https://www.viljandifolk.ee/',
start: startTime,
end: endTime,
location: location
? usei18n.t('stages.' + Number(row.parentElement?.parentElement?.parentElement?.getAttribute('data-id')))
: useI18n.t('stages.default')
}
}

function createEventHref(row: Element): string {
const data = getEventData(row);

switch (currentType) {
case "google":
return google(data);
case "yahoo":
return yahoo(data);
case "outlook":
return outlook(data);
case "office365":
return office365(data);
case "ics":
return ics(data);
default:
return ics(data);
}
const data = getEventData(row)

switch (currentType) {
case 'google':
return google(data)
case 'yahoo':
return yahoo(data)
case 'outlook':
return outlook(data)
case 'office365':
return office365(data)
case 'ics':
return ics(data)
default:
return ics(data)
}
}

function styleButtonResponsive(isMobile: boolean, button: HTMLElement) {
button.style.left = isMobile ? "10px" : "0";
button.style.top = isMobile ? "0" : "0";
button.style.left = isMobile ? '10px' : '0'
button.style.top = isMobile ? '0' : '0'
}

function addSelector() {
const element = document.querySelector(".nav-links.d-flex");
const selector = document.createElement("select");
selector.setAttribute("id", "calendar-link-selector");
selector.style.marginBottom = "12px";
selector.style.fontSize = "1rem";

linkType.forEach((value, key) => {
const option = document.createElement("option");
option.value = key;
option.text = value;
selector.appendChild(option);
});

selector.addEventListener("change", function() {
currentType = this.value as IEventFileType;
document.querySelectorAll('.calendar-link-add').forEach((link: Element) => {
link.parentElement?.removeChild(link)
const element = document.querySelector('.nav-links.d-flex')
const selector = document.createElement('select')
selector.setAttribute('id', 'calendar-link-selector')
selector.style.marginBottom = '12px'
selector.style.fontSize = '1rem'

linkType.forEach((value, key) => {
const option = document.createElement('option')
option.value = key
option.text = value
selector.appendChild(option)
})

selector.addEventListener('change', function () {
currentType = this.value as IEventFileType
document.querySelectorAll('.calendar-link-add').forEach((link: Element) => {
link.parentElement?.removeChild(link)
})

createAddButtons()
})

createAddButtons();
});

if (element) {
element.after(selector);
const label = document.createElement("label");
label.setAttribute("for", "calendar-link-selector");
label.innerText = "Vali kalendri tüüp: ";
label.style.marginRight = "4px";
selector.before(label);
}
if (element) {
element.after(selector)
const label = document.createElement('label')
label.setAttribute('for', 'calendar-link-selector')
label.innerText = useI18n.t('calendarTypeLabel') + ' '
label.style.marginRight = '4px'
selector.before(label)
}
}

function createAddButtons() {
rows.forEach((row: Element) => {
;(row as HTMLElement).style.position = "relative";
rows.forEach((row: Element) => {
;(row as HTMLElement).style.position = 'relative'

const button = createButton();
const button = createButton()

button.classList.add('calendar-link-add')
button.classList.add('calendar-link-add')

button.setAttribute('href', createEventHref(row));
button.setAttribute('target', '_blank')
button.setAttribute("download", row.querySelector(".title")?.querySelector("div")?.textContent?.trim()! + ".ics");
button.setAttribute('href', createEventHref(row))
button.setAttribute('target', '_blank')
button.setAttribute(
'download',
row.querySelector('.title')?.querySelector('div')?.textContent?.trim()! + '.ics'
)

row.querySelector("a")?.after(button);
row.querySelector('a')?.after(button)

window.addEventListener("resize", () => {
styleButtonResponsive(isMobile(), button);
});
window.addEventListener('resize', () => {
styleButtonResponsive(isMobile(), button)
})

button.addEventListener("mouseenter", () => {
button.style.color = "#b31b34";
});
button.addEventListener('mouseenter', () => {
button.style.color = '#b31b34'
})

button.addEventListener("mouseleave", () => {
button.style.color = "black";
});
});
button.addEventListener('mouseleave', () => {
button.style.color = 'black'
})
})
}

addSelector();
createAddButtons();
addSelector()
createAddButtons()
Loading

0 comments on commit 0385212

Please sign in to comment.