-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update spanish-tv-guide extension (#15437)
- Bump depdendencies - Consume new API - Merge pull request #2 from doktor500/tv-guide-v2 - Downgrade eslint to 8.X - Add eslint file - Fix lint issues - Renamet metadata directory to docs - Fix changelog typo - Update changelog date - Update changelog - Merge pull request #1 from doktor500/tv-guide-v2 - Formatting - Refactor - Imrpove markdown - Always display up to date channel schedule - Rename file - Rename to DTO - Bump dependencies - Fix imports - Fix time issue - Display if a program is live - Set selected program based on user interaction - Refactor types - Fix timezone issue - Move get program details to repository - Add maybe type - Rename property - Display program details - Fix lint - Optimise icon generation process - Extract toId function - Drop previous broadcasted programs when the list is too long - Fix flickering issue - Fix keys - Restructure directories - Refactor Channel details component - Refactor Channel component - Extract icon utils - Refactor channels component - Fix lint - Use navigation api - Selected channel view - Create all channels view - Use reducer - Remove type - Fix lint - Update raycast username - User friendly error handling - Set live stream icon - Bump dependencies - Wait for icons to be loaded - Fix metadata and readme - Update CHANGELOG.md - Fix lint - Cleanup - Update changelog - Extract constant - Bump dependencies - Resize icons - Optimize - Pull contributions - Remove live logic - Update demo.gif - Fix title - Add screenshot - Fix icon - Bump dependencies - Initial version
- Loading branch information
Showing
18 changed files
with
2,046 additions
and
819 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 28 additions & 14 deletions
42
extensions/spanish-tv-guide/src/components/SelectedChannel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 12 additions & 14 deletions
26
extensions/spanish-tv-guide/src/components/SelectedProgram.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,37 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import { Detail } from "@raycast/api"; | ||
|
||
import { tvScheduleRepository } from "../modules/tv/repositories/tvScheduleRepository"; | ||
import { ChannelScheduleDto, ProgramDto, ProgramDetailsDto } from "../modules/tv/domain/tvScheduleDto"; | ||
import { getTime } from "../utils/dateUtils"; | ||
import { Maybe } from "../utils/objectUtils"; | ||
import { truncate } from "../utils/stringUtils"; | ||
|
||
export const SelectedProgram = ({ channel, program }: { channel: ChannelScheduleDto; program: ProgramDto }) => { | ||
const [programDetails, setProgramDetails] = useState<Maybe<ProgramDetailsDto>>(); | ||
|
||
useEffect(() => void tvScheduleRepository.getProgramDetails(program).then(setProgramDetails), [program]); | ||
export const SelectedProgram = (props: { channel: ChannelScheduleDto; program: ProgramDto & ProgramDetailsDto }) => { | ||
const { channel, program } = props; | ||
|
||
return ( | ||
programDetails && ( | ||
program && ( | ||
<Detail | ||
navigationTitle={channel.name} | ||
markdown={formattedProgramDetails(programDetails)} | ||
isLoading={!programDetails} | ||
markdown={formattedProgramDetails(program)} | ||
isLoading={!program} | ||
metadata={ | ||
<Detail.Metadata> | ||
<Detail.Metadata.Label title={channel.name} icon={channel.icon} /> | ||
<Detail.Metadata.Label title={program.title} /> | ||
<Detail.Metadata.Label title={truncate(program.name)} /> | ||
</Detail.Metadata> | ||
} | ||
/> | ||
) | ||
); | ||
}; | ||
|
||
const formattedProgramDetails = ({ title, startTime, image, description }: ProgramDetailsDto) => ` | ||
### ${getTime(startTime)} ${title} | ||
type Props = ProgramDetailsDto & { name: string; startTime: Date }; | ||
|
||
const formattedProgramDetails = ({ name, startTime, imageUrl, description }: Props) => ` | ||
### ${getTime(startTime)} ${truncate(name)} | ||
--- | ||
${description} | ||
![${title}](${image}?raycast-width=125&raycast-height=188) | ||
![${truncate(name)}](${imageUrl}) | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 0 additions & 6 deletions
6
extensions/spanish-tv-guide/src/modules/tv/repositories/dto/channelResponse.ts
This file was deleted.
Oops, something went wrong.
8 changes: 0 additions & 8 deletions
8
extensions/spanish-tv-guide/src/modules/tv/repositories/dto/programResponse.ts
This file was deleted.
Oops, something went wrong.
72 changes: 18 additions & 54 deletions
72
extensions/spanish-tv-guide/src/modules/tv/repositories/tvScheduleRepository.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,36 @@ | ||
import fetch from "isomorphic-fetch"; | ||
import { parse } from "node-html-parser"; | ||
|
||
import { ChannelScheduleDto, ProgramDto, ProgramDetailsDto, TvScheduleDto } from "../domain/tvScheduleDto"; | ||
import { ProgramResponse } from "./dto/programResponse"; | ||
import { ChannelResponse } from "./dto/channelResponse"; | ||
import { now, parseTime, plusOneDay } from "../../../utils/dateUtils"; | ||
import { toString, truncate } from "../../../utils/stringUtils"; | ||
import { findLast, last, replace } from "../../../utils/collectionUtils"; | ||
import { Maybe } from "../../../utils/objectUtils"; | ||
import { ProgramDto, ProgramDetailsDto, TvScheduleDto } from "../domain/tvScheduleDto"; | ||
import { dateReviver } from "../../../utils/dateUtils"; | ||
|
||
const TV_GUIDE_URL = "https://www.movistarplus.es/programacion-tv?v=json"; | ||
const ICON_URL = "https://www.movistarplus.es/recorte/m-NEO/canal"; | ||
const ICON_EXTENSION = "png"; | ||
|
||
type Response = { data: object }; | ||
const TV_GUIDE_CHANNELS_URL = "https://spanish-tv-guide-api.vercel.app/api/guide/channels"; | ||
const TV_GUIDE_PROGRAM_DETAILS_URL = "https://spanish-tv-guide-api.vercel.app/api/guide/program"; | ||
|
||
const getAll = async (): Promise<TvScheduleDto> => { | ||
return fetch(TV_GUIDE_URL, { headers: { Accept: "application/json" } }) | ||
.then((response) => response.json() as unknown as Response) | ||
.then((response: Response) => Object.values(response.data)) | ||
.then((channels: ChannelResponse[]) => channels.map(mapToChannel)) | ||
.then((channelSchedules: ChannelScheduleDto[]) => channelSchedules.map(channelScheduleWithLiveProgram)); | ||
return fetch(TV_GUIDE_CHANNELS_URL) | ||
.then((response) => response.json()) | ||
.then((response) => JSON.parse(JSON.stringify(response), dateReviver)); | ||
}; | ||
|
||
const getProgramDetails = async (program: ProgramDto): Promise<ProgramDetailsDto> => { | ||
return fetch(program.url) | ||
.then((response: { text: () => Promise<string> }) => response.text()) | ||
.then((html: string) => { | ||
const document = parse(html); | ||
const image = document.querySelector("div.cover > img")?.getAttribute("src"); | ||
const description = document.querySelector("div.show-content > div")?.innerText?.trim(); | ||
return { ...program, image: toString(image), description: toString(description) }; | ||
}); | ||
}; | ||
const url = buildGetProgramDetailsUrl(TV_GUIDE_PROGRAM_DETAILS_URL, program.url); | ||
|
||
const mapToChannel = (channel: ChannelResponse): ChannelScheduleDto => { | ||
return { | ||
icon: `${ICON_URL}/${channel.DATOS_CADENA.CODIGO}.${ICON_EXTENSION}`, | ||
name: channel.DATOS_CADENA.NOMBRE, | ||
schedule: mapToSchedule(channel.PROGRAMAS), | ||
}; | ||
return fetch(url) | ||
.then((response) => response.json()) | ||
.then((response) => JSON.parse(JSON.stringify(response), dateReviver)); | ||
}; | ||
|
||
const mapToSchedule = (programs: ProgramResponse[]) => { | ||
return programs.reduce((programs: ProgramDto[], program: ProgramResponse) => { | ||
const currentProgram = mapToProgram(program, last(programs)); | ||
return [...programs, currentProgram]; | ||
}, []); | ||
}; | ||
const buildGetProgramDetailsUrl = (baseUrl: string, url: string) => { | ||
const encodedProgramUrl = encodeURI(url); | ||
|
||
const mapToProgram = (program: ProgramResponse, lastProgram: Maybe<ProgramDto>): ProgramDto => { | ||
const isLive = program.DIRECTO; | ||
const startTime = parseTime(program.HORA_INICIO); | ||
const fixedTime = lastProgram?.startTime && lastProgram.startTime > startTime ? plusOneDay(startTime) : startTime; | ||
|
||
return { isLive, isCurrentlyLive: false, startTime: fixedTime, url: program.URL, title: truncate(program.TITULO) }; | ||
return `${baseUrl}?${toQueryString("url", encodedProgramUrl)}`; | ||
}; | ||
|
||
const channelScheduleWithLiveProgram = ({ schedule, icon, name }: ChannelScheduleDto): ChannelScheduleDto => { | ||
const currentProgram = findLast(schedule, (program) => program.startTime < now()); | ||
const programs = currentProgram ? scheduleWithLiveProgram(schedule, currentProgram) : schedule; | ||
return { icon, name, schedule: programs }; | ||
}; | ||
const toQueryString = (key: string, value: string) => { | ||
const params = new URLSearchParams(); | ||
params.append(key, value); | ||
|
||
const scheduleWithLiveProgram = (programs: ProgramDto[], currentProgram: ProgramDto): ProgramDto[] => { | ||
return replace(currentProgram) | ||
.in(programs) | ||
.with({ ...currentProgram, isCurrentlyLive: true }); | ||
return params.toString(); | ||
}; | ||
|
||
export const tvScheduleRepository = { getAll, getProgramDetails }; |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.