mirror of
https://github.com/comatory/fb2iCal
synced 2025-01-30 17:04:48 +01:00
separate front end into modules for easier refactoring later
This commit is contained in:
parent
c336f6998b
commit
6b7c0f8454
87
lib/static/app/storage.js
Normal file
87
lib/static/app/storage.js
Normal file
@ -0,0 +1,87 @@
|
||||
import { useStorage } from './utils'
|
||||
|
||||
const migrateRecord = (record) => {
|
||||
// NOTE: v3 records
|
||||
const id = record.id || record.order
|
||||
const startTime = record.startTime || null
|
||||
|
||||
return {
|
||||
...record,
|
||||
id,
|
||||
startTime,
|
||||
}
|
||||
}
|
||||
|
||||
const getStorage = () => {
|
||||
if (!useStorage()) {
|
||||
return null
|
||||
}
|
||||
|
||||
const storage = localStorage.getItem('fb-to-ical-events')
|
||||
|
||||
if (!storage) {
|
||||
localStorage.setItem('fb-to-ical-events', JSON.stringify([]))
|
||||
return "[]"
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
const getStorageContents = (storage) => {
|
||||
return JSON.parse(storage)
|
||||
}
|
||||
|
||||
const updateStorage = (storageContents) => {
|
||||
const encodedStorage = JSON.stringify(storageContents)
|
||||
|
||||
localStorage.setItem('fb-to-ical-events', encodedStorage)
|
||||
}
|
||||
|
||||
const saveRecord = ({ id, link, createdAt, startTime, title }) => {
|
||||
if (!useStorage()) {
|
||||
return
|
||||
}
|
||||
|
||||
const storage = getStorage()
|
||||
const storageContents = getStorageContents(storage)
|
||||
|
||||
const record = {
|
||||
id,
|
||||
link,
|
||||
createdAt: createdAt.toString(),
|
||||
startTime: startTime.toString(),
|
||||
title,
|
||||
}
|
||||
|
||||
updateStorage([ ...storageContents, record ])
|
||||
}
|
||||
|
||||
const deleteRecord = (id) => {
|
||||
if (!useStorage()) {
|
||||
return
|
||||
}
|
||||
|
||||
const storage = getStorage()
|
||||
const storageContents = getStorageContents(storage)
|
||||
const index = storageContents.findIndex((record) => {
|
||||
return record.id === id
|
||||
})
|
||||
|
||||
if (!Number.isFinite(index)) {
|
||||
return
|
||||
}
|
||||
|
||||
const nextStorage = [ ...storageContents ]
|
||||
nextStorage.splice(index, 1)
|
||||
|
||||
updateStorage(nextStorage)
|
||||
}
|
||||
|
||||
export {
|
||||
migrateRecord,
|
||||
getStorage,
|
||||
getStorageContents,
|
||||
updateStorage,
|
||||
saveRecord,
|
||||
deleteRecord,
|
||||
}
|
35
lib/static/app/utils.js
Normal file
35
lib/static/app/utils.js
Normal file
@ -0,0 +1,35 @@
|
||||
const noJS = () => {
|
||||
return Boolean(document.querySelector("#nojs").checked)
|
||||
}
|
||||
|
||||
const useStorage = () => Boolean(window.localStorage)
|
||||
|
||||
// NOTE: Generate random IDs: https://stackoverflow.com/a/2117523/3056783
|
||||
const uuidv4 = () => {
|
||||
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||
)
|
||||
}
|
||||
|
||||
const parseStartTimeFromiCalString = (text = '') => {
|
||||
const [ dateStr, timeStr ] = text.split('T')
|
||||
const rawDate = dateStr || ''
|
||||
const rawTime = timeStr || ''
|
||||
|
||||
const year = Number(rawDate.slice(0, 4))
|
||||
const month = Number(Math.max(rawDate.slice(4, 6) - 1), 0)
|
||||
const date = Number(rawDate.slice(6, 8))
|
||||
const hour = Number(rawTime.slice(0, 2))
|
||||
const minutes = Number(rawTime.slice(2, 4))
|
||||
const seconds = Number(rawTime.slice(4, 6))
|
||||
|
||||
const parsedDate = new Date(year, month, date, hour, minutes, seconds)
|
||||
return parsedDate.toString()
|
||||
}
|
||||
|
||||
export {
|
||||
noJS,
|
||||
uuidv4,
|
||||
parseStartTimeFromiCalString,
|
||||
useStorage,
|
||||
}
|
@ -1,115 +1,19 @@
|
||||
import { noJS, uuidv4, parseStartTimeFromiCalString, useStorage } from './app/utils'
|
||||
import {
|
||||
migrateRecord,
|
||||
getStorage,
|
||||
getStorageContents,
|
||||
updateStorage,
|
||||
saveRecord,
|
||||
deleteRecord,
|
||||
} from './app/storage'
|
||||
|
||||
(() => {
|
||||
const noJS = () => {
|
||||
return Boolean(document.querySelector("#nojs").checked)
|
||||
}
|
||||
|
||||
const useStorage = Boolean(window.localStorage)
|
||||
|
||||
if (!window.fetch || !window.Promise || !window.URLSearchParams || !window.crypto) {
|
||||
console.info('JS features not available.')
|
||||
console.warn('JS features not available.')
|
||||
return
|
||||
}
|
||||
|
||||
// NOTE: Generate random IDs: https://stackoverflow.com/a/2117523/3056783
|
||||
const uuidv4 = () => {
|
||||
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||
)
|
||||
}
|
||||
|
||||
const parseStartTimeFromiCalString = (text = '') => {
|
||||
const [ dateStr, timeStr ] = text.split('T')
|
||||
const rawDate = dateStr || ''
|
||||
const rawTime = timeStr || ''
|
||||
|
||||
const year = Number(rawDate.slice(0, 4))
|
||||
const month = Number(Math.max(rawDate.slice(4, 6) - 1), 0)
|
||||
const date = Number(rawDate.slice(6, 8))
|
||||
const hour = Number(rawTime.slice(0, 2))
|
||||
const minutes = Number(rawTime.slice(2, 4))
|
||||
const seconds = Number(rawTime.slice(4, 6))
|
||||
|
||||
const parsedDate = new Date(year, month, date, hour, minutes, seconds)
|
||||
return parsedDate.toString()
|
||||
}
|
||||
|
||||
const migrateRecord = (record) => {
|
||||
// NOTE: v3 records
|
||||
const id = record.id || record.order
|
||||
const startTime = record.startTime || null
|
||||
|
||||
return {
|
||||
...record,
|
||||
id,
|
||||
startTime,
|
||||
}
|
||||
}
|
||||
|
||||
const getStorage = () => {
|
||||
if (!useStorage) {
|
||||
return null
|
||||
}
|
||||
|
||||
const storage = localStorage.getItem('fb-to-ical-events')
|
||||
|
||||
if (!storage) {
|
||||
localStorage.setItem('fb-to-ical-events', JSON.stringify([]))
|
||||
return "[]"
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
const getStorageContents = (storage) => {
|
||||
return JSON.parse(storage)
|
||||
}
|
||||
|
||||
const updateStorage = (storageContents) => {
|
||||
const encodedStorage = JSON.stringify(storageContents)
|
||||
|
||||
localStorage.setItem('fb-to-ical-events', encodedStorage)
|
||||
}
|
||||
|
||||
const saveRecord = ({ id, link, createdAt, startTime, title }) => {
|
||||
if (!useStorage) {
|
||||
return
|
||||
}
|
||||
|
||||
const storage = getStorage()
|
||||
const storageContents = getStorageContents(storage)
|
||||
|
||||
const record = {
|
||||
id,
|
||||
link,
|
||||
createdAt: createdAt.toString(),
|
||||
startTime: startTime.toString(),
|
||||
title,
|
||||
}
|
||||
|
||||
updateStorage([ ...storageContents, record ])
|
||||
}
|
||||
|
||||
const deleteRecord = (id) => {
|
||||
if (!useStorage) {
|
||||
return
|
||||
}
|
||||
|
||||
const storage = getStorage()
|
||||
const storageContents = getStorageContents(storage)
|
||||
const index = storageContents.findIndex((record) => {
|
||||
return record.id === id
|
||||
})
|
||||
|
||||
if (!Number.isFinite(index)) {
|
||||
return
|
||||
}
|
||||
|
||||
const nextStorage = [ ...storageContents ]
|
||||
nextStorage.splice(index, 1)
|
||||
|
||||
updateStorage(nextStorage)
|
||||
}
|
||||
|
||||
const showTable = () => {
|
||||
list.classList.remove('hidden')
|
||||
}
|
||||
@ -117,7 +21,7 @@
|
||||
const deleteTableRow = (id, row) => {
|
||||
deleteRecord(id)
|
||||
|
||||
if (!useStorage) {
|
||||
if (!useStorage()) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -182,7 +86,7 @@
|
||||
}
|
||||
|
||||
const hydrateList = () => {
|
||||
if (!useStorage) {
|
||||
if (!useStorage()) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -295,7 +199,7 @@
|
||||
const noJScheckbox = document.querySelector('#nojs')
|
||||
|
||||
const loadNoJS = () => {
|
||||
if (!useStorage) {
|
||||
if (!useStorage()) {
|
||||
return
|
||||
}
|
||||
const value = localStorage.getItem('fb-to-ical-nojs')
|
||||
@ -343,7 +247,7 @@
|
||||
}
|
||||
|
||||
noJScheckbox.addEventListener('click', (event) => {
|
||||
if (!useStorage) {
|
||||
if (!useStorage()) {
|
||||
return
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ const destination = path.join(__dirname, 'dist')
|
||||
const isDevelopment = Boolean(process.argv[2] && process.argv[2].includes('mode=development'))
|
||||
|
||||
module.exports = {
|
||||
entry: path.join(__dirname, 'lib', 'static', 'scripts.js'),
|
||||
entry: path.join(__dirname, 'lib', 'static', 'index.js'),
|
||||
watch: isDevelopment,
|
||||
output: {
|
||||
filename: '[name].[hash].js',
|
||||
|
Loading…
x
Reference in New Issue
Block a user