Repository navigation
Conversation
- Added a `selection` option to `LanguagesModal` that hands the picked languages to the caller instead of saving a settings preference, with `multiple: false` for a single pick and `noneLabel` for an explicit "no language" choice - Added an `exclude` option to leave pseudo-languages out of the list - Kept every existing call site unchanged
…ion to `BackgroundImagePlaceholderDiv` - Added a `compact` option to `MultiStateButton` for narrower, lower buttons sized to their labels, for a toolbar - Added a `position` option to `BackgroundImagePlaceholderDiv` that sets where the image sits in its frame
- Added the Airing Schedule utility, with month, week and agenda views of `GET AiringSchedule/Calendar`, under the utilities menu - Put the refresh, scope and channel toggles in a toolbar, the view switcher and the period navigation beside it, and the period in the title, sliding in the direction of travel - Moved the channel filter, airing kind and provider behind a settings gear, kept with the last view for the session - Kept the month and week grids while they load, with skeletons in each day, and drew only the agenda rows in view - Refetched the airings on the `airing` feed's sweeps, marked what is on air now and which episodes have local files, and let debug builds shift the schedule's clock
- Added a season view, now the default, listing a season's anime in the server's sections with their next new episode and a countdown, as cards in one to three columns drawn only while in view - Picked the season from a slider kept in view while scrolling, and browsed every season by year from it, in place of a separate archive view - Returned to the slider, or to where you were, after picking a season or closing the browser, and kept the slider pinned while the browser opens - Showed skeleton cards while a season or the browser loads, and refetched the season's anime every few minutes and on the `airing` feed's sweeps - Added the season view's oldest year to the airing schedule's settings modal, saved to the user's WebUI settings once typing pauses
- Added an `Airing Schedule` settings page with general options, the "Refresh Anime Airing Soon" window, airing preferences, channel visibility, "Studio & Genre Sources", the provider priority and a section per provider - Kept the page's changes in a draft sent by the settings page's Save with the core settings, the service's own options as a JSON patch on its configuration - Set each provider's kinds, sweep interval and plugin configuration, and showed its icon and, when it differs, its plugin's name - Added channel search, aliases, merges and a duplicate check, the preferred channels and tracks, and the season detail sources with `OrderList` and `TextSourcesModal`
- Switched the upcoming anime widget from `Dashboard/AniDBCalendar` to `GET /api/v3/AiringSchedule/Calendar`, without reruns, and removed the unused `useDashboardCalendarQuery` - Laid the widget out as a timeline from 12 hours ago with a "You Are Here" mark, one card per episode and day with its channel and provider icon - Added a link from the widget's header to the airing schedule - Added dashboard options for the widget's days ahead and air times, kept in the WebUI settings
- Added `SequenceNumber` and `IsResolved` to the airing, and `includeUnresolved` to the airing reads - Labelled an unresolved airing `Ep N` from its `Number`, with a muted "Not on AniDB yet" hint in the entries, cards and the dashboard widget - Linked an unresolved airing to its series rather than an episode, and showed no local files for it
- Added a "Show Recently Aired" switch and its hours, 1 to 24, to the airing schedule settings modal, saved in `WebUI_Settings.airingSchedule.recentlyAired` - Read the current and previous seasons' sections with `at` that many hours back, rounded down to 15 minutes, so a card keeps an episode that aired since - Kept a season's cards while the next 15 minute step is read, which moves them on - Showed how long ago a card's episode aired, by the clock, in place of "Just aired"
- Split the settings modal into General and Sections tabs - Added a draggable section list with an inline editor for the title, anime types, continuing and half length, saved as you edit to `airingSchedule.sections` - The season view always reads its sections by `POST`, with the saved layout or `null` for the server default, and hides the empty ones - Dropped the section `ID`; sections are keyed by their place in the layout
- Added an "Episode Types" multi-select to the General tab, saved to `airingSchedule.episodeTypes`, `null` for every type - Sent the types as `episodeType` on the season sections read and as `type` on the calendar read
- Read `Season` and `Season/ByYear` by POST with the stored layout, which joined their query keys - Showed the left-out hint only for a custom layout without a rest group
This was referenced Oct 6, 2026
Member
Author
|
Split into three stacked PRs (union reproduces this branch's tree exactly; verified with an empty
Each PR's body states what it shares with the others. The |
Member
Author
|
Closing in favour of the three stacked parts split from this branch (their union reproduces
The discussion here applies to the parts; please continue it on the relevant PR. The |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The server now has an airing schedule service (
/api/v3/AiringSchedule/*). Provider plugins (AnimeSchedule.net, Syoboi Calendar, TVmaze and others) supply timed broadcast and streaming airings, with channels, delays and sub/dub tracks. The WebUI had no way to see those airings or to configure the service, and the dashboard's Upcoming Anime widget still read the oldDashboard/AniDBCalendarwhich was based on AniDB's date-only data.Where this sits
feat/airing-schedule, againstmaster. It does not depend on the open metadata PRs; where it needed something that only lives in refactor(settings): replace the TMDB tab with settings for every metadata source #1489, it carries a copy (see Overlap to dedupe).feat(languages): let callers pick from the languages modalfeat(components): add a compact MultiStateButton and an image position to BackgroundImagePlaceholderDivfeat(airing-schedule): add an airing schedule page(Part 1, without the season view)feat(airing-schedule): add a season view(Part 1, Season)feat(airing-schedule): add an airing schedule settings page(Part 3)feat(dashboard): read the upcoming anime from the airing schedule(Part 2)feat(airing-schedule): show unresolved airings(Parts 1 and 2)feat(airing-schedule): show recently aired episodes in the season view(Part 1, Season)feat(airing-schedule): add a season section editor(Part 1, Season)feat(airing-schedule): filter the views by episode type(Part 1)Part 1: Airing Schedule page
Utilities > Airing Schedule(/webui/utilities/airing-schedule), with Season (the default), Month, Week and Agenda views.Toolbar and header
Airing Schedule | <period>; the period slides out and in the direction of travel (forward for later, back for earlier), and swaps at once on a view switch or with reduced motion. The header's right side counts the anime, seasons or airings shown.R), My Collection / All Series, Every Channel, Hide Estimates, Show Reruns. Beside it, in boxes of their own that wrap together: the view switcher (Season | Month | Week | Agenda), the navigation (previous, today or current season, next) and a settings gear.viewin the URL the page opens on the last view used (Redux, for the session). Series without files are always shown (the "Include Series Without Files" option andincludeMissingare gone).Month, Week, Agenda (read from
GET AiringSchedule/Calendar, grouped and sorted on the server)+N moreopens that day's week.+N morelists the others in place (a popover in the month's rows). Reruns only with Show Reruns, with a badge. Date-only episodes (AniDB air date) are all-day entries. Delayed airings show at their new slot. Hover shortcut on a channel to hide it, with Undo.Nowbadge on an airing while it is on air (AiredAtuntilEndsAt), tooltip "On air until HH:mm".VideoCount), with the count in its tooltip.IsResolved: false) readsEp Nfrom itsNumber, with a muted "Not on AniDB yet" hint, links to its series and never shows the files icon. The same goes for the season cards and the dashboard widget.Season
GET AiringSchedule/Season/ByYearwithout images.data-stuck, judged from the layout on scroll and resize).browse=true), so Back closes it; closing steps back over that entry; a pick replaces it, so Back then returns to the page before the browser opened.Esccloses it.POST AiringSchedule/Season/{year}/{season}/Sections): the server's sections (TV & Web, Half Length, Continuing, Movies, OVAs & Specials) and order, or the user's layout; empty sections are hidden; countdown to the next new episode, its regular slot and provider icon, the episode length, "Airing now" with "ends in ..." while on air and "Aired 30m ago" after; the files icon; source, overview, top tags, Missing Files / In Collection.getGridColumnCount), withminmax(0, 1fr)so phones never scroll sideways. Both are virtual lists on the page's scroll container.WebUI_Settings.airingSchedule.recentlyAired. While on, the current and previous seasons' sections are read withatthat many hours back, rounded down to 15 minutes, so a card keeps an episode that just aired ("Aired 2h ago", by the clock) and moves on as the next 15 minute step is read. The season list and the calendar views never send it.WebUI_Settings.airingSchedule.oldestSeasonYearand sent asfromYear.WebUI_Settings.airingSchedule.sections(nullfollows the server default fromGET AiringSchedule/Season/Sections/Default, which the first edit copies). Muted hints flag a section after a rest group and a layout with no rest group. The sections read always POSTs{ Sections },nullfor the default.WebUI_Settings.airingSchedule.episodeTypes(nullfor every type). It is sent asepisodeTypeon the season sections read and astypeon the calendar reads; the season list and the dashboard widget ignore it.Loading and data
AiringProvidersContext).airing:provider.sweptandairing:episode.airedinvalidate the calendar and the sections.useNow) for every countdown and on-air mark.Debug builds only:
?clockOffset=A signed offset (
-90m,7h40m,-1d6h) shifts the page's clock (still ticking): today, the current season, the default period and the slider. While shifted, the season, years and sections reads sendatwith the shifted time so the server agrees, and the header shows the shifted clock. Ignored in production builds.Look first at:
src/pages/utilities/AiringSchedule.tsx,src/components/Utilities/AiringSchedule/(SeasonView,SeasonSlider,SeasonBrowser,SeasonCard,CalendarViews,AiringEntry,Skeleton),src/core/utilities/seasonSlider.ts,seasonGrid.ts,airingSchedule.ts,clock.ts,src/hooks/useNow.ts.Part 2: Dashboard widget
UpcomingAnimereadsGET AiringSchedule/Calendar(date-only episodes included), same size and tabs, as a timeline from 12 hours ago: past date-only episodes first, timed airings in order, future date-only ones last, a "You Are Here" mark at now, aired ones muted. Each card shows the channel and provider icon; reruns are left out; Every Channel adds a+Nper card. Its header links to the Airing Schedule. Display Options gained the series shown, days ahead and air times.useDashboardCalendarQueryis removed.Look first at:
src/pages/dashboard/panels/UpcomingAnime.tsx,src/pages/dashboard/components/AiringDetails.tsx,src/components/Dashboard/DashboardSettingsModal.tsx.Part 3: Airing schedule settings
Settings > Airing Schedule, built like the metadata settings in #1489. Everything but a provider's plugin configuration goes into a draft onSettingsPage, sent by the shared Save and dropped by Cancel; a failed part shows its error and stays in the draft.DynamicField, viaGET AiringSchedule/Configuration).AiringSoonWindowHours(1 to 168) andAiringSoonIncludeDateOnly.PUT AiringSchedule/Channel/Hidden).SeasonDetailSourceOrder, with AniDB always listed and never removable.PUT .../Aliases), Merge into... (POST .../Merge) and a Possible Duplicates panel.selection(single pick,noneLabel) andexclude; existing call sites unchanged.Look first at:
src/pages/settings/tabs/AiringScheduleSettings.tsx,src/components/Settings/AiringScheduleSettings/,src/core/react-query/airing-schedule/draft.ts,src/core/utilities/airingChannels.ts,src/components/Dialogs/AiringChannel*Modal.tsx,LanguagesModal.tsx.Overlap to dedupe
Shared with #1489 (metadata settings), whichever lands second drops its copy:
src/core/react-query/configuration/mutations.ts,ConfigurationActionResultType, theenabledparameter ofuseConfigurationQuery, theprocessErrorexport,OrderList.tsx(plus an optionalisRemovableper item, which refactor(settings): replace the TMDB tab with settings for every metadata source #1489 needs too),TextSourcesModal.tsx,TextSourceLabel.tsx,MetadataSourceIcon.tsx,MetadataProviderConfiguration.tsx(at refactor(settings): replace the TMDB tab with settings for every metadata source #1489's path, plugin-name rule included),getDistinctPluginName.ts,src/core/react-query/metadata/*andsrc/core/types/api/metadata.ts.SettingsPage.tsx,src/core/types/context.ts,useSettingsContext.ts(refactor(settings): replace the TMDB tab with settings for every metadata source #1489 addsmetadataDraft, this PRairingScheduleDraft; both together meanssaveAllsends both), andairing-schedule/draft.tsmirroringmetadata/draft.ts.imageOrder/onImageOrderChangeis a special case ofselection.Feedback wanted
VITE_MIN_SERVER_VERSIONis unchanged; no released server has these routes yet, so which build should it require??clockOffset=in the shipped code, or drop it before merging?Testing
pnpm lint,pnpm tscheckandpnpm buildclean;pnpm test251 passed (new: season boundaries, the slider strip and browser history/scroll rules, grid columns, the clock offset, channel search and duplicate groups). No dependency changes.channel=on every read) and hide shortcut, the dashboard widget, and the settings page's draft, Cancel and Channel Visibility save.Utilities > Airing Schedule, step through seasons with the slider, open the browser from the pill and use Back; switch to Week and go back a week or two to see the files icon on episodes you have.Server gaps seen on test data
AiringSeries.ShokoIDis only set when an airing resolves through a Shoko episode.