From 9aa1b9fe501384f00c74dc80361f432d6a8aead0 Mon Sep 17 00:00:00 2001 From: freearhey <7253922+freearhey@users.noreply.github.com> Date: Fri, 7 Mar 2025 04:27:23 +0300 Subject: [PATCH] Create Channel model --- src/components/BlockedBadge.svelte | 2 +- src/components/ChannelItem.svelte | 17 ++-- src/components/ChannelPopup.svelte | 2 +- src/components/EditButton.svelte | 2 +- src/components/HTMLPreview.svelte | 10 +-- src/components/SearchSyntaxPopup.svelte | 8 +- src/models/channel.js | 44 +++++++++++ src/models/index.js | 1 + src/pages/+page.svelte | 2 +- .../channels/[country]/[name]/+page.svelte | 13 ++-- src/store.js | 78 ++++++++++++------- 11 files changed, 123 insertions(+), 56 deletions(-) create mode 100644 src/models/channel.js create mode 100644 src/models/index.js diff --git a/src/components/BlockedBadge.svelte b/src/components/BlockedBadge.svelte index aa858964f..9348a4934 100644 --- a/src/components/BlockedBadge.svelte +++ b/src/components/BlockedBadge.svelte @@ -9,7 +9,7 @@ nsfw: 'The channel has been added to our blocklist due to NSFW content' } - const blocklistRefs = channel.blocklist_records + const blocklistRefs = channel._blocklistRecords .map(record => { let refName diff --git a/src/components/ChannelItem.svelte b/src/components/ChannelItem.svelte index dd7efe823..7a282e40e 100644 --- a/src/components/ChannelItem.svelte +++ b/src/components/ChannelItem.svelte @@ -13,6 +13,7 @@ const guides = channel._guides const streams = channel._streams + const displayName = channel._displayName const [name, country] = channel.id.split('.') @@ -20,11 +21,7 @@ let prevUrl = '/' const onOpened = () => { prevUrl = window.location.href - window.history.pushState( - {}, - `${channel.displayName} • iptv-org`, - `/channels/${country}/${name}` - ) + window.history.pushState({}, `${displayName} • iptv-org`, `/channels/${country}/${name}`) } const onClose = () => { window.history.pushState({}, `iptv-org`, prevUrl) @@ -32,13 +29,13 @@ const showGuides = () => open( GuidesPopup, - { guides, title: channel.displayName }, + { guides, title: displayName }, { transitionBgProps: { duration: 0 }, transitionWindowProps: { duration: 0 } } ) const showStreams = () => open( StreamsPopup, - { streams, title: channel.displayName }, + { streams, title: displayName }, { transitionBgProps: { duration: 0 }, transitionWindowProps: { duration: 0 } } ) const showChannelData = () => { @@ -89,7 +86,7 @@ loading="lazy" referrerpolicy="no-referrer" src={channel.logo} - alt={channel.displayName} + alt={displayName} /> {/if} @@ -103,9 +100,9 @@ href="/channels/{country}/{name}" tabindex="0" class="font-normal text-gray-600 dark:text-white hover:underline hover:text-blue-500 truncate whitespace-nowrap" - title={channel.displayName} + title={displayName} > - {channel.displayName} + {displayName}
{#if channel.is_closed} diff --git a/src/components/ChannelPopup.svelte b/src/components/ChannelPopup.svelte index f6263590c..12d105a28 100644 --- a/src/components/ChannelPopup.svelte +++ b/src/components/ChannelPopup.svelte @@ -30,7 +30,7 @@ >
-

{channel.displayName}

+

{channel._displayName}

{#if channel.is_closed} diff --git a/src/components/EditButton.svelte b/src/components/EditButton.svelte index 8acbf1dfa..aa31690a1 100644 --- a/src/components/EditButton.svelte +++ b/src/components/EditButton.svelte @@ -6,7 +6,7 @@ export let channel const endpoint = 'https://github.com/iptv-org/database/issues/new' - const title = `Edit: ${channel.displayName}` + const title = `Edit: ${channel._displayName}` const labels = 'channels:edit' const template = '__channels_edit.yml' diff --git a/src/components/HTMLPreview.svelte b/src/components/HTMLPreview.svelte index 9cbaf9171..3a1322707 100644 --- a/src/components/HTMLPreview.svelte +++ b/src/components/HTMLPreview.svelte @@ -1,7 +1,5 @@ - {channel && channel.displayName ? `${channel.displayName} • iptv-org` : 'iptv-org'} - + {channel && displayName ? `${displayName} • iptv-org` : 'iptv-org'} + {@html schema()} @@ -54,7 +55,7 @@

- {channel.displayName} + {displayName}

{#if channel.is_closed} diff --git a/src/store.js b/src/store.js index 646b14c5a..ed371bea0 100644 --- a/src/store.js +++ b/src/store.js @@ -3,6 +3,7 @@ import { Playlist, Link } from 'iptv-playlist-generator' import sj from '@freearhey/search-js' import _ from 'lodash' import { browser } from '$app/environment' +import { Channel } from './models' export const query = writable('') export const hasQuery = writable(false) @@ -32,7 +33,7 @@ export async function fetchChannels() { countries.set(api.countries) - let _channels = api.channels.map(c => transformChannel(c, api)) + let _channels = api.channels.map(c => createChannel(c, api)) channels.set(_channels) filteredChannels.set(_channels) @@ -41,13 +42,17 @@ export async function fetchChannels() { 'id', 'name', 'alt_names', + 'alt_name', 'network', + 'owner', 'owners', 'country', 'subdivision', 'city', 'broadcast_area', + 'language', 'languages', + 'category', 'categories', 'launched', 'closed', @@ -155,38 +160,59 @@ async function loadAPI() { return api } -export function transformChannel(channel, data) { - channel._streams = data.streams[channel.id] || [] - channel._guides = data.guides[channel.id] || [] - channel._country = data.countries[channel.country] - channel._subdivision = data.subdivisions[channel.subdivision] - channel._languages = channel.languages.map(code => data.languages[code]).filter(i => i) - channel._categories = channel.categories.map(id => data.categories[id]).filter(i => i) - channel._broadcast_area = channel.broadcast_area.map(value => { - const [type, code] = value.split('/') +function createChannel(data, api) { + let broadcastArea = [] + let regionCountries = [] + + data.broadcast_area.forEach(areaCode => { + const [type, code] = areaCode.split('/') switch (type) { case 'c': - return { type, ...data.countries[code] } + const country = api.countries[code] + if (country) broadcastArea.push({ type, code: country.code, name: country.name }) + break case 'r': - return { type, ...data.regions[code] } + const region = api.regions[code] + if (region) { + broadcastArea.push({ type, code: region.code, name: region.name }) + regionCountries = [ + ...regionCountries, + ...region.countries.map(code => api.countries[code]).filter(Boolean) + ] + } + break case 's': - return { type, ...data.subdivisions[code] } + const subdivision = api.subdivisions[code] + if (subdivision) + broadcastArea.push({ type, code: subdivision.code, name: subdivision.name }) + break } }) - channel.is_closed = !!channel.closed || !!channel.replaced_by - channel.is_blocked = !!data.blocklist[channel.id] - channel.streams = channel._streams.length - channel.guides = channel._guides.length - channel.blocklist_records = Array.isArray(data.blocklist[channel.id]) - ? data.blocklist[channel.id] - : [] - const isChannelNameRepeated = data.nameIndex[channel.name.toLowerCase()].length > 1 - channel.displayName = isChannelNameRepeated - ? `${channel.name} (${channel._country.name})` - : channel.name - - return channel + return new Channel({ + id: data.id, + name: data.name, + altNames: data.alt_names, + network: data.network, + owners: data.owners, + city: data.city, + country: api.countries[data.country], + subdivision: api.subdivisions[data.subdivision], + languages: data.languages.map(code => api.languages[code]).filter(Boolean), + categories: data.categories.map(id => api.categories[id]).filter(Boolean), + isNSFW: data.is_nsfw, + launched: data.launched, + closed: data.closed, + replacedBy: data.replaced_by, + website: data.website, + logo: data.logo, + streams: api.streams[data.id], + guides: api.guides[data.id], + blocklistRecords: api.blocklist[data.id], + hasUniqueName: api.nameIndex[data.name.toLowerCase()].length === 1, + broadcastArea, + regionCountries + }) } function getStreams() {