Project import generated by Copybara.

GitOrigin-RevId: dc6df4683dd1ae55904108f04a26dbf68fed5e3c
This commit is contained in:
Madari Developers 2025-01-04 15:38:24 +00:00
parent 0891e8eddf
commit f7c6cdb209
8 changed files with 64 additions and 248 deletions

View file

@ -6,8 +6,8 @@ import 'package:flutter/material.dart';
import 'package:madari_client/features/connection/types/stremio.dart';
import 'package:madari_client/features/connections/service/base_connection_service.dart';
import 'package:madari_client/features/doc_viewer/container/doc_viewer.dart';
import 'package:madari_client/utils/external_player.dart';
import '../../../../utils/external_player.dart';
import '../../../../utils/load_language.dart';
import '../../../doc_viewer/types/doc_source.dart';
import '../../../downloads/service/service.dart';

View file

@ -274,16 +274,10 @@ class _StremioItemViewerState extends State<StremioItemViewer> {
if (widget.original != null &&
widget.original?.type == "series" &&
widget.original?.videos?.isNotEmpty == true)
SliverPadding(
padding: EdgeInsets.symmetric(
horizontal: isWideScreen ? (screenWidth - contentWidth) / 2 : 0,
vertical: 0,
),
sliver: StremioItemSeasonSelector(
meta: item!,
library: widget.library,
service: widget.service,
),
StremioItemSeasonSelector(
meta: item!,
library: widget.library,
service: widget.service,
),
SliverPadding(
padding: EdgeInsets.symmetric(

View file

@ -165,56 +165,62 @@ class _StremioItemSeasonSelectorState extends State<StremioItemSeasonSelector>
return SliverMainAxisGroup(
slivers: [
SliverToBoxAdapter(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 12,
),
Center(
child: Container(
constraints: const BoxConstraints(maxWidth: 320),
child: ElevatedButton.icon(
icon: const Icon(Icons.shuffle),
label: const Text("Random Episode"),
onPressed: () {
Random random = Random();
int randomIndex = random.nextInt(
widget.meta.videos!.length,
);
SliverPadding(
padding: EdgeInsets.symmetric(
horizontal: isWideScreen ? (screenWidth - contentWidth) / 2 : 8,
),
sliver: SliverToBoxAdapter(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
height: 12,
),
Center(
child: Container(
constraints: const BoxConstraints(maxWidth: 320),
child: ElevatedButton.icon(
icon: const Icon(Icons.shuffle),
label: const Text("Random Episode"),
onPressed: () {
Random random = Random();
int randomIndex = random.nextInt(
widget.meta.videos!.length,
);
openEpisode(
currentSeason: widget.meta.videos![randomIndex].season,
episode: widget.meta.videos![randomIndex],
);
},
openEpisode(
currentSeason:
widget.meta.videos![randomIndex].season,
episode: widget.meta.videos![randomIndex],
);
},
),
),
),
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: colorScheme.surface.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: colorScheme.surface.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: TabBar(
tabAlignment: TabAlignment.start,
dividerColor: Colors.transparent,
controller: _tabController,
isScrollable: true,
splashBorderRadius: BorderRadius.circular(8),
padding: const EdgeInsets.all(4),
tabs: seasons.map((season) {
return Tab(
text: season == 0 ? "Specials" : 'Season $season',
height: 40,
);
}).toList(),
),
),
child: TabBar(
tabAlignment: TabAlignment.start,
dividerColor: Colors.transparent,
controller: _tabController,
isScrollable: true,
splashBorderRadius: BorderRadius.circular(8),
padding: const EdgeInsets.all(4),
tabs: seasons.map((season) {
return Tab(
text: season == 0 ? "Specials" : 'Season $season',
height: 40,
);
}).toList(),
),
),
const SizedBox(height: 16),
],
const SizedBox(height: 16),
],
),
),
),
SliverPadding(

View file

@ -5,7 +5,6 @@ import 'package:madari_client/engine/engine.dart';
import 'package:pdfrx/pdfrx.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart';
class MagicShowMarkdown extends StatefulWidget {
final RecordModel record;
@ -141,8 +140,6 @@ class _MagicShowMarkdownState extends State<MagicShowMarkdown> {
}
}
// Add the mermaid diagram
contentWidgets.add(_buildMermaidDiagram(match.group(1)!));
lastEnd = match.end;
}
@ -173,17 +170,6 @@ class _MagicShowMarkdownState extends State<MagicShowMarkdown> {
);
}
Widget _buildMermaidDiagram(String mermaidCode) {
return Container(
constraints: const BoxConstraints(
maxHeight: 300,
),
child: MermaidRenderer(
html: mermaidCode,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -339,143 +325,3 @@ class _MagicShowMarkdownState extends State<MagicShowMarkdown> {
);
}
}
class MermaidRenderer extends StatefulWidget {
final String html;
const MermaidRenderer({
super.key,
required this.html,
});
@override
State<MermaidRenderer> createState() => _MermaidRendererState();
}
class _MermaidRendererState extends State<MermaidRenderer> {
late WebViewController controller;
bool isFullScreen = false;
bool hasError = false;
String get html => """
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({
startOnLoad: true,
theme: 'default'
});
window.onerror = function(msg, url, lineNo, columnNo, error) {
window.flutter_inappwebview.callHandler('onError', msg);
return false;
};
mermaid.parseError = function(err) {
window.flutter_inappwebview.callHandler('onError', err);
};
</script>
</head>
<body>
<div class="mermaid">
${widget.html}
</div>
</body>
</html>
""";
@override
void initState() {
super.initState();
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
'flutter_inappwebview',
onMessageReceived: (message) {
setState(() {
hasError = true;
});
},
)
..loadHtmlString(html);
}
@override
Widget build(BuildContext context) {
if (hasError) {
return Container(
height: 100,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
borderRadius: BorderRadius.circular(10),
),
child: const Center(
child: Text(
'Unable to render diagram.\nPlease check the syntax.',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red),
),
),
);
}
return Stack(
children: [
ClipRRect(
borderRadius:
isFullScreen ? BorderRadius.zero : BorderRadius.circular(10),
child: WebViewWidget(
controller: controller,
),
),
Positioned(
top: 8,
right: 8,
child: IconButton(
icon: Icon(
isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
color: Colors.grey[800],
),
onPressed: () {
setState(() {
isFullScreen = !isFullScreen;
});
if (isFullScreen) {
final controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadHtmlString(html);
Navigator.of(context)
.push(
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) => Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.close),
onPressed: () => Navigator.of(context).pop(),
),
title: const Text("Diagram"),
),
body: WebViewWidget(controller: controller),
),
),
)
.then((_) {
setState(() {
isFullScreen = false;
});
});
}
},
),
),
],
);
}
}

