refactor(static): split schedule and weather to modules
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
export class DataStorage<T extends { id: string }> {
|
||||||
|
constructor(private storageKey: string) {}
|
||||||
|
|
||||||
|
private readValues(): T[] {
|
||||||
|
const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "[]");
|
||||||
|
if (!Array.isArray(objects)) {
|
||||||
|
return Object.values(objects);
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private writeValues(values: T[]) {
|
||||||
|
window.localStorage.setItem(this.storageKey, JSON.stringify(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
getAll(): T[] {
|
||||||
|
return this.readValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
add(value: T) {
|
||||||
|
const values = this.readValues();
|
||||||
|
for (const v of values) {
|
||||||
|
if (v.id == value.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
values.push(value);
|
||||||
|
this.writeValues(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(id: string) {
|
||||||
|
const values = this.readValues();
|
||||||
|
for (let i = 0; i < values.length; i++) {
|
||||||
|
if (values[i].id == id) {
|
||||||
|
values.splice(i, 1);
|
||||||
|
this.writeValues(values);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,50 +1,6 @@
|
|||||||
export interface Channel {
|
import { Channel } from "./model";
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
provider: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ScheduleChannelStorage {
|
export class ScheduleChannelElement extends HTMLElement {
|
||||||
private storageKey: string = "schedule:channels";
|
|
||||||
|
|
||||||
getAll(): Channel[] {
|
|
||||||
const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
|
|
||||||
return Object.values(objects);
|
|
||||||
}
|
|
||||||
|
|
||||||
add(object: Channel) {
|
|
||||||
const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
|
|
||||||
objects[object.id] = object;
|
|
||||||
window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(id: string) {
|
|
||||||
const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
|
|
||||||
delete objects[id];
|
|
||||||
window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ScheduleChannelManager {
|
|
||||||
loadChannels(selector: string) {
|
|
||||||
const channels = window.scheduleChannelStorage.getAll();
|
|
||||||
const container = document.querySelector(selector);
|
|
||||||
if (container) {
|
|
||||||
container.innerHTML = "";
|
|
||||||
for (const channel of channels) {
|
|
||||||
const element = new ScheduleChannelElement();
|
|
||||||
element.setAttribute("channel", JSON.stringify(channel));
|
|
||||||
element.setAttribute("removable", "");
|
|
||||||
container.appendChild(element);
|
|
||||||
}
|
|
||||||
const groupElement = new ScheduleChannelGroupElement();
|
|
||||||
groupElement.setAttribute("channels", JSON.stringify(channels));
|
|
||||||
container.append(groupElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ScheduleChannelElement extends HTMLElement {
|
|
||||||
static observedAttributes = ["channel", "removable"];
|
static observedAttributes = ["channel", "removable"];
|
||||||
|
|
||||||
channel: Channel | null = null;
|
channel: Channel | null = null;
|
||||||
@@ -100,9 +56,7 @@ class ScheduleChannelElement extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("schedule-channel", ScheduleChannelElement);
|
export class ScheduleChannelGroupElement extends HTMLElement {
|
||||||
|
|
||||||
class ScheduleChannelGroupElement extends HTMLElement {
|
|
||||||
static observedAttributes = ["channels"];
|
static observedAttributes = ["channels"];
|
||||||
|
|
||||||
channels: Channel[] | null = null;
|
channels: Channel[] | null = null;
|
||||||
@@ -124,14 +78,6 @@ class ScheduleChannelGroupElement extends HTMLElement {
|
|||||||
this.classList = "list-group-item list-group-item-action";
|
this.classList = "list-group-item list-group-item-action";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
customElements.define("schedule-channel", ScheduleChannelElement);
|
||||||
customElements.define("schedule-channel-group", ScheduleChannelGroupElement);
|
customElements.define("schedule-channel-group", ScheduleChannelGroupElement);
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
scheduleChannelStorage: ScheduleChannelStorage;
|
|
||||||
scheduleChannelManager: ScheduleChannelManager;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.scheduleChannelStorage = new ScheduleChannelStorage();
|
|
||||||
window.scheduleChannelManager = new ScheduleChannelManager();
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import { DataStorage } from "../base/storage";
|
||||||
|
import { ScheduleChannelElement, ScheduleChannelGroupElement } from "./component";
|
||||||
|
import { Channel } from "./model";
|
||||||
|
|
||||||
|
export class ScheduleChannelManager {
|
||||||
|
loadChannels(selector: string) {
|
||||||
|
const channels = window.scheduleChannelStorage.getAll();
|
||||||
|
const container = document.querySelector(selector);
|
||||||
|
if (container) {
|
||||||
|
container.innerHTML = "";
|
||||||
|
for (const channel of channels) {
|
||||||
|
const element = new ScheduleChannelElement();
|
||||||
|
element.setAttribute("channel", JSON.stringify(channel));
|
||||||
|
element.setAttribute("removable", "");
|
||||||
|
container.appendChild(element);
|
||||||
|
}
|
||||||
|
const groupElement = new ScheduleChannelGroupElement();
|
||||||
|
groupElement.setAttribute("channels", JSON.stringify(channels));
|
||||||
|
container.append(groupElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
scheduleChannelStorage: DataStorage<Channel>;
|
||||||
|
scheduleChannelManager: ScheduleChannelManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.scheduleChannelStorage = new DataStorage("schedule:channels");
|
||||||
|
window.scheduleChannelManager = new ScheduleChannelManager();
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export interface Channel {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
provider: string;
|
||||||
|
}
|
||||||
@@ -1,51 +1,6 @@
|
|||||||
export interface Location {
|
import { Location } from "./model";
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
provider: string;
|
|
||||||
country_code: string;
|
|
||||||
country?: string;
|
|
||||||
district?: string;
|
|
||||||
subdistrict?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WeatherLocationStorage {
|
export class WeatherLocationElement extends HTMLElement {
|
||||||
private storageKey: string = "weather:locations";
|
|
||||||
|
|
||||||
getAll(): Location[] {
|
|
||||||
const locations = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
|
|
||||||
return Object.values(locations);
|
|
||||||
}
|
|
||||||
|
|
||||||
add(location: Location) {
|
|
||||||
const locations = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
|
|
||||||
locations[location.id] = location;
|
|
||||||
window.localStorage.setItem(this.storageKey, JSON.stringify(locations));
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(id: string) {
|
|
||||||
const locations = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
|
|
||||||
delete locations[id];
|
|
||||||
window.localStorage.setItem(this.storageKey, JSON.stringify(locations));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WeatherLocationManager {
|
|
||||||
loadLocations(selector: string) {
|
|
||||||
const locations = window.weatherLocationStorage.getAll();
|
|
||||||
const container = document.querySelector(selector);
|
|
||||||
if (container) {
|
|
||||||
container.innerHTML = "";
|
|
||||||
for (const location of locations) {
|
|
||||||
const element = new WeatherLocationElement();
|
|
||||||
element.setAttribute("location", JSON.stringify(location));
|
|
||||||
element.setAttribute("removable", "");
|
|
||||||
container.appendChild(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WeatherLocationElement extends HTMLElement {
|
|
||||||
static observedAttributes = ["location", "removable"];
|
static observedAttributes = ["location", "removable"];
|
||||||
|
|
||||||
location: Location | null = null;
|
location: Location | null = null;
|
||||||
@@ -75,7 +30,7 @@ class WeatherLocationElement extends HTMLElement {
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</a>`;
|
</a>`;
|
||||||
this.classList = 'list-group-item list-group-item-action';
|
this.classList = "list-group-item list-group-item-action";
|
||||||
this.addEventListener("click", this.handleClick);
|
this.addEventListener("click", this.handleClick);
|
||||||
if (this.hasAttribute("removable")) {
|
if (this.hasAttribute("removable")) {
|
||||||
this.querySelector<HTMLElement>("[data-remove]")?.addEventListener("click", this.handleRemoveClick);
|
this.querySelector<HTMLElement>("[data-remove]")?.addEventListener("click", this.handleRemoveClick);
|
||||||
@@ -106,13 +61,3 @@ class WeatherLocationElement extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("weather-location", WeatherLocationElement);
|
customElements.define("weather-location", WeatherLocationElement);
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
weatherLocationStorage: WeatherLocationStorage;
|
|
||||||
weatherLocationManager: WeatherLocationManager;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.weatherLocationStorage = new WeatherLocationStorage();
|
|
||||||
window.weatherLocationManager = new WeatherLocationManager();
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { DataStorage } from "../base/storage";
|
||||||
|
import { WeatherLocationElement } from "./component";
|
||||||
|
import { Location } from "./model";
|
||||||
|
|
||||||
|
export class WeatherLocationManager {
|
||||||
|
loadLocations(selector: string) {
|
||||||
|
const locations = window.weatherLocationStorage.getAll();
|
||||||
|
const container = document.querySelector(selector);
|
||||||
|
if (container) {
|
||||||
|
container.innerHTML = "";
|
||||||
|
for (const location of locations) {
|
||||||
|
const element = new WeatherLocationElement();
|
||||||
|
element.setAttribute("location", JSON.stringify(location));
|
||||||
|
element.setAttribute("removable", "");
|
||||||
|
container.appendChild(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
weatherLocationStorage: DataStorage<Location>;
|
||||||
|
weatherLocationManager: WeatherLocationManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.weatherLocationStorage = new DataStorage("weather:locations");
|
||||||
|
window.weatherLocationManager = new WeatherLocationManager();
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export interface Location {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
provider: string;
|
||||||
|
country_code: string;
|
||||||
|
country?: string;
|
||||||
|
district?: string;
|
||||||
|
subdistrict?: string;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user