Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
955b691ed6
|
|||
|
fb03d06b0a
|
|||
|
d2173319b2
|
|||
|
f232324f11
|
|||
|
426c6b7567
|
|||
|
7e6aaf40c4
|
|||
|
bc30c9586e
|
|||
|
36e13ecb50
|
|||
|
d08ce9172f
|
|||
|
2cfddc0fe9
|
|||
|
c2c919b55e
|
|||
|
c3717042a1
|
|||
|
04873f1240
|
|||
|
137f31c104
|
|||
|
0a9b0f7547
|
|||
|
1a6ca9fa73
|
|||
|
4fc2c4bfa6
|
|||
|
9070b70145
|
|||
|
1cfba71655
|
|||
|
a384c05a63
|
|||
|
e24740899c
|
|||
|
b953e2d110
|
|||
|
6f9429c77f
|
|||
|
e4b9c33044
|
|||
|
c94cec66ce
|
|||
|
ddedfdab50
|
12
.github/workflows/linux-web.yaml
vendored
@@ -37,7 +37,7 @@ jobs:
|
|||||||
run: flutter build linux
|
run: flutter build linux
|
||||||
|
|
||||||
- name: Build for Android
|
- name: Build for Android
|
||||||
run: flutter build appbundle
|
run: flutter build appbundle --debug
|
||||||
|
|
||||||
- name: Build for web
|
- name: Build for web
|
||||||
run: flutter build web --no-web-resources-cdn --csp --web-renderer canvaskit
|
run: flutter build web --no-web-resources-cdn --csp --web-renderer canvaskit
|
||||||
@@ -62,3 +62,13 @@ jobs:
|
|||||||
name: flutter-web-build-latest
|
name: flutter-web-build-latest
|
||||||
path: build/web
|
path: build/web
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Publish to Cloudflare Pages
|
||||||
|
uses: cloudflare/pages-action@v1
|
||||||
|
with:
|
||||||
|
apiToken: ${{ secrets.CLOUDFLARE_PAGES_DEPLOY }}
|
||||||
|
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
projectName: ything-radio
|
||||||
|
directory: build/web
|
||||||
|
# push directly to "production" on cloudflare pages
|
||||||
|
branch: main
|
||||||
|
|||||||
5
.github/workflows/windows.yaml
vendored
@@ -37,3 +37,8 @@ jobs:
|
|||||||
name: flutter-windows-build-latest
|
name: flutter-windows-build-latest
|
||||||
path: build/windows/x64/runner
|
path: build/windows/x64/runner
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
#- name: Build MSIX for Windows
|
||||||
|
# run: dart run msix:create
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ or to facilitate user input for internet radio sites.
|
|||||||
|
|
||||||
This app has been designed to run across all platforms!
|
This app has been designed to run across all platforms!
|
||||||
|
|
||||||
- Android
|
- Android ([Google Play Store](https://play.google.com/store/apps/details?id=net.ything.radio.android))
|
||||||
- iOS
|
- iOS (Requires [TestFlight](https://itunes.apple.com/us/app/testflight/id899247664?mt=8), contact info@ything.app for invitation)
|
||||||
- MacOS
|
- MacOS
|
||||||
- Windows
|
- Windows
|
||||||
- Linux
|
- Linux
|
||||||
- Web
|
- Web ([Live Demo](https://radio-demo.ything.app/))
|
||||||
|
|
||||||
Provide a single unified experience across *all* platforms for your users!
|
Provide a single unified experience across *all* platforms for your users!
|
||||||
|
|
||||||
@@ -25,7 +25,5 @@ Want to have us modify this app for you? Reach out to info@ything.app
|
|||||||
Coming Soon:
|
Coming Soon:
|
||||||
|
|
||||||
- Apple App Store Live Demo!
|
- Apple App Store Live Demo!
|
||||||
- Google Play Store Live Demo!
|
|
||||||
- Windows portable exe
|
- Windows portable exe
|
||||||
- Web based live demo
|
|
||||||
- Screenshots / Demo Videos
|
- Screenshots / Demo Videos
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ plugins {
|
|||||||
id "dev.flutter.flutter-gradle-plugin"
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "net.ything.radio.android"
|
namespace = "net.ything.radio.android"
|
||||||
//compileSdk = flutter.compileSdkVersion
|
//compileSdk = flutter.compileSdkVersion
|
||||||
@@ -25,17 +31,27 @@ android {
|
|||||||
applicationId = "net.ything.radio.android"
|
applicationId = "net.ything.radio.android"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
minSdk = flutter.minSdkVersion
|
minSdk = 24
|
||||||
targetSdk = flutter.targetSdkVersion
|
targetSdk = 34
|
||||||
versionCode = flutter.versionCode
|
versionCode = 2
|
||||||
versionName = flutter.versionName
|
versionName = "1.0.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
keyAlias = keystoreProperties['keyAlias']
|
||||||
|
keyPassword = keystoreProperties['keyPassword']
|
||||||
|
storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||||
|
storePassword = keystoreProperties['storePassword']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
// TODO: Add your own signing config for the release build.
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
signingConfig = signingConfigs.debug
|
signingConfig = signingConfigs.release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 4.1 KiB |
4
android/key.properties.dist
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
storePassword=
|
||||||
|
keyPassword=
|
||||||
|
keyAlias=
|
||||||
|
storeFile=
|
||||||
4
android/readme-signing.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
https://docs.flutter.dev/deployment/android#signing-the-app
|
||||||
|
|
||||||
|
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
|
||||||
BIN
assets/appicon/feature_radio.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
assets/appicon/feature_radio.xcf
Normal file
BIN
assets/appicon/icon.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
assets/appicon/radio.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
1
assets/appicon/radio.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-radio"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14 3l-9.371 3.749a1 1 0 0 0 -.629 .928v11.323a1 1 0 0 0 1 1h14a1 1 0 0 0 1 -1v-11a1 1 0 0 0 -1 -1h-14.5" /><path d="M4 12h16" /><path d="M7 12v-2" /><path d="M17 16v.01" /><path d="M13 16v.01" /></svg>
|
||||||
|
After Width: | Height: | Size: 517 B |
BIN
assets/appicon/radio.xcf
Normal file
BIN
assets/images/app-background.jpg
Normal file
|
After Width: | Height: | Size: 244 KiB |
BIN
assets/images/app-background2.jpg
Normal file
|
After Width: | Height: | Size: 243 KiB |
BIN
assets/images/app-background3.jpg
Normal file
|
After Width: | Height: | Size: 245 KiB |
19
flutter_launcher_icons.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
flutter_launcher_icons:
|
||||||
|
android: true
|
||||||
|
ios: true
|
||||||
|
remove_alpha_ios: true
|
||||||
|
image_path: "assets/appicon/icon.png"
|
||||||
|
min_sdk_android: 21
|
||||||
|
adaptive_icon_background: "#FFA86A"
|
||||||
|
web:
|
||||||
|
generate: true
|
||||||
|
image_path: "assets/appicon/icon.png"
|
||||||
|
background_color: "#FFA86A"
|
||||||
|
theme_color: "#FFA86A"
|
||||||
|
windows:
|
||||||
|
generate: true
|
||||||
|
image_path: "assets/appicon/icon.png"
|
||||||
|
icon_size: 192
|
||||||
|
macos:
|
||||||
|
generate: true
|
||||||
|
image_path: "assets/appicon/icon.png"
|
||||||
@@ -40,5 +40,12 @@ end
|
|||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(target)
|
flutter_additional_ios_build_settings(target)
|
||||||
|
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
'$(inherited)',
|
||||||
|
'AUDIO_SESSION_MICROPHONE=0'
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -49,6 +49,6 @@ SPEC CHECKSUMS:
|
|||||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||||
|
|
||||||
PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796
|
PODFILE CHECKSUM: fe2316eacdf4337bc10b81b9cf460c6f69aee374
|
||||||
|
|
||||||
COCOAPODS: 1.15.2
|
COCOAPODS: 1.15.2
|
||||||
|
|||||||
@@ -542,7 +542,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
@@ -599,7 +599,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 944 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.5 KiB |
@@ -1,40 +1,29 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:ything_radio/SafeZone.dart';
|
import 'package:ything_radio/SafeZone.dart';
|
||||||
|
|
||||||
|
import 'Globals.dart';
|
||||||
|
|
||||||
class About extends StatelessWidget {
|
class About extends StatelessWidget {
|
||||||
const About({super.key});
|
const About({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeZone(
|
return Container(
|
||||||
child: DefaultTextStyle(
|
decoration: const BoxDecoration(
|
||||||
style: Theme.of(context).textTheme.bodyLarge!,
|
image: DecorationImage(
|
||||||
child: const SingleChildScrollView(
|
image: AssetImage('assets/images/app-background2.jpg'),
|
||||||
child: Text(
|
fit: BoxFit.cover,
|
||||||
'Ything Radio is an app that is intended to provide a demonstration of the '
|
opacity: 0.2,
|
||||||
'open source ything_radio app. This app is used to provide the ability for the '
|
),
|
||||||
'"look and feel" of the app to be tested on real devices for those wishing to '
|
),
|
||||||
'either use the code as a template for themselves; or, alternatively, have Ything LLC '
|
child: SafeZone(
|
||||||
'create a custom app for them!'
|
child: DefaultTextStyle(
|
||||||
'\n\n'
|
style: Theme.of(context).textTheme.bodyLarge!,
|
||||||
'This app intentionally does not provide a method to change the streaming source '
|
child: SingleChildScrollView(
|
||||||
'as it is intended for use by internet radio stations to provide a dedicated app '
|
child: Text(
|
||||||
'for their radio station. This is not intended to be an app for generic usage for '
|
getAboutText(),
|
||||||
'multiple radio stations, a discovery platform, or to facilitate user input for '
|
textAlign: TextAlign.justify,
|
||||||
'internet radio sites.'
|
),
|
||||||
'\n\n'
|
|
||||||
'This app has been designed to run across all platforms!'
|
|
||||||
'\n\n'
|
|
||||||
'Android, iOS, MacOS, Windows, Linux, and Web!'
|
|
||||||
'\n\n'
|
|
||||||
'Have a single unified experience across all platforms for your users!'
|
|
||||||
'\n\n'
|
|
||||||
'Want to have us modify this app for you? Reach out at info@ything.net '
|
|
||||||
'We can add additional features for you! Schedule views, up next listings, '
|
|
||||||
'and even custom user interactivity! '
|
|
||||||
'\n\n'
|
|
||||||
'We look forward to hearing from you soon! We would love to build your app!',
|
|
||||||
textAlign: TextAlign.justify,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,11 +1,55 @@
|
|||||||
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
import 'package:audio_service/audio_service.dart';
|
import 'package:audio_service/audio_service.dart';
|
||||||
import 'package:audio_session/audio_session.dart';
|
import 'package:audio_session/audio_session.dart';
|
||||||
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
import 'ListenHandler.dart';
|
import 'ListenHandler.dart';
|
||||||
|
|
||||||
late final ListenHandler _listenHandler;
|
late final ListenHandler _listenHandler;
|
||||||
late final AudioSession _session;
|
late final AudioSession _session;
|
||||||
|
|
||||||
|
const String _fallback =
|
||||||
|
"https://generic.ything.app/music/separation-185196.mp3";
|
||||||
|
final _urlSource = Uri.parse("https://generic.ything.app/music/player.url");
|
||||||
|
late final String _radioUrl;
|
||||||
|
|
||||||
|
Future<void> loadCurrentUrl() async {
|
||||||
|
final resp = await http.get(_urlSource);
|
||||||
|
if (resp.statusCode == 200) {
|
||||||
|
_radioUrl = resp.body.trim();
|
||||||
|
print('Loaded remote url');
|
||||||
|
} else {
|
||||||
|
_radioUrl = _fallback;
|
||||||
|
print('Request for current streaming url failed, using fallback url');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const String _fallbackAbout =
|
||||||
|
"Ything Radio is an internet radio streaming application.";
|
||||||
|
final _urlAbout =
|
||||||
|
Uri.parse("https://generic.ything.app/ything_radio/about.txt");
|
||||||
|
|
||||||
|
final _urlAboutIOS =
|
||||||
|
Uri.parse("https://generic.ything.app/ything_radio/about_ios.txt");
|
||||||
|
|
||||||
|
late final String _remoteAbout;
|
||||||
|
|
||||||
|
Future<void> loadAboutUrl() async {
|
||||||
|
final resp = await http.get(Platform.isIOS ? _urlAboutIOS : _urlAbout);
|
||||||
|
|
||||||
|
if (resp.statusCode == 200) {
|
||||||
|
_remoteAbout = resp.body;
|
||||||
|
print('Loaded remote about');
|
||||||
|
} else {
|
||||||
|
_remoteAbout = _fallbackAbout;
|
||||||
|
print('Request for remote about failed, using fallback about');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getAboutText() => _remoteAbout;
|
||||||
|
|
||||||
Future<void> setupListenHandler() async {
|
Future<void> setupListenHandler() async {
|
||||||
_listenHandler = await AudioService.init(
|
_listenHandler = await AudioService.init(
|
||||||
builder: () => ListenHandler(),
|
builder: () => ListenHandler(),
|
||||||
@@ -17,10 +61,44 @@ Future<void> setupListenHandler() async {
|
|||||||
_session = await AudioSession.instance;
|
_session = await AudioSession.instance;
|
||||||
|
|
||||||
await _session.configure(const AudioSessionConfiguration.music());
|
await _session.configure(const AudioSessionConfiguration.music());
|
||||||
|
|
||||||
|
//TODO: Do I need to handle these events? audioplayers may be doing it already
|
||||||
|
//_session.interruptionEventStream.listen((event) {
|
||||||
|
// if (event.begin) {
|
||||||
|
// switch (event.type) {
|
||||||
|
// case AudioInterruptionType.duck:
|
||||||
|
// _listenHandler.duck();
|
||||||
|
// break;
|
||||||
|
// case AudioInterruptionType.pause:
|
||||||
|
// case AudioInterruptionType.unknown:
|
||||||
|
// _listenHandler.pause();
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// switch (event.type) {
|
||||||
|
// case AudioInterruptionType.duck:
|
||||||
|
// _listenHandler.unDuck();
|
||||||
|
// break;
|
||||||
|
// case AudioInterruptionType.pause:
|
||||||
|
// _listenHandler.play();
|
||||||
|
// break;
|
||||||
|
// case AudioInterruptionType.unknown:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//});
|
||||||
|
|
||||||
|
//_session.becomingNoisyEventStream.listen((_) {
|
||||||
|
// _listenHandler.pause();
|
||||||
|
//});
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenHandler getListenHandlder() => _listenHandler;
|
ListenHandler getListenHandlder() => _listenHandler;
|
||||||
|
|
||||||
|
UrlSource getUrlSource() {
|
||||||
|
return UrlSource(_radioUrl, mimeType: "audio/mpeg");
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> startAudioSession() async {
|
Future<bool> startAudioSession() async {
|
||||||
return await _session.setActive(true);
|
return await _session.setActive(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,21 @@ class Links extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultTextStyle(
|
return Container(
|
||||||
style: Theme.of(context).textTheme.headlineSmall!,
|
decoration: const BoxDecoration(
|
||||||
child: SafeZone(
|
image: DecorationImage(
|
||||||
child: Center(
|
image: AssetImage('assets/images/app-background3.jpg'),
|
||||||
child: Column(
|
fit: BoxFit.cover,
|
||||||
children: links.map((link) => link).toList(),
|
opacity: 0.4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: DefaultTextStyle(
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall!,
|
||||||
|
child: SafeZone(
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
children: links.map((link) => link).toList(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -9,8 +9,17 @@ class Listen extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const Center(
|
return Container(
|
||||||
child: PlayControls(),
|
decoration: const BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage('assets/images/app-background.jpg'),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
opacity: 0.4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Center(
|
||||||
|
child: PlayControls(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,9 +36,7 @@ class _PlayControlsState extends State<PlayControls>
|
|||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
bool isPlaying = false;
|
bool _isLoading = false;
|
||||||
|
|
||||||
//late final AudioPlayer player;
|
|
||||||
|
|
||||||
final ListenHandler _listenHandler = getListenHandlder();
|
final ListenHandler _listenHandler = getListenHandlder();
|
||||||
|
|
||||||
@@ -39,80 +46,62 @@ class _PlayControlsState extends State<PlayControls>
|
|||||||
|
|
||||||
print("Listen init");
|
print("Listen init");
|
||||||
|
|
||||||
_listenHandler.playbackState.listen((PlaybackState event) {
|
_listenHandler.playbackState.listen((PlaybackState state) {
|
||||||
if (isPlaying == event.playing) {
|
print("Playback state changed");
|
||||||
print("State unchanged, skipping setState()");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setState(() {
|
setState(() {
|
||||||
isPlaying = event.playing;
|
//if state changed, we're no longer loading!
|
||||||
print("Updated playing state to $isPlaying");
|
//doesn't matter if we're playing or not!
|
||||||
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//player = AudioPlayer();
|
|
||||||
|
|
||||||
//player.setReleaseMode(ReleaseMode.release);
|
|
||||||
|
|
||||||
//player
|
|
||||||
// .setSourceUrl("https://generic.ything.app/music/separation-185196.mp3");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
||||||
//player.stop();
|
|
||||||
|
|
||||||
//player.dispose();
|
|
||||||
|
|
||||||
_listenHandler.stop();
|
_listenHandler.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> playPause() async {
|
||||||
|
print("playPause called");
|
||||||
|
_listenHandler.isPlaying()
|
||||||
|
? await _listenHandler.stop()
|
||||||
|
: await _listenHandler.play();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
|
|
||||||
print("Running build - Listen");
|
print("Running build - Listen");
|
||||||
|
|
||||||
if (isPlaying) {
|
|
||||||
//player.resume();
|
|
||||||
_listenHandler.play();
|
|
||||||
_listenHandler.playbackState.add(PlaybackState(
|
|
||||||
controls: [
|
|
||||||
MediaControl.stop,
|
|
||||||
MediaControl.pause,
|
|
||||||
],
|
|
||||||
systemActions: {
|
|
||||||
MediaAction.stop,
|
|
||||||
MediaAction.pause,
|
|
||||||
},
|
|
||||||
playing: true,
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
//player.stop();
|
|
||||||
_listenHandler.stop();
|
|
||||||
_listenHandler.playbackState.add(PlaybackState(
|
|
||||||
controls: [],
|
|
||||||
systemActions: {},
|
|
||||||
playing: false,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return ClipOval(
|
return ClipOval(
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Theme.of(context).colorScheme.primaryContainer,
|
color: Theme.of(context).colorScheme.primaryContainer,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
splashColor: Theme.of(context).colorScheme.onPrimaryContainer,
|
splashColor: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
|
if (_isLoading) {
|
||||||
|
//skip doing anything else if we're still loading...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await playPause();
|
||||||
setState(() {
|
setState(() {
|
||||||
isPlaying = !isPlaying;
|
if (!_listenHandler.isPlaying()) {
|
||||||
|
_isLoading = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 100,
|
height: 100,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
isPlaying ? Icons.stop : Icons.play_arrow,
|
_isLoading
|
||||||
|
? Icons.hourglass_empty
|
||||||
|
: _listenHandler.isPlaying()
|
||||||
|
? Icons.stop
|
||||||
|
: Icons.play_arrow,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
size: 50,
|
size: 50,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,23 +5,69 @@ import 'package:ything_radio/Globals.dart';
|
|||||||
class ListenHandler extends BaseAudioHandler {
|
class ListenHandler extends BaseAudioHandler {
|
||||||
final _player = AudioPlayer();
|
final _player = AudioPlayer();
|
||||||
|
|
||||||
|
final UrlSource _radioSource = getUrlSource();
|
||||||
|
|
||||||
setup_player() {
|
setup_player() {
|
||||||
_player.setReleaseMode(ReleaseMode.release);
|
_player.setReleaseMode(ReleaseMode.release);
|
||||||
|
_player.onPlayerStateChanged.listen((event) {
|
||||||
|
print("Received audioplayers event: $event");
|
||||||
|
|
||||||
_player.setSourceUrl(
|
switch (event) {
|
||||||
"https://generic.ything.app/music/separation-185196.mp3",
|
case PlayerState.playing:
|
||||||
mimeType: "audio/mpeg",
|
super.playbackState.add(PlaybackState(
|
||||||
);
|
controls: [
|
||||||
|
MediaControl.stop,
|
||||||
|
MediaControl.pause,
|
||||||
|
],
|
||||||
|
systemActions: {
|
||||||
|
MediaAction.stop,
|
||||||
|
MediaAction.pause,
|
||||||
|
},
|
||||||
|
playing: true,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case PlayerState.paused:
|
||||||
|
case PlayerState.stopped:
|
||||||
|
case PlayerState.completed:
|
||||||
|
case PlayerState.disposed:
|
||||||
|
super.playbackState.add(PlaybackState(
|
||||||
|
controls: [],
|
||||||
|
systemActions: {},
|
||||||
|
playing: false,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenHandler() {
|
ListenHandler() {
|
||||||
setup_player();
|
setup_player();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isPlaying() => super.playbackState.value.playing;
|
||||||
|
|
||||||
|
double _duckVol = 0;
|
||||||
|
|
||||||
|
void duck() {
|
||||||
|
//TODO: Confirm I need to do this manually, it looks like audioplayers already does this
|
||||||
|
print("Duck requested");
|
||||||
|
//_duckVol = _player.volume;
|
||||||
|
|
||||||
|
//_player.setVolume(_duckVol - 0.4 > 0 ? _duckVol - 0.4 : 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unDuck() {
|
||||||
|
//TODO: Confirm I need to do this manually, it looks like audioplayers already does this
|
||||||
|
print("Unduck requested");
|
||||||
|
//_player.setVolume(_duckVol);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> play() async {
|
Future<void> play() async {
|
||||||
if (await startAudioSession()) {
|
if (await startAudioSession()) {
|
||||||
_player.resume();
|
//setSource followed by resume does not work on Android or web
|
||||||
|
//play works everywhere though
|
||||||
|
_player.play(_radioSource, mode: PlayerMode.mediaPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,4 +79,11 @@ class ListenHandler extends BaseAudioHandler {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> stop() => pause();
|
Future<void> stop() => pause();
|
||||||
|
|
||||||
|
//make appo stop playing when swiped away in task manager on Android
|
||||||
|
@override
|
||||||
|
Future<void> onTaskRemoved() async {
|
||||||
|
await stop();
|
||||||
|
return super.onTaskRemoved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class YthingRadio extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Ything Radio',
|
title: 'Ything Radio',
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
colorScheme: ColorScheme.fromSeed(
|
colorScheme: ColorScheme.fromSeed(
|
||||||
seedColor: Colors.orange,
|
seedColor: Colors.orange,
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import 'Globals.dart';
|
|||||||
import 'YthingRadio.dart';
|
import 'YthingRadio.dart';
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
|
await loadCurrentUrl();
|
||||||
|
await loadAboutUrl();
|
||||||
await setupListenHandler();
|
await setupListenHandler();
|
||||||
runApp(const YthingRadio());
|
runApp(const YthingRadio());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +1,68 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"info": {
|
||||||
{
|
"version": 1,
|
||||||
"size" : "16x16",
|
"author": "xcode"
|
||||||
"idiom" : "mac",
|
|
||||||
"filename" : "app_icon_16.png",
|
|
||||||
"scale" : "1x"
|
|
||||||
},
|
},
|
||||||
{
|
"images": [
|
||||||
"size" : "16x16",
|
{
|
||||||
"idiom" : "mac",
|
"size": "16x16",
|
||||||
"filename" : "app_icon_32.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_16.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "32x32",
|
{
|
||||||
"idiom" : "mac",
|
"size": "16x16",
|
||||||
"filename" : "app_icon_32.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_32.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "32x32",
|
{
|
||||||
"idiom" : "mac",
|
"size": "32x32",
|
||||||
"filename" : "app_icon_64.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_32.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "128x128",
|
{
|
||||||
"idiom" : "mac",
|
"size": "32x32",
|
||||||
"filename" : "app_icon_128.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_64.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "128x128",
|
{
|
||||||
"idiom" : "mac",
|
"size": "128x128",
|
||||||
"filename" : "app_icon_256.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_128.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "256x256",
|
{
|
||||||
"idiom" : "mac",
|
"size": "128x128",
|
||||||
"filename" : "app_icon_256.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_256.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "256x256",
|
{
|
||||||
"idiom" : "mac",
|
"size": "256x256",
|
||||||
"filename" : "app_icon_512.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_256.png",
|
||||||
},
|
"scale": "1x"
|
||||||
{
|
},
|
||||||
"size" : "512x512",
|
{
|
||||||
"idiom" : "mac",
|
"size": "256x256",
|
||||||
"filename" : "app_icon_512.png",
|
"idiom": "mac",
|
||||||
"scale" : "1x"
|
"filename": "app_icon_512.png",
|
||||||
},
|
"scale": "2x"
|
||||||
{
|
},
|
||||||
"size" : "512x512",
|
{
|
||||||
"idiom" : "mac",
|
"size": "512x512",
|
||||||
"filename" : "app_icon_1024.png",
|
"idiom": "mac",
|
||||||
"scale" : "2x"
|
"filename": "app_icon_512.png",
|
||||||
}
|
"scale": "1x"
|
||||||
],
|
},
|
||||||
"info" : {
|
{
|
||||||
"version" : 1,
|
"size": "512x512",
|
||||||
"author" : "xcode"
|
"idiom": "mac",
|
||||||
}
|
"filename": "app_icon_1024.png",
|
||||||
}
|
"scale": "2x"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 851 B |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |
122
pubspec.lock
@@ -1,6 +1,22 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.6.1"
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.5.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -113,6 +129,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
checked_yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: checked_yaml
|
||||||
|
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.3"
|
||||||
|
cli_util:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cli_util
|
||||||
|
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.4.1"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -129,6 +161,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.18.0"
|
version: "1.18.0"
|
||||||
|
console:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: console
|
||||||
|
sha256: e04e7824384c5b39389acdd6dc7d33f3efe6b232f6f16d7626f194f6a01ad69a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -190,6 +230,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.1"
|
version: "3.4.1"
|
||||||
|
flutter_launcher_icons:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: flutter_launcher_icons
|
||||||
|
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.13.1"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@@ -216,8 +264,16 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
http:
|
get_it:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: get_it
|
||||||
|
sha256: d85128a5dae4ea777324730dc65edd9c9f43155c109d5cc0a69cab74139fbac1
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.7.0"
|
||||||
|
http:
|
||||||
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||||
@@ -232,6 +288,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.0.2"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.0"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -240,6 +304,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.1"
|
version: "0.7.1"
|
||||||
|
json_annotation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.9.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -296,6 +368,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.15.0"
|
||||||
|
msix:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: msix
|
||||||
|
sha256: c50d6bd1aafe0d071a3c1e5a5ccb056404502935cb0a549e3178c4aae16caf33
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.16.8"
|
||||||
|
package_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_config
|
||||||
|
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -352,6 +440,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.0.2"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -368,6 +464,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
pub_semver:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pub_semver
|
||||||
|
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.4"
|
||||||
rxdart:
|
rxdart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -573,6 +677,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.5.0"
|
||||||
|
yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: yaml
|
||||||
|
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.5.1 <4.0.0"
|
dart: ">=3.5.1 <4.0.0"
|
||||||
flutter: ">=3.24.0"
|
flutter: ">=3.24.0"
|
||||||
|
|||||||
14
pubspec.yaml
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.0.0+1
|
version: 1.0.2
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.5.1
|
sdk: ^3.5.1
|
||||||
@@ -40,6 +40,7 @@ dependencies:
|
|||||||
flutter_tabler_icons: ^1.38.0
|
flutter_tabler_icons: ^1.38.0
|
||||||
audio_service: ^0.18.15
|
audio_service: ^0.18.15
|
||||||
audio_session: ^0.1.21
|
audio_session: ^0.1.21
|
||||||
|
http: ^1.2.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -51,6 +52,8 @@ dev_dependencies:
|
|||||||
# package. See that file for information about deactivating specific lint
|
# package. See that file for information about deactivating specific lint
|
||||||
# rules and activating additional ones.
|
# rules and activating additional ones.
|
||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^4.0.0
|
||||||
|
msix: ^3.16.8
|
||||||
|
flutter_launcher_icons: ^0.13.1
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
@@ -64,9 +67,12 @@ 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:
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
- assets/images/app-background.jpg
|
||||||
|
- assets/images/app-background2.jpg
|
||||||
|
- assets/images/app-background3.jpg
|
||||||
|
|
||||||
# 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/to/resolution-aware-images
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|||||||
BIN
web/favicon.png
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 851 B |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 8.8 KiB |
@@ -3,8 +3,8 @@
|
|||||||
"short_name": "Radio",
|
"short_name": "Radio",
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"background_color": "#0175C2",
|
"background_color": "#FFA86A",
|
||||||
"theme_color": "#0175C2",
|
"theme_color": "#FFA86A",
|
||||||
"description": "A simple internet streaming radio application",
|
"description": "A simple internet streaming radio application",
|
||||||
"orientation": "portrait-primary",
|
"orientation": "portrait-primary",
|
||||||
"prefer_related_applications": false,
|
"prefer_related_applications": false,
|
||||||
@@ -32,4 +32,4 @@
|
|||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 4.2 KiB |