7 Commits
mvp2 ... mvp4

53 changed files with 174 additions and 80 deletions

View File

@@ -62,3 +62,13 @@ jobs:
name: flutter-web-build-latest
path: build/web
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

View File

@@ -16,7 +16,7 @@ This app has been designed to run across all platforms!
- MacOS
- Windows
- Linux
- Web
- Web ([Live Demo](https://radio-demo.ything.app/))
Provide a single unified experience across *all* platforms for your users!
@@ -27,5 +27,4 @@ Coming Soon:
- Apple App Store Live Demo!
- Google Play Store Live Demo!
- Windows portable exe
- Web based live demo
- Screenshots / Demo Videos

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

1
assets/appicon/radio.svg Normal file
View 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

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -6,35 +6,44 @@ class About extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeZone(
child: DefaultTextStyle(
style: Theme.of(context).textTheme.bodyLarge!,
child: const SingleChildScrollView(
child: Text(
'Ything Radio is an app that is intended to provide a demonstration of the '
'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 '
'create a custom app for them!'
'\n\n'
'This app intentionally does not provide a method to change the streaming source '
'as it is intended for use by internet radio stations to provide a dedicated app '
'for their radio station. This is not intended to be an app for generic usage for '
'multiple radio stations, a discovery platform, or to facilitate user input for '
'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,
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/app-background2.jpg'),
fit: BoxFit.cover,
opacity: 0.2,
),
),
child: SafeZone(
child: DefaultTextStyle(
style: Theme.of(context).textTheme.bodyLarge!,
child: const SingleChildScrollView(
child: Text(
'Ything Radio is an app that is intended to provide a demonstration of the '
'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 '
'create a custom app for them!'
'\n\n'
'This app intentionally does not provide a method to change the streaming source '
'as it is intended for use by internet radio stations to provide a dedicated app '
'for their radio station. This is not intended to be an app for generic usage for '
'multiple radio stations, a discovery platform, or to facilitate user input for '
'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,
),
),
),
),

View File

@@ -17,6 +17,36 @@ Future<void> setupListenHandler() async {
_session = await AudioSession.instance;
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;

View File

@@ -38,12 +38,21 @@ class Links extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.headlineSmall!,
child: SafeZone(
child: Center(
child: Column(
children: links.map((link) => link).toList(),
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/app-background3.jpg'),
fit: BoxFit.cover,
opacity: 0.4,
),
),
child: DefaultTextStyle(
style: Theme.of(context).textTheme.headlineSmall!,
child: SafeZone(
child: Center(
child: Column(
children: links.map((link) => link).toList(),
),
),
),
),

View File

@@ -9,8 +9,17 @@ class Listen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const Center(
child: PlayControls(),
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/app-background.jpg'),
fit: BoxFit.cover,
opacity: 0.4,
),
),
child: const Center(
child: PlayControls(),
),
);
}
}
@@ -27,8 +36,6 @@ class _PlayControlsState extends State<PlayControls>
@override
bool get wantKeepAlive => true;
bool isPlaying = false;
final ListenHandler _listenHandler = getListenHandlder();
@override
@@ -37,15 +44,9 @@ class _PlayControlsState extends State<PlayControls>
print("Listen init");
_listenHandler.playbackState.listen((PlaybackState event) {
if (isPlaying == event.playing) {
print("State unchanged, skipping setState()");
return;
}
setState(() {
isPlaying = event.playing;
print("Updated playing state to $isPlaying");
});
_listenHandler.playbackState.listen((PlaybackState state) {
print("Playback state changed");
setState(() {});
});
}
@@ -56,48 +57,33 @@ class _PlayControlsState extends State<PlayControls>
_listenHandler.stop();
}
Future<void> playPause() async {
print("playPause called");
_listenHandler.isPlaying()
? await _listenHandler.stop()
: await _listenHandler.play();
}
@override
Widget build(BuildContext context) {
super.build(context);
print("Running build - Listen");
if (isPlaying) {
_listenHandler.play();
_listenHandler.playbackState.add(PlaybackState(
controls: [
MediaControl.stop,
MediaControl.pause,
],
systemActions: {
MediaAction.stop,
MediaAction.pause,
},
playing: true,
));
} else {
_listenHandler.stop();
_listenHandler.playbackState.add(PlaybackState(
controls: [],
systemActions: {},
playing: false,
));
}
return ClipOval(
child: Material(
color: Theme.of(context).colorScheme.primaryContainer,
child: InkWell(
splashColor: Theme.of(context).colorScheme.onPrimaryContainer,
onTap: () {
setState(() {
isPlaying = !isPlaying;
});
onTap: () async {
await playPause();
setState(() {});
},
child: SizedBox(
width: 100,
height: 100,
child: Icon(
isPlaying ? Icons.stop : Icons.play_arrow,
_listenHandler.isPlaying() ? Icons.stop : Icons.play_arrow,
color: Colors.white,
size: 50,
),

View File

@@ -11,12 +11,59 @@ class ListenHandler extends BaseAudioHandler {
setup_player() {
_player.setReleaseMode(ReleaseMode.release);
_player.onPlayerStateChanged.listen((event) {
print("Received audioplayers event: $event");
switch (event) {
case PlayerState.playing:
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() {
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
Future<void> play() async {
if (await startAudioSession()) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -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
# 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.
version: 1.0.0+1
version: 1.0.1
environment:
sdk: ^3.5.1
@@ -66,9 +66,12 @@ flutter:
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
assets:
# - images/a_dot_burr.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
# https://flutter.dev/to/resolution-aware-images

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB