Connects MDBList through its OAuth device-code grant, registered as a Device Code app so no client secret or redirect URI ships in the binary and TV, mobile and desktop all use the same flow. MDBList omits `verification_uri_complete`, but its device page seeds the code field from a `user_code` query parameter and the sign-in redirect preserves the query string, so the activation link is built locally and the dialog's open button lands on a filled-in form instead of an empty one. A server-supplied complete URL still wins if one ever appears. Poll state is read from the response body rather than the status code: `authorization_pending` and `slow_down` both arrive as HTTP 400, and a missing grant answers 404 `device_not_found`. Writes go out as real-time `/scrobble/*` reports plus `/sync/watched` for the marks that never pass through the player, with ratings on `/sync/ratings`. Matching uses IMDb and TMDb only — MDBList's id block has no `tvdb` field, so a TVDB-only item is skipped rather than written under an empty id block.
38 lines
1.4 KiB
Dart
38 lines
1.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
|
|
import '../models/catalog/catalog_item.dart';
|
|
|
|
/// Brand mark of a service, tinted with the ambient icon color. The single
|
|
/// table of brand asset paths: every surface that shows a service logo goes
|
|
/// through here, including services that do not participate in the Explore
|
|
/// catalog. Uses [SvgTheme.currentColor] so SVGs with multiple explicit fills
|
|
/// (AniList keeps its brand-blue L while the A follows the theme) render
|
|
/// correctly alongside single-color wordmarks.
|
|
class CatalogSourceLogo extends StatelessWidget {
|
|
final CatalogSourceId id;
|
|
final double size;
|
|
|
|
const CatalogSourceLogo(this.id, {super.key, this.size = 20});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final asset = switch (id) {
|
|
CatalogSourceId.plex => 'assets/plex_chevron.svg',
|
|
CatalogSourceId.trakt => 'assets/trakt_circlemark.svg',
|
|
CatalogSourceId.mal => 'assets/mal_mark.svg',
|
|
CatalogSourceId.anilist => 'assets/anilist_mark.svg',
|
|
CatalogSourceId.simkl => 'assets/simkl_mark.svg',
|
|
CatalogSourceId.seerr => 'assets/seerr_mark.svg',
|
|
CatalogSourceId.mdblist => 'assets/mdblist_mark.svg',
|
|
};
|
|
final color = IconTheme.of(context).color ?? Theme.of(context).colorScheme.onSurface;
|
|
return SvgPicture.asset(
|
|
asset,
|
|
width: size,
|
|
height: size,
|
|
theme: SvgTheme(currentColor: color),
|
|
);
|
|
}
|
|
}
|