Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
poka | a1b8e7a001 | |
poka | 8f220f800d | |
poka | 7f06a7b96e | |
poka | d7cb5885f7 | |
poka | 60c4a1f68d | |
poka | 422aaefbac | |
poka | 29491fb800 | |
poka | a23f77bf68 | |
poka | cb556da4de | |
poka | 6ca3367808 | |
poka | ebb8806c2b | |
poka | 05f1d702e3 | |
poka | 22369d241a | |
poka | 7396babf61 | |
poka | be75e079e8 | |
poka | 76fcb6b6eb | |
poka | 41062a2261 |
24
.metadata
|
@ -1,10 +1,30 @@
|
||||||
# This file tracks properties of this Flutter project.
|
# This file tracks properties of this Flutter project.
|
||||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
#
|
#
|
||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: 5464c5bac742001448fe4fc0597be939379f88ea
|
revision: f72efea43c3013323d1b95cff571f3c1caa37583
|
||||||
channel: stable
|
channel: stable
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: f72efea43c3013323d1b95cff571f3c1caa37583
|
||||||
|
base_revision: f72efea43c3013323d1b95cff571f3c1caa37583
|
||||||
|
- platform: windows
|
||||||
|
create_revision: f72efea43c3013323d1b95cff571f3c1caa37583
|
||||||
|
base_revision: f72efea43c3013323d1b95cff571f3c1caa37583
|
||||||
|
|
||||||
|
# User provided section
|
||||||
|
|
||||||
|
# List of Local paths (relative to this file) that should be
|
||||||
|
# ignored by the migrate tool.
|
||||||
|
#
|
||||||
|
# Files that are not part of the templates will be ignored by default.
|
||||||
|
unmanaged_files:
|
||||||
|
- 'lib/main.dart'
|
||||||
|
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"ExpandedNodes": [
|
||||||
|
"",
|
||||||
|
"\\windows"
|
||||||
|
],
|
||||||
|
"SelectedNode": "\\windows",
|
||||||
|
"PreviewInSolutionExplorer": false
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -1,4 +1,4 @@
|
||||||
# fip_parser_ui
|
# fipy
|
||||||
|
|
||||||
Explore FIP's webradio latest tracks, play it and download what you want.
|
Explore FIP's webradio latest tracks, play it and download what you want.
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId "com.example.fip_parser_ui"
|
applicationId "fipy.p2p.legal"
|
||||||
minSdkVersion flutter.minSdkVersion
|
minSdkVersion flutter.minSdkVersion
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.fip_parser_ui">
|
package="fipy.p2p.legal">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.fip_parser_ui">
|
package="fipy.p2p.legal">
|
||||||
<application
|
<application
|
||||||
android:label="fip_parser_ui"
|
android:label="fipy"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/launcher_icon">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|
After Width: | Height: | Size: 50 KiB |
|
@ -1,4 +1,4 @@
|
||||||
package com.example.fip_parser_ui
|
package fipy.p2p.legal
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 12 KiB |
|
@ -1,5 +1,5 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.fip_parser_ui">
|
package="fipy.p2p.legal">
|
||||||
<!-- Flutter needs it to communicate with the running application
|
<!-- Flutter needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
|
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
|
@ -294,7 +294,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.fipParserUi;
|
PRODUCT_BUNDLE_IDENTIFIER = fipy.p2p.legal;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
@ -422,7 +422,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.fipParserUi;
|
PRODUCT_BUNDLE_IDENTIFIER = fipy.p2p.legal;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
@ -444,7 +444,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.fipParserUi;
|
PRODUCT_BUNDLE_IDENTIFIER = fipy.p2p.legal;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|
|
@ -1,122 +1,122 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images": [
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
"filename": "Icon-App-20x20@2x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-20x20@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
"filename": "Icon-App-20x20@3x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-20x20@3x.png",
|
"scale": "3x",
|
||||||
"scale" : "3x"
|
"size": "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
"filename": "Icon-App-29x29@1x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-29x29@1x.png",
|
"scale": "1x",
|
||||||
"scale" : "1x"
|
"size": "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
"filename": "Icon-App-29x29@2x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-29x29@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
"filename": "Icon-App-29x29@3x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-29x29@3x.png",
|
"scale": "3x",
|
||||||
"scale" : "3x"
|
"size": "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
"filename": "Icon-App-40x40@2x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-40x40@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
"filename": "Icon-App-40x40@3x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-40x40@3x.png",
|
"scale": "3x",
|
||||||
"scale" : "3x"
|
"size": "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "60x60",
|
"filename": "Icon-App-60x60@2x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-60x60@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "60x60"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "60x60",
|
"filename": "Icon-App-60x60@3x.png",
|
||||||
"idiom" : "iphone",
|
"idiom": "iphone",
|
||||||
"filename" : "Icon-App-60x60@3x.png",
|
"scale": "3x",
|
||||||
"scale" : "3x"
|
"size": "60x60"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
"filename": "Icon-App-20x20@1x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-20x20@1x.png",
|
"scale": "1x",
|
||||||
"scale" : "1x"
|
"size": "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
"filename": "Icon-App-20x20@2x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-20x20@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
"filename": "Icon-App-29x29@1x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-29x29@1x.png",
|
"scale": "1x",
|
||||||
"scale" : "1x"
|
"size": "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
"filename": "Icon-App-29x29@2x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-29x29@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
"filename": "Icon-App-40x40@1x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-40x40@1x.png",
|
"scale": "1x",
|
||||||
"scale" : "1x"
|
"size": "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
"filename": "Icon-App-40x40@2x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-40x40@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "76x76",
|
"filename": "Icon-App-76x76@1x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-76x76@1x.png",
|
"scale": "1x",
|
||||||
"scale" : "1x"
|
"size": "76x76"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "76x76",
|
"filename": "Icon-App-76x76@2x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-76x76@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "76x76"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "83.5x83.5",
|
"filename": "Icon-App-83.5x83.5@2x.png",
|
||||||
"idiom" : "ipad",
|
"idiom": "ipad",
|
||||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
"scale": "2x",
|
||||||
"scale" : "2x"
|
"size": "83.5x83.5"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "1024x1024",
|
"filename": "Icon-App-1024x1024@1x.png",
|
||||||
"idiom" : "ios-marketing",
|
"idiom": "ios-marketing",
|
||||||
"filename" : "Icon-App-1024x1024@1x.png",
|
"scale": "1x",
|
||||||
"scale" : "1x"
|
"size": "1024x1024"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info": {
|
||||||
"version" : 1,
|
"author": "icons_launcher",
|
||||||
"author" : "xcode"
|
"version": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 137 KiB |
Before Width: | Height: | Size: 467 B After Width: | Height: | Size: 512 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 786 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9.4 KiB |
|
@ -13,7 +13,7 @@
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>fip_parser_ui</string>
|
<string>fipy</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:logger/logger.dart';
|
||||||
|
|
||||||
late String token;
|
|
||||||
TextStyle globalTextStyle = TextStyle(color: Colors.grey[350]);
|
TextStyle globalTextStyle = TextStyle(color: Colors.grey[350]);
|
||||||
const proxyHeader =
|
const proxyHeader =
|
||||||
kDebugMode || !kIsWeb ? 'https://' : 'http://127.0.0.1:8080/';
|
kDebugMode || !kIsWeb ? 'https://' : 'http://127.0.0.1:8080/';
|
||||||
|
|
||||||
|
// Logger
|
||||||
|
final log = Logger();
|
||||||
|
|
||||||
|
// context
|
||||||
|
late BuildContext homeContext;
|
||||||
|
late BuildContext playerContext;
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import 'package:fip_parser_ui/providers/home.dart';
|
import 'package:fipy/providers/download.dart';
|
||||||
import 'package:fip_parser_ui/providers/player.dart';
|
import 'package:fipy/providers/home.dart';
|
||||||
import 'package:fip_parser_ui/screens/home.dart';
|
import 'package:fipy/providers/player.dart';
|
||||||
|
import 'package:fipy/screens/home.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:kplayer/kplayer.dart';
|
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
Player.boot();
|
|
||||||
runApp(const FipyApp());
|
runApp(const FipyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +24,8 @@ class FipyApp extends StatelessWidget {
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
title: 'Fipy',
|
title: 'Fipy',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
primarySwatch: Colors.blue, backgroundColor: Colors.grey[900]),
|
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.blue)
|
||||||
|
.copyWith(background: Colors.grey[900])),
|
||||||
home: const HomeScreen(title: 'Fipy'),
|
home: const HomeScreen(title: 'Fipy'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,6 +8,7 @@ class Track {
|
||||||
String? image;
|
String? image;
|
||||||
String? imageUrl;
|
String? imageUrl;
|
||||||
String? id;
|
String? id;
|
||||||
|
Duration? position;
|
||||||
Duration? duration;
|
Duration? duration;
|
||||||
File? file;
|
File? file;
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ class Track {
|
||||||
this.album,
|
this.album,
|
||||||
this.id,
|
this.id,
|
||||||
this.duration,
|
this.duration,
|
||||||
|
this.position,
|
||||||
this.file,
|
this.file,
|
||||||
this.image,
|
this.image,
|
||||||
this.imageUrl});
|
this.imageUrl});
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:fipy/globals.dart';
|
||||||
|
import 'package:fipy/models/track.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
||||||
|
|
||||||
|
class DownloadProvider with ChangeNotifier {
|
||||||
|
Future downloadMusic(BuildContext context, Track track) async {
|
||||||
|
var yt = YoutubeExplode();
|
||||||
|
var manifest = await yt.videos.streamsClient.getManifest(track.id);
|
||||||
|
var streamManifest = StreamManifest(manifest.streams);
|
||||||
|
var streamInfo = streamManifest.audioOnly.withHighestBitrate();
|
||||||
|
var stream = yt.videos.streamsClient.get(streamInfo);
|
||||||
|
final fileName = '${track.title} - ${track.artiste}'
|
||||||
|
.replaceAll('\\', '')
|
||||||
|
.replaceAll('/', '')
|
||||||
|
.replaceAll(':', '')
|
||||||
|
.replaceAll('*', '')
|
||||||
|
.replaceAll('?', '')
|
||||||
|
.replaceAll('"', '')
|
||||||
|
.replaceAll('<', '')
|
||||||
|
.replaceAll('>', '')
|
||||||
|
.replaceAll('|', '');
|
||||||
|
|
||||||
|
if (!kIsWeb) {
|
||||||
|
final filePath = Platform.isAndroid
|
||||||
|
? Directory('/storage/emulated/0/Download')
|
||||||
|
: await getDownloadsDirectory();
|
||||||
|
|
||||||
|
var file = File('${filePath!.path}/$fileName.webm');
|
||||||
|
var fileStream = file.openWrite();
|
||||||
|
|
||||||
|
await stream.pipe(fileStream);
|
||||||
|
|
||||||
|
await fileStream.flush();
|
||||||
|
await fileStream.close();
|
||||||
|
yt.close();
|
||||||
|
// convertToMp3(file.path);
|
||||||
|
|
||||||
|
track.file = file;
|
||||||
|
|
||||||
|
ScaffoldMessenger.of(playerContext).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content:
|
||||||
|
SizedBox(height: 90, child: Text('Son téléchargé: ${file.path}')),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
log.d(file.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reload() {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,21 @@
|
||||||
// ignore_for_file: avoid_print
|
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'package:fipy/globals.dart';
|
||||||
import 'package:fip_parser_ui/models/track.dart';
|
import 'package:fipy/models/track.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:kplayer/kplayer.dart';
|
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
||||||
import 'package:fip_parser_ui/providers/player.dart';
|
import 'package:fipy/providers/player.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
|
|
||||||
class HomeProvider with ChangeNotifier {
|
class HomeProvider with ChangeNotifier {
|
||||||
Track? currentTrack;
|
Track? currentTrack;
|
||||||
PlayerController? player;
|
AudioPlayer player = AudioPlayer(playerId: 'fipyPlayerID');
|
||||||
|
|
||||||
List<Track> trackList = [];
|
List<Track> trackList = [];
|
||||||
int trackNbr = 0;
|
int trackNbr = 0;
|
||||||
int userPageNbr = 3;
|
int userPageNbr = 3;
|
||||||
|
double currentVolume = 1;
|
||||||
|
|
||||||
Future<List<Track>> getTracks(String radio, {String cursor = ''}) async {
|
Future<List<Track>> getTracks(String radio, {String cursor = ''}) async {
|
||||||
int pageNbr = 0;
|
int pageNbr = 0;
|
||||||
|
@ -25,18 +24,20 @@ class HomeProvider with ChangeNotifier {
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
while (pageNbr < userPageNbr && !stop) {
|
while (pageNbr < userPageNbr && !stop) {
|
||||||
final req = Uri.parse(
|
final req = Uri.parse(
|
||||||
'https://www.radiofrance.fr/api/v1.7/stations/fip/webradios/$radio/songs?pageCursor=$cursor');
|
'${proxyHeader}www.radiofrance.fr:443/api/v1.7/stations/fip/webradios/$radio/songs?pageCursor=$cursor');
|
||||||
|
|
||||||
final res = await get(req, headers: {
|
final res = await get(req, headers: {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS"
|
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
|
||||||
|
'Content-Type': 'text/plain'
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
Map body = jsonDecode(res.body);
|
Map body = jsonDecode(res.body);
|
||||||
if (body['next'] != null) {
|
if (body['next'] != null) {
|
||||||
cursor = body['next'];
|
cursor = body['next'];
|
||||||
} else {
|
} else {
|
||||||
print('Page N°$pageNbr');
|
log.d('Page N°$pageNbr');
|
||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,115 +66,112 @@ class HomeProvider with ChangeNotifier {
|
||||||
return trackList;
|
return trackList;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future playTrack(BuildContext context, Track track) async {
|
Future playTrack(Track track) async {
|
||||||
var yt = YoutubeExplode();
|
var yt = YoutubeExplode();
|
||||||
PlayerProvider playerProvider =
|
PlayerProvider playerProvider =
|
||||||
Provider.of<PlayerProvider>(context, listen: false);
|
Provider.of<PlayerProvider>(homeContext, listen: false);
|
||||||
HomeProvider homeProvider =
|
HomeProvider homeProvider =
|
||||||
Provider.of<HomeProvider>(context, listen: false);
|
Provider.of<HomeProvider>(homeContext, listen: false);
|
||||||
|
|
||||||
// track = trackList[track.number - 1];
|
// track = trackList[track.number - 1];
|
||||||
currentTrack = track;
|
currentTrack = track;
|
||||||
|
|
||||||
final currentVolume = player?.volume ?? 1;
|
|
||||||
player?.dispose();
|
|
||||||
Future.delayed(const Duration(milliseconds: 5));
|
|
||||||
|
|
||||||
if (track.file == null) {
|
|
||||||
if (track.id == null) {
|
if (track.id == null) {
|
||||||
final secondMatch = track.artiste == '' ? track.album : track.artiste;
|
final secondMatch = track.artiste == '' ? track.album : track.artiste;
|
||||||
final resultUrl =
|
final resultUrl = await yt.search
|
||||||
await yt.search.search(track.title + ' ' + secondMatch!);
|
.search('${track.title} ${secondMatch!}', filter: TypeFilters.video);
|
||||||
track.id = resultUrl.first.id.value;
|
track.id = resultUrl.first.id.value;
|
||||||
}
|
}
|
||||||
player = Player.network(
|
const invidiousUrl = [
|
||||||
"https://invidious.fdn.fr/embed/${track.id}?raw=1&listen=1");
|
'yewtu.be',
|
||||||
print(track.id);
|
'vid.puffyan.us',
|
||||||
} else {
|
'invidious.snopyta.org',
|
||||||
player = Player.asset(track.file!.path);
|
'invidious.fdn.fr',
|
||||||
}
|
];
|
||||||
player!.volume = currentVolume;
|
|
||||||
|
player.stop();
|
||||||
|
Future.delayed(const Duration(milliseconds: 5));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
player!.play();
|
final source = UrlSource(
|
||||||
|
"https://${invidiousUrl[3]}/latest_version?id=${track.id}&itag=140&local=true&listen=1");
|
||||||
|
log.d(source.url);
|
||||||
|
await player.play(source);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Play error: ' + e.toString());
|
log.d('Play error: $e');
|
||||||
}
|
}
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
Future.delayed(const Duration(milliseconds: 50));
|
||||||
player!.callback = (PlayerEvent event) {
|
|
||||||
if (event.name == 'position') {
|
player.onDurationChanged.listen((event) async {
|
||||||
currentTrack!.duration = player!.duration;
|
currentTrack!.duration = await player.getDuration();
|
||||||
playerProvider.reload();
|
playerProvider.reload();
|
||||||
}
|
});
|
||||||
if (event.name == 'status') {
|
|
||||||
var nextTrack = trackList
|
player.onPositionChanged.listen((position) async {
|
||||||
.firstWhere((element) => element.number == track.number + 1);
|
currentTrack!.position = position;
|
||||||
playTrack(context, nextTrack);
|
playerProvider.reload();
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
player.onPlayerComplete.listen((event) {
|
||||||
|
var nextTrack =
|
||||||
|
trackList.firstWhere((element) => element.number == track.number + 1);
|
||||||
|
currentTrack = nextTrack;
|
||||||
|
playTrack(nextTrack);
|
||||||
|
});
|
||||||
|
|
||||||
playerProvider.reload();
|
playerProvider.reload();
|
||||||
homeProvider.reload();
|
homeProvider.reload();
|
||||||
yt.close();
|
yt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future downloadMusic(BuildContext context, Track track) async {
|
Future nextTrack() async {
|
||||||
var yt = YoutubeExplode();
|
if (currentTrack != null && currentTrack!.number < trackList.last.number) {
|
||||||
var manifest = await yt.videos.streamsClient.getManifest(track.id);
|
currentTrack = trackList
|
||||||
var streamManifest = StreamManifest(manifest.streams);
|
.firstWhere((element) => element.number == currentTrack!.number + 1);
|
||||||
var streamInfo = streamManifest.audioOnly.withHighestBitrate();
|
await playTrack(currentTrack!);
|
||||||
var stream = yt.videos.streamsClient.get(streamInfo);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final filePath = await getDownloadsDirectory();
|
Future backTrack() async {
|
||||||
final fileName = '${track.title} - ${track.artiste}'
|
if (currentTrack != null && currentTrack!.number > 1) {
|
||||||
.replaceAll('\\', '')
|
currentTrack = trackList
|
||||||
.replaceAll('/', '')
|
.firstWhere((element) => element.number == currentTrack!.number - 1);
|
||||||
.replaceAll(':', '')
|
await playTrack(currentTrack!);
|
||||||
.replaceAll('*', '')
|
}
|
||||||
.replaceAll('?', '')
|
}
|
||||||
.replaceAll('"', '')
|
|
||||||
.replaceAll('<', '')
|
|
||||||
.replaceAll('>', '')
|
|
||||||
.replaceAll('|', '');
|
|
||||||
var file = File('${filePath!.path}/$fileName.webm');
|
|
||||||
var fileStream = file.openWrite();
|
|
||||||
|
|
||||||
await stream.pipe(fileStream);
|
void resumePlay() {
|
||||||
|
if (currentTrack == null) {
|
||||||
await fileStream.flush();
|
currentTrack = trackList.first;
|
||||||
await fileStream.close();
|
playTrack(currentTrack!);
|
||||||
yt.close();
|
} else {
|
||||||
|
player.state.name == 'playing' ? player.pause() : player.resume();
|
||||||
// Play it
|
}
|
||||||
track.file = file;
|
|
||||||
// playTrack(context, track);
|
|
||||||
|
|
||||||
print(file.path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DropdownMenuItem<String>> get radioList {
|
List<DropdownMenuItem<String>> get radioList {
|
||||||
List<DropdownMenuItem<String>> menuItems = [
|
List<DropdownMenuItem<String>> menuItems = [
|
||||||
const DropdownMenuItem(child: Text("FIP"), value: "fip"),
|
const DropdownMenuItem(value: "fip", child: Text("FIP")),
|
||||||
const DropdownMenuItem(child: Text("Electro"), value: "fip_electro"),
|
const DropdownMenuItem(value: "fip_electro", child: Text("Electro")),
|
||||||
const DropdownMenuItem(child: Text("Groove"), value: "fip_groove"),
|
const DropdownMenuItem(value: "fip_groove", child: Text("Groove")),
|
||||||
const DropdownMenuItem(child: Text("Rock"), value: "fip_rock"),
|
const DropdownMenuItem(value: "fip_rock", child: Text("Rock")),
|
||||||
const DropdownMenuItem(child: Text("Jazz"), value: "fip_jazz"),
|
const DropdownMenuItem(value: "fip_jazz", child: Text("Jazz")),
|
||||||
const DropdownMenuItem(child: Text("Pop"), value: "fip_pop"),
|
const DropdownMenuItem(value: "fip_pop", child: Text("Pop")),
|
||||||
const DropdownMenuItem(child: Text("Reggae"), value: "fip_reggae"),
|
const DropdownMenuItem(value: "fip_reggae", child: Text("Reggae")),
|
||||||
const DropdownMenuItem(child: Text("World"), value: "fip_world"),
|
const DropdownMenuItem(value: "fip_world", child: Text("World")),
|
||||||
const DropdownMenuItem(
|
const DropdownMenuItem(
|
||||||
child: Text("Nouveautés"), value: "fip_nouveautes"),
|
value: "fip_nouveautes", child: Text("Nouveautés")),
|
||||||
];
|
];
|
||||||
return menuItems;
|
return menuItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DropdownMenuItem<String>> get pageList {
|
List<DropdownMenuItem<String>> get pageList {
|
||||||
List<DropdownMenuItem<String>> menuItems = [
|
List<DropdownMenuItem<String>> menuItems = [
|
||||||
const DropdownMenuItem(child: Text("25"), value: "3"),
|
const DropdownMenuItem(value: "3", child: Text("25")),
|
||||||
const DropdownMenuItem(child: Text("50"), value: "6"),
|
const DropdownMenuItem(value: "6", child: Text("50")),
|
||||||
const DropdownMenuItem(child: Text("100"), value: "12"),
|
const DropdownMenuItem(value: "12", child: Text("100")),
|
||||||
const DropdownMenuItem(child: Text("200"), value: "25"),
|
const DropdownMenuItem(value: "25", child: Text("200")),
|
||||||
const DropdownMenuItem(child: Text("500"), value: "62"),
|
const DropdownMenuItem(value: "62", child: Text("500")),
|
||||||
];
|
];
|
||||||
return menuItems;
|
return menuItems;
|
||||||
}
|
}
|
||||||
|
@ -182,9 +180,3 @@ class HomeProvider with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DownloadProvider with ChangeNotifier {
|
|
||||||
void reload() {
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
// ignore_for_file: prefer_const_literals_to_create_immutables, avoid_print
|
// ignore_for_file: prefer_const_literals_to_create_immutables, avoid_print
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:fip_parser_ui/models/track.dart';
|
import 'package:fipy/globals.dart';
|
||||||
import 'package:fip_parser_ui/providers/home.dart';
|
import 'package:fipy/models/track.dart';
|
||||||
import 'package:fip_parser_ui/providers/player.dart';
|
import 'package:fipy/providers/home.dart';
|
||||||
|
import 'package:fipy/providers/player.dart';
|
||||||
|
import 'package:fipy/widgets/download_track.dart';
|
||||||
|
import 'package:fipy/widgets/player/player.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:miniplayer/miniplayer.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
|
||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
const HomeScreen({Key? key, required this.title}) : super(key: key);
|
const HomeScreen({Key? key, required this.title}) : super(key: key);
|
||||||
|
@ -21,19 +23,38 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
homeContext = context;
|
||||||
HomeProvider hp = Provider.of<HomeProvider>(context, listen: false);
|
HomeProvider hp = Provider.of<HomeProvider>(context, listen: false);
|
||||||
final MiniplayerController controller = MiniplayerController();
|
|
||||||
|
|
||||||
return Stack(
|
return RawKeyboardListener(
|
||||||
|
autofocus: true,
|
||||||
|
focusNode: FocusNode(),
|
||||||
|
onKey: (RawKeyEvent event) {
|
||||||
|
// log.d(event.data.logicalKey.keyId);
|
||||||
|
if (event.runtimeType == RawKeyDownEvent) //Enter Key ID from keyboard
|
||||||
|
{
|
||||||
|
switch (event.data.logicalKey.keyId) {
|
||||||
|
case 32:
|
||||||
|
case 112:
|
||||||
|
case 4294969861:
|
||||||
|
hp.resumePlay();
|
||||||
|
break;
|
||||||
|
case 110:
|
||||||
|
case 94489280688:
|
||||||
|
hp.nextTrack();
|
||||||
|
break;
|
||||||
|
case 98:
|
||||||
|
case 94489280689:
|
||||||
|
hp.backTrack();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Scaffold(
|
Scaffold(
|
||||||
body: RawScrollbar(
|
backgroundColor: Colors.black,
|
||||||
thumbColor: Colors.grey[600],
|
body: SingleChildScrollView(
|
||||||
radius: const Radius.circular(20),
|
|
||||||
thickness: 12,
|
|
||||||
thumbVisibility: true,
|
|
||||||
mainAxisMargin: 70,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
|
@ -78,8 +99,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
AsyncSnapshot<List<Track>> snapshot,
|
AsyncSnapshot<List<Track>> snapshot,
|
||||||
) {
|
) {
|
||||||
print(snapshot.connectionState);
|
print(snapshot.connectionState);
|
||||||
if (snapshot.connectionState ==
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
ConnectionState.waiting) {
|
|
||||||
return Stack(children: [
|
return Stack(children: [
|
||||||
Container(
|
Container(
|
||||||
height: 10000,
|
height: 10000,
|
||||||
|
@ -110,7 +130,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Text(
|
Text(
|
||||||
'Error: ' + snapshot.error.toString(),
|
'Error: ${snapshot.error}',
|
||||||
style: TextStyle(color: Colors.grey[500]),
|
style: TextStyle(color: Colors.grey[500]),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
@ -126,18 +146,16 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
defaultVerticalAlignment:
|
defaultVerticalAlignment:
|
||||||
TableCellVerticalAlignment.middle,
|
TableCellVerticalAlignment.middle,
|
||||||
children: snapshot.data!
|
children: snapshot.data!
|
||||||
.map((item) => _buildTableRow(item, context))
|
.map((item) => _buildTableRow(item))
|
||||||
.toList()
|
.toList()
|
||||||
..insert(
|
..insert(
|
||||||
0,
|
0,
|
||||||
_buildTableRow(
|
_buildTableRow(Track(
|
||||||
Track(
|
|
||||||
number: -1,
|
number: -1,
|
||||||
title: 'TITRE',
|
title: 'TITRE',
|
||||||
artiste: 'ARTISTE',
|
artiste: 'ARTISTE',
|
||||||
album: 'ALBUM',
|
album: 'ALBUM',
|
||||||
id: 'URL'),
|
id: 'URL')),
|
||||||
context),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,234 +169,23 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
const SizedBox(height: 70)
|
const SizedBox(height: 70)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)),
|
|
||||||
),
|
|
||||||
Consumer<PlayerProvider>(builder: (context, playerProvider, _) {
|
|
||||||
TextEditingController trackTitle = TextEditingController();
|
|
||||||
TextEditingController trackArtiste = TextEditingController();
|
|
||||||
trackTitle.text = hp.currentTrack?.title ?? '';
|
|
||||||
trackArtiste.text = hp.currentTrack?.artiste ?? '';
|
|
||||||
return Miniplayer(
|
|
||||||
controller: controller,
|
|
||||||
backgroundColor: Colors.grey[900]!,
|
|
||||||
minHeight: 70,
|
|
||||||
maxHeight: 370,
|
|
||||||
builder: (height, percentage) {
|
|
||||||
return Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
hp.currentTrack?.imageUrl != '' &&
|
|
||||||
hp.currentTrack?.imageUrl != null
|
|
||||||
? Image.network(
|
|
||||||
hp.currentTrack!.imageUrl!,
|
|
||||||
width: 70,
|
|
||||||
)
|
|
||||||
: const SizedBox(width: 70),
|
|
||||||
Expanded(
|
|
||||||
child: Column(children: [
|
|
||||||
SizedBox(
|
|
||||||
height: 20,
|
|
||||||
child: TextField(
|
|
||||||
enabled: false,
|
|
||||||
maxLines: 1,
|
|
||||||
controller: trackTitle,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
border: InputBorder.none,
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
disabledBorder: InputBorder.none,
|
|
||||||
contentPadding: EdgeInsets.only(left: 15),
|
|
||||||
),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Colors.grey[300],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const Player()
|
||||||
SizedBox(
|
|
||||||
height: 20,
|
|
||||||
child: TextField(
|
|
||||||
enabled: false,
|
|
||||||
maxLines: 1,
|
|
||||||
controller: trackArtiste,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
border: InputBorder.none,
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
disabledBorder: InputBorder.none,
|
|
||||||
contentPadding: EdgeInsets.only(left: 15),
|
|
||||||
),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: Colors.grey[500],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
Column(children: [
|
|
||||||
const Spacer(),
|
|
||||||
Row(children: [
|
|
||||||
const SizedBox(width: 70),
|
|
||||||
Column(children: [
|
|
||||||
IconButton(
|
|
||||||
padding: const EdgeInsets.all(0),
|
|
||||||
icon: Icon(Icons.skip_previous,
|
|
||||||
color: Colors.grey[500], size: 32),
|
|
||||||
onPressed: () {
|
|
||||||
if (hp.currentTrack != null &&
|
|
||||||
hp.currentTrack!.number > 1) {
|
|
||||||
hp.currentTrack = hp.trackList.firstWhere(
|
|
||||||
(element) =>
|
|
||||||
element.number ==
|
|
||||||
hp.currentTrack!.number - 1);
|
|
||||||
hp.playTrack(context, hp.currentTrack!);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
]),
|
|
||||||
const SizedBox(width: 1),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
hp.player?.playing ?? false
|
|
||||||
? hp.player?.pause()
|
|
||||||
: hp.player?.play();
|
|
||||||
playerProvider.reload();
|
|
||||||
},
|
|
||||||
child: Icon(
|
|
||||||
hp.player?.playing ?? false
|
|
||||||
? Icons.pause
|
|
||||||
: Icons.play_arrow,
|
|
||||||
color: Colors.grey[900],
|
|
||||||
size: 30),
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
shape: const CircleBorder(),
|
|
||||||
padding: const EdgeInsets.all(12),
|
|
||||||
primary: Colors.grey[300],
|
|
||||||
onPrimary: Colors.grey[900],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Column(children: [
|
|
||||||
IconButton(
|
|
||||||
padding: const EdgeInsets.all(0),
|
|
||||||
icon: Icon(Icons.skip_next,
|
|
||||||
color: Colors.grey[500], size: 32),
|
|
||||||
onPressed: () {
|
|
||||||
if (hp.currentTrack != null &&
|
|
||||||
hp.currentTrack!.number <
|
|
||||||
hp.trackList.last.number) {
|
|
||||||
hp.currentTrack = hp.trackList.firstWhere(
|
|
||||||
(element) =>
|
|
||||||
element.number ==
|
|
||||||
hp.currentTrack!.number + 1);
|
|
||||||
hp.playTrack(context, hp.currentTrack!);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
// const SizedBox(height: 7),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
const Spacer(),
|
|
||||||
Row(children: [
|
|
||||||
const SizedBox(width: 70),
|
|
||||||
Text(
|
|
||||||
timeFormat(
|
|
||||||
hp.player?.position ?? const Duration(seconds: 0)),
|
|
||||||
style: TextStyle(color: Colors.grey[500], fontSize: 12),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 3),
|
|
||||||
SliderTheme(
|
|
||||||
data: const SliderThemeData(
|
|
||||||
thumbShape:
|
|
||||||
RoundSliderThumbShape(enabledThumbRadius: 2),
|
|
||||||
overlayShape:
|
|
||||||
RoundSliderThumbShape(enabledThumbRadius: 5),
|
|
||||||
trackHeight: 2,
|
|
||||||
),
|
|
||||||
child: SizedBox(
|
|
||||||
width: 300,
|
|
||||||
child: Slider(
|
|
||||||
value: double.parse(
|
|
||||||
hp.player?.position.inSeconds.toString() ??
|
|
||||||
'0'),
|
|
||||||
max: double.parse(
|
|
||||||
hp.player?.duration.inSeconds.toString() ??
|
|
||||||
'2000'),
|
|
||||||
onChanged: (double value) {
|
|
||||||
if (hp.player?.position != null) {
|
|
||||||
hp.player!.position =
|
|
||||||
Duration(seconds: value.toInt());
|
|
||||||
playerProvider.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
activeColor: Colors.grey[400],
|
|
||||||
inactiveColor: Colors.grey[700],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 3),
|
|
||||||
Text(
|
|
||||||
timeFormat(
|
|
||||||
hp.player?.duration ?? const Duration(seconds: 0)),
|
|
||||||
style: TextStyle(color: Colors.grey[500], fontSize: 12),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
const Spacer(),
|
|
||||||
]),
|
|
||||||
const Spacer(),
|
|
||||||
SliderTheme(
|
|
||||||
data: const SliderThemeData(
|
|
||||||
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7),
|
|
||||||
overlayShape:
|
|
||||||
RoundSliderThumbShape(enabledThumbRadius: 8),
|
|
||||||
trackHeight: 2.5,
|
|
||||||
),
|
|
||||||
child: SizedBox(
|
|
||||||
width: 130,
|
|
||||||
child: Slider(
|
|
||||||
value: hp.player?.volume ?? 1,
|
|
||||||
max: 1,
|
|
||||||
onChanged: (double value) {
|
|
||||||
if (hp.player?.volume != null) {
|
|
||||||
hp.player!.volume = value;
|
|
||||||
playerProvider.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
activeColor: Colors.grey[400],
|
|
||||||
inactiveColor: Colors.grey[700],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 20)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
})
|
|
||||||
],
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget trackLine(Track track) {
|
TableRow _buildTableRow(Track track) {
|
||||||
return SizedBox(
|
final hp = Provider.of<HomeProvider>(homeContext, listen: false);
|
||||||
height: 30,
|
|
||||||
child: Row(
|
|
||||||
children: [Text(track.title + ' - ' + track.artiste)],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
TableRow _buildTableRow(Track track, BuildContext context) {
|
|
||||||
DownloadProvider downloadProvider =
|
|
||||||
Provider.of<DownloadProvider>(context, listen: false);
|
|
||||||
HomeProvider hp = Provider.of<HomeProvider>(context, listen: false);
|
|
||||||
int isDownloading = -1;
|
|
||||||
|
|
||||||
final textStyle = TextStyle(
|
final textStyle = TextStyle(
|
||||||
fontWeight: track.number == -1 ? FontWeight.w200 : FontWeight.normal,
|
fontWeight: track.number == -1 ? FontWeight.w200 : FontWeight.normal,
|
||||||
color: Colors.grey[500],
|
color: Colors.grey[500],
|
||||||
fontSize: track.number == -1 ? 15 : 14);
|
fontSize: track.number == -1 ? 15 : 14);
|
||||||
const rowPadding = EdgeInsets.all(10);
|
const rowPadding = EdgeInsets.all(10);
|
||||||
final yt = YoutubeExplode();
|
|
||||||
|
|
||||||
return TableRow(
|
return TableRow(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
|
@ -391,7 +198,7 @@ TableRow _buildTableRow(Track track, BuildContext context) {
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (track.number != -1) {
|
if (track.number != -1) {
|
||||||
hp.playTrack(context, track);
|
hp.playTrack(track);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
|
@ -409,7 +216,10 @@ TableRow _buildTableRow(Track track, BuildContext context) {
|
||||||
return Text(track.title,
|
return Text(track.title,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
color: hp.currentTrack?.title == track.title && hp.currentTrack?.artiste == track.artiste
|
color:
|
||||||
|
hp.currentTrack?.title == track.title &&
|
||||||
|
hp.currentTrack?.artiste ==
|
||||||
|
track.artiste
|
||||||
? Colors.green
|
? Colors.green
|
||||||
: Colors.grey[350],
|
: Colors.grey[350],
|
||||||
fontSize: 14));
|
fontSize: 14));
|
||||||
|
@ -434,48 +244,8 @@ TableRow _buildTableRow(Track track, BuildContext context) {
|
||||||
TableCell(
|
TableCell(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: rowPadding,
|
padding: rowPadding,
|
||||||
child: InkWell(
|
child: DownloadTrack(track: track),
|
||||||
onTap: () async {
|
|
||||||
isDownloading = track.number;
|
|
||||||
downloadProvider.reload();
|
|
||||||
if (track.id == null) {
|
|
||||||
final secondMatch =
|
|
||||||
track.artiste == '' ? track.album : track.artiste;
|
|
||||||
final resultUrl = await yt.search
|
|
||||||
.search(track.title + ' ' + secondMatch!);
|
|
||||||
track.id = resultUrl.first.id.value;
|
|
||||||
}
|
|
||||||
if (track.id != null) {
|
|
||||||
hp.downloadMusic(context, track);
|
|
||||||
}
|
|
||||||
isDownloading = -1;
|
|
||||||
yt.close();
|
|
||||||
downloadProvider.reload();
|
|
||||||
},
|
|
||||||
child: track.number == -1
|
|
||||||
? Text('TÉLÉCHARGER', style: textStyle)
|
|
||||||
: Consumer<DownloadProvider>(builder: (context, _, __) {
|
|
||||||
return Row(children: [
|
|
||||||
const SizedBox(width: 37),
|
|
||||||
isDownloading == track.number
|
|
||||||
? SizedBox(
|
|
||||||
height: 20,
|
|
||||||
width: 20,
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
color: Colors.grey[500],
|
|
||||||
),
|
),
|
||||||
)
|
|
||||||
: Icon(Icons.download, color: Colors.grey[500]),
|
|
||||||
]);
|
|
||||||
}))),
|
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
String timeFormat(Duration d) {
|
|
||||||
String dd = d.toString().split('.').first;
|
|
||||||
String minutes = dd.toString().split(':')[1];
|
|
||||||
String seconds = dd.toString().split(':')[2];
|
|
||||||
return '$minutes:$seconds';
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
import 'package:fipy/models/track.dart';
|
||||||
|
import 'package:fipy/providers/download.dart';
|
||||||
|
import 'package:fipy/providers/home.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
||||||
|
|
||||||
|
class DownloadTrack extends StatelessWidget {
|
||||||
|
const DownloadTrack({Key? key, this.track}) : super(key: key);
|
||||||
|
|
||||||
|
final Track? track;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final hp = Provider.of<HomeProvider>(context, listen: true);
|
||||||
|
final dl = Provider.of<DownloadProvider>(context, listen: false);
|
||||||
|
int isDownloading = -2;
|
||||||
|
final yt = YoutubeExplode();
|
||||||
|
|
||||||
|
final track = this.track ??
|
||||||
|
hp.currentTrack ??
|
||||||
|
Track(number: -3, title: 'title', artiste: 'artiste');
|
||||||
|
|
||||||
|
return InkWell(
|
||||||
|
onTap: track.number == -3
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
isDownloading = track.number;
|
||||||
|
dl.reload();
|
||||||
|
if (track.id == null) {
|
||||||
|
final secondMatch =
|
||||||
|
track.artiste == '' ? track.album : track.artiste;
|
||||||
|
final resultUrl =
|
||||||
|
await yt.search.search('${track.title} ${secondMatch!}');
|
||||||
|
track.id = resultUrl.first.id.value;
|
||||||
|
}
|
||||||
|
if (track.id != null) {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
await dl.downloadMusic(context, track);
|
||||||
|
}
|
||||||
|
isDownloading = -2;
|
||||||
|
yt.close();
|
||||||
|
dl.reload();
|
||||||
|
},
|
||||||
|
child: Consumer<DownloadProvider>(builder: (context, _, __) {
|
||||||
|
return Row(children: [
|
||||||
|
const SizedBox(width: 37),
|
||||||
|
isDownloading == track.number
|
||||||
|
? SizedBox(
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Icon(Icons.download, color: Colors.grey[500]),
|
||||||
|
]);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
import 'package:fipy/globals.dart';
|
||||||
|
import 'package:fipy/providers/home.dart';
|
||||||
|
import 'package:fipy/widgets/download_track.dart';
|
||||||
|
import 'package:fipy/widgets/player/player_controls.dart';
|
||||||
|
import 'package:fipy/widgets/player/player_title.dart';
|
||||||
|
import 'package:fipy/widgets/player/player_volume.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:miniplayer/miniplayer.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class Player extends StatelessWidget {
|
||||||
|
const Player({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
playerContext = context;
|
||||||
|
final controller = MiniplayerController();
|
||||||
|
final hp = Provider.of<HomeProvider>(context, listen: false);
|
||||||
|
|
||||||
|
return Miniplayer(
|
||||||
|
controller: controller,
|
||||||
|
backgroundColor: Colors.grey[900]!,
|
||||||
|
minHeight: 70,
|
||||||
|
maxHeight: 70,
|
||||||
|
builder: (height, percentage) {
|
||||||
|
return Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
hp.currentTrack?.imageUrl != '' && hp.currentTrack?.imageUrl != null
|
||||||
|
? Image.network(
|
||||||
|
hp.currentTrack!.imageUrl!,
|
||||||
|
width: 70,
|
||||||
|
)
|
||||||
|
: const SizedBox(width: 70),
|
||||||
|
const PlayerTitle(),
|
||||||
|
const SizedBox(width: 90),
|
||||||
|
const PlayerControls(),
|
||||||
|
const Spacer(),
|
||||||
|
const DownloadTrack(),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
const PlayerVolume(),
|
||||||
|
const SizedBox(width: 20)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
import 'package:fipy/providers/home.dart';
|
||||||
|
import 'package:fipy/providers/player.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class PlayerControls extends StatelessWidget {
|
||||||
|
const PlayerControls({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final hp = Provider.of<HomeProvider>(context, listen: true);
|
||||||
|
final playerProvider = Provider.of<PlayerProvider>(context, listen: true);
|
||||||
|
return Column(children: [
|
||||||
|
const Spacer(),
|
||||||
|
Row(children: [
|
||||||
|
const SizedBox(width: 70),
|
||||||
|
Column(children: [
|
||||||
|
IconButton(
|
||||||
|
padding: const EdgeInsets.all(0),
|
||||||
|
icon:
|
||||||
|
Icon(Icons.skip_previous, color: Colors.grey[500], size: 32),
|
||||||
|
onPressed: () {
|
||||||
|
hp.backTrack();
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
const SizedBox(width: 1),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
hp.resumePlay();
|
||||||
|
},
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: Colors.grey[900],
|
||||||
|
backgroundColor: Colors.grey[300],
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
hp.player.state.name == 'playing'
|
||||||
|
? Icons.pause
|
||||||
|
: Icons.play_arrow,
|
||||||
|
color: Colors.grey[900],
|
||||||
|
size: 30),
|
||||||
|
),
|
||||||
|
Column(children: [
|
||||||
|
IconButton(
|
||||||
|
padding: const EdgeInsets.all(0),
|
||||||
|
icon: Icon(Icons.skip_next, color: Colors.grey[500], size: 32),
|
||||||
|
onPressed: () {
|
||||||
|
hp.nextTrack();
|
||||||
|
}),
|
||||||
|
// const SizedBox(height: 7),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
const Spacer(),
|
||||||
|
Row(children: [
|
||||||
|
const SizedBox(width: 70),
|
||||||
|
Text(
|
||||||
|
timeFormat(hp.currentTrack?.position ?? const Duration(seconds: 0)),
|
||||||
|
style: TextStyle(color: Colors.grey[500], fontSize: 12),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 3),
|
||||||
|
(hp.currentTrack?.duration?.inSeconds ?? -1) <= 0
|
||||||
|
? Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(width: 300),
|
||||||
|
hp.currentTrack?.title == null
|
||||||
|
? Text(
|
||||||
|
'Choisissez un titre',
|
||||||
|
style: TextStyle(color: Colors.grey[500]),
|
||||||
|
)
|
||||||
|
: const SizedBox(
|
||||||
|
height: 15,
|
||||||
|
width: 15,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
color: Colors.orange,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: SliderTheme(
|
||||||
|
data: const SliderThemeData(
|
||||||
|
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 2),
|
||||||
|
overlayShape: RoundSliderThumbShape(enabledThumbRadius: 5),
|
||||||
|
trackHeight: 2,
|
||||||
|
),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 300,
|
||||||
|
child: Slider(
|
||||||
|
value: double.parse(
|
||||||
|
hp.currentTrack?.position?.inSeconds.toString() ?? '0'),
|
||||||
|
max: double.parse(
|
||||||
|
hp.currentTrack?.duration?.inSeconds.toString() ??
|
||||||
|
'2000'),
|
||||||
|
onChanged: (double value) {
|
||||||
|
if (hp.currentTrack?.position != null) {
|
||||||
|
hp.player.seek(
|
||||||
|
Duration(seconds: value.toInt()),
|
||||||
|
);
|
||||||
|
playerProvider.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
activeColor: Colors.grey[400],
|
||||||
|
inactiveColor: Colors.grey[700],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 3),
|
||||||
|
Text(
|
||||||
|
timeFormat(hp.currentTrack?.duration ?? const Duration(seconds: 0)),
|
||||||
|
style: TextStyle(color: Colors.grey[500], fontSize: 12),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
const Spacer(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String timeFormat(Duration d) {
|
||||||
|
String dd = d.toString().split('.').first;
|
||||||
|
String minutes = dd.toString().split(':')[1];
|
||||||
|
String seconds = dd.toString().split(':')[2];
|
||||||
|
return '$minutes:$seconds';
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
import 'package:fipy/providers/home.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class PlayerTitle extends StatelessWidget {
|
||||||
|
const PlayerTitle({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final hp = Provider.of<HomeProvider>(context, listen: true);
|
||||||
|
final trackTitle = TextEditingController();
|
||||||
|
final trackArtiste = TextEditingController();
|
||||||
|
trackTitle.text = hp.currentTrack?.title ?? '';
|
||||||
|
trackArtiste.text = hp.currentTrack?.artiste ?? '';
|
||||||
|
|
||||||
|
return Expanded(
|
||||||
|
child: Column(children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
child: TextField(
|
||||||
|
enabled: false,
|
||||||
|
maxLines: 1,
|
||||||
|
controller: trackTitle,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
disabledBorder: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.only(left: 15),
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey[300],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
child: TextField(
|
||||||
|
enabled: false,
|
||||||
|
maxLines: 1,
|
||||||
|
controller: trackArtiste,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
disabledBorder: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.only(left: 15),
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:fipy/providers/home.dart';
|
||||||
|
import 'package:fipy/providers/player.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class PlayerVolume extends StatelessWidget {
|
||||||
|
const PlayerVolume({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final hp = Provider.of<HomeProvider>(context, listen: false);
|
||||||
|
final playerProvider = Provider.of<PlayerProvider>(context, listen: true);
|
||||||
|
|
||||||
|
return SliderTheme(
|
||||||
|
data: const SliderThemeData(
|
||||||
|
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7),
|
||||||
|
overlayShape: RoundSliderThumbShape(enabledThumbRadius: 8),
|
||||||
|
trackHeight: 2.5,
|
||||||
|
),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 130,
|
||||||
|
child: Slider(
|
||||||
|
value: hp.currentVolume,
|
||||||
|
max: 1,
|
||||||
|
onChanged: (double value) async {
|
||||||
|
hp.currentVolume = value;
|
||||||
|
await hp.player.setVolume(value);
|
||||||
|
playerProvider.reload();
|
||||||
|
},
|
||||||
|
activeColor: Colors.grey[400],
|
||||||
|
inactiveColor: Colors.grey[700],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10)
|
||||||
project(runner LANGUAGES CXX)
|
project(runner LANGUAGES CXX)
|
||||||
|
|
||||||
set(BINARY_NAME "fipy")
|
set(BINARY_NAME "fipy")
|
||||||
set(APPLICATION_ID "com.example.fipy")
|
set(APPLICATION_ID "fipy.p2p.legal")
|
||||||
|
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,10 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <dart_vlc/dart_vlc_plugin.h>
|
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
g_autoptr(FlPluginRegistrar) dart_vlc_registrar =
|
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "DartVlcPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||||
dart_vlc_plugin_register_with_registrar(dart_vlc_registrar);
|
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
|
||||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
dart_vlc
|
audioplayers_linux
|
||||||
url_launcher_linux
|
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
//
|
||||||
|
// Generated file. Do not edit.
|
||||||
|
//
|
||||||
|
|
||||||
|
import FlutterMacOS
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
import audioplayers_darwin
|
||||||
|
import path_provider_foundation
|
||||||
|
|
||||||
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||||
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// This is a generated file; do not edit or check into version control.
|
||||||
|
FLUTTER_ROOT=C:\Users\poka\dev\flutter
|
||||||
|
FLUTTER_APPLICATION_PATH=C:\Users\poka\dev\fipy
|
||||||
|
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||||
|
FLUTTER_BUILD_DIR=build
|
||||||
|
FLUTTER_BUILD_NAME=0.0.2
|
||||||
|
FLUTTER_BUILD_NUMBER=2
|
||||||
|
DART_OBFUSCATION=false
|
||||||
|
TRACK_WIDGET_CREATION=true
|
||||||
|
TREE_SHAKE_ICONS=false
|
||||||
|
PACKAGE_CONFIG=.dart_tool/package_config.json
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# This is a generated file; do not edit or check into version control.
|
||||||
|
export "FLUTTER_ROOT=C:\Users\poka\dev\flutter"
|
||||||
|
export "FLUTTER_APPLICATION_PATH=C:\Users\poka\dev\fipy"
|
||||||
|
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||||
|
export "FLUTTER_BUILD_DIR=build"
|
||||||
|
export "FLUTTER_BUILD_NAME=0.0.2"
|
||||||
|
export "FLUTTER_BUILD_NUMBER=2"
|
||||||
|
export "DART_OBFUSCATION=false"
|
||||||
|
export "TRACK_WIDGET_CREATION=true"
|
||||||
|
export "TREE_SHAKE_ICONS=false"
|
||||||
|
export "PACKAGE_CONFIG=.dart_tool/package_config.json"
|
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"filename": "app_icon_16.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "1x",
|
||||||
|
"size": "16x16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_32.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "2x",
|
||||||
|
"size": "16x16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_32.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "1x",
|
||||||
|
"size": "32x32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_64.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "2x",
|
||||||
|
"size": "32x32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_128.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "1x",
|
||||||
|
"size": "128x128"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_256.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "2x",
|
||||||
|
"size": "128x128"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_256.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "1x",
|
||||||
|
"size": "256x256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_512.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "2x",
|
||||||
|
"size": "256x256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_512.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "1x",
|
||||||
|
"size": "512x512"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "app_icon_1024.png",
|
||||||
|
"idiom": "mac",
|
||||||
|
"scale": "2x",
|
||||||
|
"size": "512x512"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"author": "icons_launcher",
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 137 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 871 B |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 2.1 KiB |
14
make_exe.iss
|
@ -5,7 +5,7 @@
|
||||||
#define MyAppVersion "0.1"
|
#define MyAppVersion "0.1"
|
||||||
#define MyAppPublisher "p2p.legal"
|
#define MyAppPublisher "p2p.legal"
|
||||||
#define MyAppURL "https://p2p.legal"
|
#define MyAppURL "https://p2p.legal"
|
||||||
#define MyAppExeName "fip_parser_ui.exe"
|
#define MyAppExeName "fipy.exe"
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||||
|
@ -35,14 +35,10 @@ Name: "french"; MessagesFile: "compiler:Languages\French.isl"
|
||||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "C:\Users\poka\dev\fipy\build\windows\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\dart_vlc_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "C:\Users\poka\dev\fipy\build\windows\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "C:\Users\poka\dev\fipy\build\windows\runner\Release\audioplayers_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\libvlc.dll"; DestDir: "{app}"; Flags: ignoreversion
|
Source: "C:\Users\poka\dev\fipy\build\windows\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\libvlccore.dll"; DestDir: "{app}"; Flags: ignoreversion
|
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion
|
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs
|
|
||||||
Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\plugins\*"; DestDir: "{app}\plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
|
|
||||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
|
||||||
[Icons]
|
[Icons]
|
||||||
|
|
512
pubspec.lock
|
@ -5,147 +5,183 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: archive
|
name: archive
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.0"
|
version: "3.3.7"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.4.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.8.2"
|
version: "2.10.0"
|
||||||
audio_session:
|
audioplayers:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: audioplayers
|
||||||
|
sha256: "6063c05f987596ba7a3dad9bb9a5d8adfa5e7c07b9bae5301b27c11d0b3a239f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.1"
|
||||||
|
audioplayers_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: audio_session
|
name: audioplayers_android
|
||||||
url: "https://pub.dartlang.org"
|
sha256: fb6bca878ad175d8f6ddc0e0a2d4226d81fa7c10747c12db420e96c7a096b2cc
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.6+1"
|
version: "3.0.1"
|
||||||
audio_video_progress_bar:
|
audioplayers_darwin:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: audio_video_progress_bar
|
name: audioplayers_darwin
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c4a56c49347b2e85ac4e1efea218948ca0fba87f04d2a3d3de07ce2410037038
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.0"
|
version: "4.0.1"
|
||||||
|
audioplayers_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_linux
|
||||||
|
sha256: "897e24f190232a3fbb88134b062aa83a9240f55789b5e8d17c114283284ef56b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
|
audioplayers_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_platform_interface
|
||||||
|
sha256: "3a90a46198d375fc7d47bc1d3070c8fd8863b6469b7d87ca80f953efb090f976"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.0"
|
||||||
|
audioplayers_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_web
|
||||||
|
sha256: "4f5dcbfec0bf98ea09e243d5f5b64ea43a4e6710a2f292724bed16cdba3c691e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
|
audioplayers_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: audioplayers_windows
|
||||||
|
sha256: "010f575653c01ccbe9756050b18df83d89426740e04b684f6438aa26c775a965"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.dartlang.org"
|
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.1"
|
||||||
charcode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: charcode
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.3.1"
|
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.dartlang.org"
|
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.16.0"
|
version: "1.17.0"
|
||||||
|
convert:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: convert
|
||||||
|
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.1"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
url: "https://pub.dartlang.org"
|
sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.2"
|
||||||
csslib:
|
csslib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: csslib
|
name: csslib
|
||||||
url: "https://pub.dartlang.org"
|
sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.17.1"
|
version: "0.17.2"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
url: "https://pub.dartlang.org"
|
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.5"
|
||||||
dart_vlc:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dart_vlc
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.9"
|
|
||||||
dart_vlc_ffi:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dart_vlc_ffi
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.5+1"
|
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.1"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "2.0.1"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.2"
|
version: "6.1.4"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
flutter_launcher_icons_maker:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: flutter_launcher_icons_maker
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.10.2"
|
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: flutter_lints
|
name: flutter_lints
|
||||||
url: "https://pub.dartlang.org"
|
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.1"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -160,128 +196,106 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: freezed_annotation
|
name: freezed_annotation
|
||||||
url: "https://pub.dartlang.org"
|
sha256: aeac15850ef1b38ee368d4c53ba9a847e900bb2c53a4db3f6881cbb3cb684338
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "2.2.0"
|
||||||
html:
|
html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: html
|
name: html
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "79d498e6d6761925a34ee5ea8fa6dfef38607781d2fa91e37523474282af55cb"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.0"
|
version: "0.15.2"
|
||||||
http:
|
http:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.4"
|
version: "0.13.5"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.2"
|
||||||
|
icons_launcher:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: icons_launcher
|
||||||
|
sha256: f8ccfb80b56856b6eac586980bdd9c14f5ec24fb87127514055445ceb9424f4c
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: image
|
name: image
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "483a389d6ccb292b570c31b3a193779b1b0178e7eb571986d9a49904b6861227"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "4.0.15"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.4"
|
version: "0.6.5"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.0"
|
version: "4.8.0"
|
||||||
just_audio:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: just_audio
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.9.20"
|
|
||||||
just_audio_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: just_audio_platform_interface
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "4.1.0"
|
|
||||||
just_audio_web:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: just_audio_web
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.7"
|
|
||||||
kplayer:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: kplayer
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.12"
|
|
||||||
kplayer_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: kplayer_platform_interface
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.0.7"
|
|
||||||
kplayer_with_dart_vlc:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: kplayer_with_dart_vlc
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.0.8"
|
|
||||||
kplayer_with_just_audio:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: kplayer_with_just_audio
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.0.8"
|
|
||||||
lints:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: lints
|
name: lints
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "2.0.1"
|
||||||
|
logger:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: logger
|
||||||
|
sha256: db2ff852ed77090ba9f62d3611e4208a3d11dfa35991a81ae724c113fcb3e3f7
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.11"
|
version: "0.12.13"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
url: "https://pub.dartlang.org"
|
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.4"
|
version: "0.2.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
version: "1.8.0"
|
||||||
miniplayer:
|
miniplayer:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -295,107 +309,114 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: nested
|
name: nested
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.dartlang.org"
|
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.8.2"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c7edf82217d4b2952b2129a61d3ad60f1075b9299e629e149a8d2e39c2e6aad4
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.9"
|
version: "2.0.14"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
url: "https://pub.dartlang.org"
|
sha256: da97262be945a72270513700a92b39dd2f4a54dad55d061687e2e37a6390366a
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.13"
|
version: "2.0.25"
|
||||||
path_provider_ios:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_ios
|
name: path_provider_foundation
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ad4c4d011830462633f03eb34445a45345673dfd4faf1ab0b4735fbd93b19183
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.8"
|
version: "2.2.2"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.10"
|
||||||
path_provider_macos:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_provider_macos
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.5"
|
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.6"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
url: "https://pub.dartlang.org"
|
sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.1.5"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: petitparser
|
name: petitparser
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.4.0"
|
version: "5.1.0"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.4"
|
||||||
|
pointycastle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pointycastle
|
||||||
|
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.7.3"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: process
|
name: process
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.4"
|
version: "4.2.4"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: provider
|
name: provider
|
||||||
url: "https://pub.dartlang.org"
|
sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.2"
|
version: "6.0.5"
|
||||||
rxdart:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: rxdart
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.27.3"
|
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -405,163 +426,130 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.2"
|
version: "1.9.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.11.0"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.2.0"
|
||||||
|
synchronized:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: synchronized
|
||||||
|
sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.1"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.9"
|
version: "0.4.16"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.1"
|
||||||
universal_io:
|
universal_io:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: universal_io
|
name: universal_io
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "06866290206d196064fd61df4c7aea1ffe9a4e7c4ccaa8fcded42dd41948005d"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.4"
|
version: "2.2.0"
|
||||||
url_launcher:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: url_launcher
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.1.0"
|
|
||||||
url_launcher_android:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: url_launcher_android
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.0.16"
|
|
||||||
url_launcher_ios:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: url_launcher_ios
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "6.0.15"
|
|
||||||
url_launcher_linux:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: url_launcher_linux
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
url_launcher_macos:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: url_launcher_macos
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
url_launcher_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: url_launcher_platform_interface
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.5"
|
|
||||||
url_launcher_web:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: url_launcher_web
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.9"
|
|
||||||
url_launcher_windows:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: url_launcher_windows
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
uuid:
|
uuid:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.7"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.4"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.dartlang.org"
|
sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.2"
|
version: "3.1.4"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
url: "https://pub.dartlang.org"
|
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0+1"
|
version: "1.0.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.3.1"
|
version: "6.2.2"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.1"
|
||||||
youtube_explode_dart:
|
youtube_explode_dart:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: youtube_explode_dart
|
name: youtube_explode_dart
|
||||||
url: "https://pub.dartlang.org"
|
sha256: "07889a6229a63e78f8d45a3b852897c2e0fa42e96c4daa38d411be211575bc38"
|
||||||
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.12.4"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.17.0-0 <3.0.0"
|
dart: ">=2.18.0 <3.0.0"
|
||||||
flutter: ">=2.10.0"
|
flutter: ">=3.3.0"
|
||||||
|
|
51
pubspec.yaml
|
@ -1,8 +1,8 @@
|
||||||
name: fip_parser_ui
|
name: fipy
|
||||||
description: Advanced FIP radio track explorer
|
description: Advanced FIP radio track explorer
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
version: 0.0.1+1
|
version: 0.0.3+2
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.16.2 <3.0.0"
|
sdk: ">=2.16.2 <3.0.0"
|
||||||
|
@ -15,9 +15,9 @@ dependencies:
|
||||||
# git:
|
# git:
|
||||||
# url: https://git.p2p.legal/poka/youtube_explode.git
|
# url: https://git.p2p.legal/poka/youtube_explode.git
|
||||||
# ref: master
|
# ref: master
|
||||||
url_launcher: ^6.1.0
|
|
||||||
http: ^0.13.4
|
http: ^0.13.4
|
||||||
kplayer: ^0.1.12
|
# kplayer: ^0.1.18
|
||||||
|
# kplayer_with_audioplayers: ^0.0.10
|
||||||
miniplayer: #^1.0.1
|
miniplayer: #^1.0.1
|
||||||
git:
|
git:
|
||||||
url: https://git.p2p.legal/poka/flutter_miniplayer.git
|
url: https://git.p2p.legal/poka/flutter_miniplayer.git
|
||||||
|
@ -25,27 +25,48 @@ dependencies:
|
||||||
provider: ^6.0.1
|
provider: ^6.0.1
|
||||||
path_provider: ^2.0.9
|
path_provider: ^2.0.9
|
||||||
universal_io: ^2.0.4
|
universal_io: ^2.0.4
|
||||||
|
# ffmpeg_cli: ^0.1.0
|
||||||
|
audioplayers: ^4.0.1
|
||||||
|
logger: ^1.3.0
|
||||||
|
# git:
|
||||||
|
# url: https://github.com/bluefireteam/audioplayers/tree/main/packages/audioplayers_linux
|
||||||
|
# ref: main
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_lints: ^1.0.0
|
flutter_lints: ^2.0.1
|
||||||
flutter_launcher_icons_maker: ^0.10.2
|
icons_launcher: ^2.0.6
|
||||||
|
|
||||||
flutter_icons:
|
icons_launcher:
|
||||||
android: "launcher_icon"
|
image_path: 'assets/logo_green_dark.jpg'
|
||||||
ios: true
|
platforms:
|
||||||
macos: true
|
android:
|
||||||
windows: true
|
enable: true
|
||||||
web: true
|
ios:
|
||||||
image_path: "assets/logo.jpg"
|
enable: true
|
||||||
|
windows:
|
||||||
|
enable: true
|
||||||
|
linux:
|
||||||
|
enable: true
|
||||||
|
macos:
|
||||||
|
enable: true
|
||||||
|
|
||||||
|
# flutter_icons:
|
||||||
|
# android: true
|
||||||
|
# ios: true
|
||||||
|
# # macos: true
|
||||||
|
# windows: true
|
||||||
|
# web: true
|
||||||
|
# image_path: "assets/logo_green_dark.jpg"
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
# assets:
|
||||||
- assets/logo.jpg
|
# - assets/test.webm
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Flutter Linux App
|
||||||
|
Comment=Flutter Linux launcher icon
|
||||||
|
Exec=app_icon
|
||||||
|
Icon=app_icon.png
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Entertainment;
|
After Width: | Height: | Size: 18 KiB |
|
@ -8,7 +8,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import 'package:fip_parser_ui/main.dart';
|
import 'package:fipy/main.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||||
|
|
BIN
web/favicon.png
Before Width: | Height: | Size: 394 B After Width: | Height: | Size: 396 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 50 KiB |
|
@ -23,13 +23,13 @@
|
||||||
<!-- iOS meta tags & icons -->
|
<!-- iOS meta tags & icons -->
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
<meta name="apple-mobile-web-app-title" content="fip_parser_ui">
|
<meta name="apple-mobile-web-app-title" content="fipy">
|
||||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||||
|
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
<title>fip_parser_ui</title>
|
<title>fipy</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "fip_parser_ui",
|
"name": "fipy",
|
||||||
"short_name": "fip_parser_ui",
|
"short_name": "fipy",
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#0175C2",
|
"background_color": "#0175C2",
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
|
# Project-level configuration.
|
||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
project(fip_parser_ui LANGUAGES CXX)
|
project(fipy LANGUAGES CXX)
|
||||||
|
|
||||||
set(BINARY_NAME "fip_parser_ui")
|
# The name of the executable created for the application. Change this to change
|
||||||
|
# the on-disk name of your application.
|
||||||
|
set(BINARY_NAME "fipy")
|
||||||
|
|
||||||
|
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||||
|
# versions of CMake.
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
|
||||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
|
# Define build configuration option.
|
||||||
|
|
||||||
# Configure build options.
|
|
||||||
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
if(IS_MULTICONFIG)
|
if(IS_MULTICONFIG)
|
||||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
|
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
|
||||||
|
@ -20,7 +23,7 @@ else()
|
||||||
"Debug" "Profile" "Release")
|
"Debug" "Profile" "Release")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
# Define settings for the Profile build mode.
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
|
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
|
||||||
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
|
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
|
||||||
|
@ -30,6 +33,10 @@ set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
add_definitions(-DUNICODE -D_UNICODE)
|
add_definitions(-DUNICODE -D_UNICODE)
|
||||||
|
|
||||||
# Compilation settings that should be applied to most targets.
|
# Compilation settings that should be applied to most targets.
|
||||||
|
#
|
||||||
|
# Be cautious about adding new options here, as plugins use this function by
|
||||||
|
# default. In most cases, you should add new options to specific targets instead
|
||||||
|
# of modifying this function.
|
||||||
function(APPLY_STANDARD_SETTINGS TARGET)
|
function(APPLY_STANDARD_SETTINGS TARGET)
|
||||||
target_compile_features(${TARGET} PUBLIC cxx_std_17)
|
target_compile_features(${TARGET} PUBLIC cxx_std_17)
|
||||||
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
|
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
|
||||||
|
@ -38,12 +45,11 @@ function(APPLY_STANDARD_SETTINGS TARGET)
|
||||||
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
|
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
|
|
||||||
|
|
||||||
# Flutter library and tool build rules.
|
# Flutter library and tool build rules.
|
||||||
|
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
|
||||||
add_subdirectory(${FLUTTER_MANAGED_DIR})
|
add_subdirectory(${FLUTTER_MANAGED_DIR})
|
||||||
|
|
||||||
# Application build
|
# Application build; see runner/CMakeLists.txt.
|
||||||
add_subdirectory("runner")
|
add_subdirectory("runner")
|
||||||
|
|
||||||
# Generated plugin build rules, which manage building the plugins and adding
|
# Generated plugin build rules, which manage building the plugins and adding
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# This file controls Flutter-level build steps. It should not be edited.
|
||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
||||||
|
|
|
@ -6,12 +6,9 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <dart_vlc/dart_vlc_plugin.h>
|
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
DartVlcPluginRegisterWithRegistrar(
|
AudioplayersWindowsPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("DartVlcPlugin"));
|
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
|
||||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
dart_vlc
|
audioplayers_windows
|
||||||
url_launcher_windows
|
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
project(runner LANGUAGES CXX)
|
project(runner LANGUAGES CXX)
|
||||||
|
|
||||||
|
# Define the application target. To change its name, change BINARY_NAME in the
|
||||||
|
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
|
||||||
|
# work.
|
||||||
|
#
|
||||||
|
# Any new source files that you add to the application should be added here.
|
||||||
add_executable(${BINARY_NAME} WIN32
|
add_executable(${BINARY_NAME} WIN32
|
||||||
"flutter_window.cpp"
|
"flutter_window.cpp"
|
||||||
"main.cpp"
|
"main.cpp"
|
||||||
|
@ -10,8 +15,26 @@ add_executable(${BINARY_NAME} WIN32
|
||||||
"Runner.rc"
|
"Runner.rc"
|
||||||
"runner.exe.manifest"
|
"runner.exe.manifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Apply the standard set of build settings. This can be removed for applications
|
||||||
|
# that need different build settings.
|
||||||
apply_standard_settings(${BINARY_NAME})
|
apply_standard_settings(${BINARY_NAME})
|
||||||
|
|
||||||
|
# Add preprocessor definitions for the build version.
|
||||||
|
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
|
||||||
|
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
|
||||||
|
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
|
||||||
|
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
|
||||||
|
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
|
||||||
|
|
||||||
|
# Disable Windows macros that collide with C++ standard library functions.
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
|
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
|
||||||
|
|
||||||
|
# Add dependency libraries and include directories. Add any application-specific
|
||||||
|
# dependencies here.
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
|
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
|
||||||
|
target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
|
||||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
||||||
|
|
||||||
|
# Run the Flutter tool portions of the build. This must not be removed.
|
||||||
add_dependencies(${BINARY_NAME} flutter_assemble)
|
add_dependencies(${BINARY_NAME} flutter_assemble)
|
||||||
|
|
|
@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico"
|
||||||
// Version
|
// Version
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifdef FLUTTER_BUILD_NUMBER
|
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
|
||||||
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
|
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
|
||||||
#else
|
#else
|
||||||
#define VERSION_AS_NUMBER 1,0,0
|
#define VERSION_AS_NUMBER 1,0,0,0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FLUTTER_BUILD_NAME
|
#if defined(FLUTTER_VERSION)
|
||||||
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
|
#define VERSION_AS_STRING FLUTTER_VERSION
|
||||||
#else
|
#else
|
||||||
#define VERSION_AS_STRING "1.0.0"
|
#define VERSION_AS_STRING "1.0.0"
|
||||||
#endif
|
#endif
|
||||||
|
@ -89,13 +89,13 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "040904e4"
|
BLOCK "040904e4"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "com.example" "\0"
|
VALUE "CompanyName", "fipy.p2p" "\0"
|
||||||
VALUE "FileDescription", "fip_parser_ui" "\0"
|
VALUE "FileDescription", "fipy" "\0"
|
||||||
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
||||||
VALUE "InternalName", "fip_parser_ui" "\0"
|
VALUE "InternalName", "fipy" "\0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0"
|
VALUE "LegalCopyright", "Copyright (C) 2023 fipy.p2p. All rights reserved." "\0"
|
||||||
VALUE "OriginalFilename", "fip_parser_ui.exe" "\0"
|
VALUE "OriginalFilename", "fipy.exe" "\0"
|
||||||
VALUE "ProductName", "fip_parser_ui" "\0"
|
VALUE "ProductName", "fipy" "\0"
|
||||||
VALUE "ProductVersion", VERSION_AS_STRING "\0"
|
VALUE "ProductVersion", VERSION_AS_STRING "\0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -26,6 +26,11 @@ bool FlutterWindow::OnCreate() {
|
||||||
}
|
}
|
||||||
RegisterPlugins(flutter_controller_->engine());
|
RegisterPlugins(flutter_controller_->engine());
|
||||||
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
||||||
|
|
||||||
|
flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
||||||
|
this->Show();
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||||
FlutterWindow window(project);
|
FlutterWindow window(project);
|
||||||
Win32Window::Point origin(10, 10);
|
Win32Window::Point origin(10, 10);
|
||||||
Win32Window::Size size(1280, 720);
|
Win32Window::Size size(1280, 720);
|
||||||
if (!window.CreateAndShow(L"fip_parser_ui", origin, size)) {
|
if (!window.Create(L"fipy", origin, size)) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
window.SetQuitOnClose(true);
|
window.SetQuitOnClose(true);
|
||||||
|
|
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 825 B |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 2.0 KiB |
|
@ -7,7 +7,7 @@
|
||||||
</application>
|
</application>
|
||||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
<application>
|
<application>
|
||||||
<!-- Windows 10 -->
|
<!-- Windows 10 and Windows 11 -->
|
||||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||||
<!-- Windows 8.1 -->
|
<!-- Windows 8.1 -->
|
||||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||||
|
|
|
@ -48,10 +48,10 @@ std::string Utf8FromUtf16(const wchar_t* utf16_string) {
|
||||||
int target_length = ::WideCharToMultiByte(
|
int target_length = ::WideCharToMultiByte(
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
||||||
-1, nullptr, 0, nullptr, nullptr);
|
-1, nullptr, 0, nullptr, nullptr);
|
||||||
if (target_length == 0) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
std::string utf8_string;
|
std::string utf8_string;
|
||||||
|
if (target_length == 0 || target_length > utf8_string.max_size()) {
|
||||||
|
return utf8_string;
|
||||||
|
}
|
||||||
utf8_string.resize(target_length);
|
utf8_string.resize(target_length);
|
||||||
int converted_length = ::WideCharToMultiByte(
|
int converted_length = ::WideCharToMultiByte(
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
||||||
|
|
|
@ -1,13 +1,31 @@
|
||||||
#include "win32_window.h"
|
#include "win32_window.h"
|
||||||
|
|
||||||
|
#include <dwmapi.h>
|
||||||
#include <flutter_windows.h>
|
#include <flutter_windows.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
/// Window attribute that enables dark mode window decorations.
|
||||||
|
///
|
||||||
|
/// Redefined in case the developer's machine has a Windows SDK older than
|
||||||
|
/// version 10.0.22000.0.
|
||||||
|
/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
||||||
|
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||||
|
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||||
|
#endif
|
||||||
|
|
||||||
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
|
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
|
||||||
|
|
||||||
|
/// Registry key for app theme preference.
|
||||||
|
///
|
||||||
|
/// A value of 0 indicates apps should use dark mode. A non-zero or missing
|
||||||
|
/// value indicates apps should use light mode.
|
||||||
|
constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
|
||||||
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
||||||
|
constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
|
||||||
|
|
||||||
// The number of Win32Window objects that currently exist.
|
// The number of Win32Window objects that currently exist.
|
||||||
static int g_active_window_count = 0;
|
static int g_active_window_count = 0;
|
||||||
|
|
||||||
|
@ -31,8 +49,8 @@ void EnableFullDpiSupportIfAvailable(HWND hwnd) {
|
||||||
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
|
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
|
||||||
if (enable_non_client_dpi_scaling != nullptr) {
|
if (enable_non_client_dpi_scaling != nullptr) {
|
||||||
enable_non_client_dpi_scaling(hwnd);
|
enable_non_client_dpi_scaling(hwnd);
|
||||||
FreeLibrary(user32_module);
|
|
||||||
}
|
}
|
||||||
|
FreeLibrary(user32_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -102,7 +120,7 @@ Win32Window::~Win32Window() {
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Win32Window::CreateAndShow(const std::wstring& title,
|
bool Win32Window::Create(const std::wstring& title,
|
||||||
const Point& origin,
|
const Point& origin,
|
||||||
const Size& size) {
|
const Size& size) {
|
||||||
Destroy();
|
Destroy();
|
||||||
|
@ -117,7 +135,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
|
||||||
double scale_factor = dpi / 96.0;
|
double scale_factor = dpi / 96.0;
|
||||||
|
|
||||||
HWND window = CreateWindow(
|
HWND window = CreateWindow(
|
||||||
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
|
||||||
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
|
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
|
||||||
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
|
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
|
||||||
nullptr, nullptr, GetModuleHandle(nullptr), this);
|
nullptr, nullptr, GetModuleHandle(nullptr), this);
|
||||||
|
@ -126,9 +144,15 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateTheme(window);
|
||||||
|
|
||||||
return OnCreate();
|
return OnCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Win32Window::Show() {
|
||||||
|
return ShowWindow(window_handle_, SW_SHOWNORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
|
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
|
||||||
UINT const message,
|
UINT const message,
|
||||||
|
@ -188,6 +212,10 @@ Win32Window::MessageHandler(HWND hwnd,
|
||||||
SetFocus(child_content_);
|
SetFocus(child_content_);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case WM_DWMCOLORIZATIONCOLORCHANGED:
|
||||||
|
UpdateTheme(hwnd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProc(window_handle_, message, wparam, lparam);
|
return DefWindowProc(window_handle_, message, wparam, lparam);
|
||||||
|
@ -243,3 +271,18 @@ bool Win32Window::OnCreate() {
|
||||||
void Win32Window::OnDestroy() {
|
void Win32Window::OnDestroy() {
|
||||||
// No-op; provided for subclasses.
|
// No-op; provided for subclasses.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Win32Window::UpdateTheme(HWND const window) {
|
||||||
|
DWORD light_mode;
|
||||||
|
DWORD light_mode_size = sizeof(light_mode);
|
||||||
|
LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
|
||||||
|
kGetPreferredBrightnessRegValue,
|
||||||
|
RRF_RT_REG_DWORD, nullptr, &light_mode,
|
||||||
|
&light_mode_size);
|
||||||
|
|
||||||
|
if (result == ERROR_SUCCESS) {
|
||||||
|
BOOL enable_dark_mode = light_mode == 0;
|
||||||
|
DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
|
||||||
|
&enable_dark_mode, sizeof(enable_dark_mode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -28,15 +28,16 @@ class Win32Window {
|
||||||
Win32Window();
|
Win32Window();
|
||||||
virtual ~Win32Window();
|
virtual ~Win32Window();
|
||||||
|
|
||||||
// Creates and shows a win32 window with |title| and position and size using
|
// Creates a win32 window with |title| that is positioned and sized using
|
||||||
// |origin| and |size|. New windows are created on the default monitor. Window
|
// |origin| and |size|. New windows are created on the default monitor. Window
|
||||||
// sizes are specified to the OS in physical pixels, hence to ensure a
|
// sizes are specified to the OS in physical pixels, hence to ensure a
|
||||||
// consistent size to will treat the width height passed in to this function
|
// consistent size this function will scale the inputted width and height as
|
||||||
// as logical pixels and scale to appropriate for the default monitor. Returns
|
// as appropriate for the default monitor. The window is invisible until
|
||||||
// true if the window was created successfully.
|
// |Show| is called. Returns true if the window was created successfully.
|
||||||
bool CreateAndShow(const std::wstring& title,
|
bool Create(const std::wstring& title, const Point& origin, const Size& size);
|
||||||
const Point& origin,
|
|
||||||
const Size& size);
|
// Show the current window. Returns true if the window was successfully shown.
|
||||||
|
bool Show();
|
||||||
|
|
||||||
// Release OS resources associated with window.
|
// Release OS resources associated with window.
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
@ -86,6 +87,9 @@ class Win32Window {
|
||||||
// Retrieves a class instance pointer for |window|
|
// Retrieves a class instance pointer for |window|
|
||||||
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
|
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
|
||||||
|
|
||||||
|
// Update the window frame's theme to match the system theme.
|
||||||
|
static void UpdateTheme(HWND const window);
|
||||||
|
|
||||||
bool quit_on_close_ = false;
|
bool quit_on_close_ = false;
|
||||||
|
|
||||||
// window handle for top level window.
|
// window handle for top level window.
|
||||||
|
|