View file

@ -38,10 +38,16 @@ PlaybackConfig getPlaybackConfig() {
@JsonSerializable()
class PlaybackConfig {
@JsonKey(defaultValue: true)
final bool autoPlay;
@JsonKey(defaultValue: 1.0)
final double playbackSpeed;
@JsonKey(defaultValue: "eng")
final String defaultAudioTrack;
@JsonKey(defaultValue: "eng")
final String defaultSubtitleTrack;
@JsonKey(defaultValue: false)
final bool externalPlayer;
final Map<String, String>? externalPlayerId;

View file

@ -19,7 +19,6 @@ import sqflite_darwin
import sqlite3_flutter_libs
import url_launcher_macos
import wakelock_plus
import webview_flutter_wkwebview
import window_manager
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
@ -37,6 +36,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
FLTWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "FLTWebViewFlutterPlugin"))
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
}

View file

@ -1812,38 +1812,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
webview_flutter:
dependency: "direct main"
description:
name: webview_flutter
sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec"
url: "https://pub.dev"
source: hosted
version: "4.10.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: "285cedfd9441267f6cca8843458620b5fda1af75b04f5818d0441acda5d7df19"
url: "https://pub.dev"
source: hosted
version: "4.1.0"
webview_flutter_platform_interface:
dependency: transitive
description:
name: webview_flutter_platform_interface
sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
url: "https://pub.dev"
source: hosted
version: "2.10.0"
webview_flutter_wkwebview:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: b7e92f129482460951d96ef9a46b49db34bd2e1621685de26e9eaafd9674e7eb
url: "https://pub.dev"
source: hosted
version: "3.16.3"
win32:
dependency: transitive
description:
@ -1869,7 +1837,7 @@ packages:
source: hosted
version: "1.1.0"
xml:
dependency: "direct main"
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226

View file

@ -44,12 +44,10 @@ dependencies:
flutter_dotenv: ^5.2.1
intl: ^0.20.1
simple_animations: ^5.0.0+3
webview_flutter: ^4.10.0
pdfrx: ^1.0.93
photo_view: ^0.15.0
window_manager: ^0.4.2
background_downloader: ^8.8.0
xml: ^6.5.0
file_picker: ^8.1.4
flutter_inappwebview: ^6.1.5
drift: ^2.22.1