Giter VIP home page Giter VIP logo

partyq-android's Introduction

partyq Android

niehusst

partyq is a music queue app that uses Spotify to play music. If one person has Spotify premium (and the Spotify app on their device) they can use partyq to host a music party for a group of people with partyq who don't have Spotify (and are nearby/connected to the same wifi). Everyone connected to the party can search for and add songs to a shared queue, while the host device plays the music using Spotify.

Note that many of the Spotify API and AppRemote endpoints that this app depends on are in beta and are subject to change without warning.

Contributing

This is an open-source project, so contributions are welcome! To see full environment setup instructions, go to the project wiki.

Acknowledgements

  • Android Architecture Components samples (for bottom nav view code with Jetpack navigation)

Authors

License

This work is dual-licensed under Apache 2.0 AND an End User License Agreement that protects Spotify's intellectual property and licensing.

The specifics can be found in LICENSE* files in the root of this project directory.

Copyright 2020 Liam Niehus-Staab

Licensed to the Apache Software Foundation (ASF) under one or more contributor 
license agreements. See the NOTICE file distributed with this work for 
additional information regarding copyright ownership. The ASF licenses this 
file to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance with the License. You may obtain a copy 
of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
License for the specific language governing permissions and limitations under 
the License.

partyq-android's People

Contributors

niehusst avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

partyq-android's Issues

reloading party: play/pause toggle incorrect

When inflating the NowPlayingFragment, the play/pause button always starts with the "playing" drawable. This is usually what we want, however, in restoring instance state after pausing the song it might be possible to see the wrong drawable for the current play state of the song (e.g. button shows song is playing, but its actually paused on Spotify).

This might be a difficult bug state to reach (can be reached by pausing song and then rotating device) and it is easily amendable by the user, so unless seen more frequently in a common user flow, it may not be worth working on.

Potentially fix idea:
In NowPlayingFragment, I could check if the current spotify song is paused and set the correct drawable from that in onCreateView(). You can player state from spotifyAppRemote, however, you can only get it from a getter-callback, so making a simple isPaused(): Boolean function for SpotifyPlayerService won't be super easy.

Make guest update service

make a background service that will regularly send queue updates to all guests (should I worry about race condition of somebody leaving the party while the service is sending updates? is it bad if Nearby tries to send a payload to a disconnected/nonexistent guest?).

This might be doable with WorkManager.

Research how frequently these updates can/should be sent. Every 1-2 seconds would be ideal from UX standpoint, but not sure if that would saturate the network, or overwork device battery/hardware.

minimize on back press

when in a party, if the back button is pressed, the app should minimize rather than finishing the PartyActivity and minimizing

survive process death

Test that the party activity can survive process death and keep the party data going

create layout+fragment for SpotifyLoginFragment

layout should specify that "Spotify Premium account is required (?), and Spotify app must be downloaded on this device"

should have 1 touch authentication thru the Spotify app-remote-apk

Create CommunicationService

Use nearby connections api to connect guests to host in P2P_STAR shape.
(needs 2 services? 1 for host, 1 for guest? or can both functionalities go in one?)

The connection code will need to be obtained and displayed at launch of PartyActivity (for showing to host for first time). This code could be stored in shared prefs?

As it will also be required to type it into the PartyJoinFragment, should be a short code (no more than 8 chars). Do some simple compression if necessary

Leaving party does not fully clean out memory

Repro:
Create a party on 1 device, and join the party on another device
On guest device click "leave party" from options menu
(The host can either fully clear the app and start a new party, or just stay in the same party; doesn't matter)
On the guest device, without clearing the app, click on Partyq launcher
Click on Join party
-> notice that after being on the correct screen for a second, it automatically navs to PartyActivity w/o entering a party code, and old party data is still present in the activity

What seems to have happened is that the connected live data in CommunicationService is still set to Status.SUCCESS, so as soon as the PartyJoinFragment loads, the observer sees that we've already successfully connected and navs (but no code was entered, so we set an empty string as the party code). And somehow the activity data persisted despite being finished.

search fragment bottom nav doesnt disappear

when the keyboard comes up while searching in the SearchFragment, the bottom nav is pushed up to be above the keyboard.
Instead, the keyboard should cover the bottom nav, like an overlay.

fix NowPlayingFragment landscape mode

When turning the NowPlayingFragment horizontal, the layout doesn't seem to be able to fit everything in so it just disappears.
(There could also be issues with the skip button width being linked to image width?)

Is it possible to specify a diff layout file for landscape??

enable proguard

enable minification and obfuscation (FOR PRODUCTION ONLY IF POSSIBLE)

make QueueFragment

just the layouts and fragment code && navigation etc.
Try to leave queue logic until the queue service ticket

convert menu option fragment to BottomSheets

Since opening up a menu option frag (e.g. AboutFragment) fills in the nav host space, the user can still swap fragments w/ bottom nav while the menu opt frag is still up, leading to weirdness w/ the backstack and potentially confusing UX.

To remedy this, each of the fragments openable via menu option should be converted into a BottomSheet so as to cover the bottom nav and eliminate the potential for confusion.

visualize explicit

Make there a visual marker for explicit tracks (at least in search if not queue and currently playing as well).

Item has a field explicit that could be utilized in SearchAdapter viewholder binding and put into databinding for search_result_item.xml.
Perhaps a little [E] icon or something? see what spotify does

Create PartyCodeFragment

Fragment should only be reachable on transition from mainActivyt to PartyActiviyt.
Should remind user that this code (and this same fragment?? idk) can be found via options menu

code should be in a read-only edittext for easier copy paste

layout should look an overlay, with an x to close the fragment rather than a misleading up-button (will probs have to be worked into PartyActivity layout for this behavior)

create PartyEndActivity

activity that acts as explainer for the end of party (i.e. inform guest that host has ended party and that's why they're here).
Should have a button saying "Party again?" or something that navs back to PartyConnectFrag

Should have diff text for if guest was disconnected by host, or if guest/host chose to disconnect themselves

implement end/leave party

host:
0. popup dialog asking if host really wants to end party for all guests

  1. stop broadcasting discovery service
  2. send disconnect message to guests (upon disconnect, guests should show dialog frag "party over" and closing frag calls leaveParty for the guest)
  3. disconnect from the guests
  4. stop the spotify playing service
  5. reset anything in saved prefs? (like anything that would bring host back to their party on reopen)
  6. finish party activity

guest:

  1. send disconnect message to host if not responding to party end (upon receiving, host removes that guestEndpointId from the list of guests)
  2. disconnect from host
  3. reset anything in saved prefs?
  4. finish party activity

fill in legal and about fragments

likely a late game ticket (for once I have all the legal acks and a clearer understanding of permissions/reqs for the app and how it works)

mostly just fill in the about and legal content in strings.xml

add start padding to SearchFragment EditText search icon

The search icon in the search bar looks a little too close to the view start, but there is no way to fix it w/ XML layout. The dirty hack that the internet seems to suggest is to get another icon with some horz padding build in.

add ripple to click surfaces

most notably the search_result_item should have ripple added to it.
perhaps some other buttons (like party_code_fragment close_button could use this too)

create PartyActivity

after SUCCESSFUL auth from Spotify (PartyStartFragment), send relevant info (e.g. any Spotify info) to the PartyActivity

layout will have:
the bottom nav
fragment container view (requires new nav graph)

create stubs for (each of these should be their own individual classes, just launched from this activity):
starting Spotify service
starting P2P_STAR connection service

create SearchFragment

build layout + recyclerview stuff as required (visualize w/ tools).
Have text that shows up when there are no items in the list.

Figure out what data spotify actually gives us? Obv we get Song title and Artist name, but do we get album photo??

make NowPlayingFragment

just make the fragment + layouts + nav etc.
Music playing logic does NOT go in this fragment, it should only be handled w/ communication between the queue service and the player service.

databind to first element of the queue in queue service

No spotify premium remediation

When user doesnt have spotify premium and trys to start a party, the PartyActivity (code for detecting non-premium users already present) must navigate to a new activity w/ info on how why they can't party (you cant play specific songs if you don't have premium) and finish PartyActivity to prevent going back to broken party.

Make host rejoining the party possible

if as the host, you accidentally press the hw back the activity is closed and reopening the app leads back to the home screen, and thus out of the party they had already started.

In order to prevent loss of party control by the host, once the host connects, the app should save some token/data in shared prefs onDestroy (or onPause) so that the host can regain access to the same party (app remote auth should automatically be preserved? because spotify would have remained open in bg).

This shared prefs data would only be destroyed when the host consciously clicks end party

add bottom snackbar to SearchFragment

the snackbar will display either red error info on failed search, or green notification that a clicked song was "Added to queue".

(ripple animation ticket #40 is closely related to the spirit of this ticket)

give PartyActivity a viewModel?

PartyActivity does a lot of service setup and teardown. This could be delegated to a viewmodel to clean up the activity

Not sure if activity+viewmodel is part of MVVM? will they work well together?

Nearby API device wifi connection prevents wifi usage

When a guest joins the party, it seems that it cant load any of the spotify scdn images from URL while the host app is using them.
If you completely close out of the host Partyq and Spotify, then the guest will suddenly load the missing images in the queue/now-playing.

Seems weird that there would be some limit on which devices can load the same images at the same time? Computer seems able to load the images from URL via browser? This might be an issue arising from a combo of Glide and whatever cdn stuff spotify is using?

make join party frag

make the structure for connecting to a party, just leaving the actual connection part stubbed out.

setup circleci

setup to run unit tests (not sure if I should do UI tests as well since that costs $$$ w/ firebase?)

adjust Menu item back nav

Repro:
Open app. Click start party. go to "more" options menu, and click either About or Legal. Click up arrow. You are taken back to PartyConnectFragment rather than SpotifyLoginFragment.

Expected behavior:
clicking up arrow takes you back to the screen you were on immediately before navigation.

Would fiddling with nav graph fix this?

make Queue service

the Host has to keep track of the current, master queue state for all guests.

The service will need to handle the queue of Items in the order to be played. It will also need to work closely with the communication service to send updates to all guests every time the queue changes (think about batching maybe? not sure how many reqs will be gotten w/ what freq).

There will need to be 2 versions. One for the host version that does the distribution, and one for guests that also holds their queue, but only locally (and receives updates from coms).

implement song skip

impl logic for iff >50% of party goers have voted to skip a song, then song is skipped

Make bottom nav not recreate fragments

With Jetpack Navigation, calling findNavController().navigate() will destroy the current fragment and recreate the target. For something like bottom nav, this could lead to a bad UX.

Consider looking into ways to avoid this fragment destruction when using Jetpack Nav + bottom nav

Create SpotifyPlayerService

Service should access the SpotifyAppRemote instance from SpotifyAuthenticationService to play songs out of the queue

create way to stop trying to discover a party

currently, when in PartyJoinFrag, if you press back discovery wont (?) stop, and returning to the fragment you will get a blank screen.

To fix:
in PartyJoinFrag onStop() stop discovery
ensure that returning to PartyJoinFrag doesn't result in blank screen (reset loading livedata???)
create a button to manually stop discovery?

song keeps playing after party end

Sometimes (not sure how often yet) after host selects leave party, app remote will disconnect before the pause command goes through.
Depending on how egregious this bug is, SpotifyPlayerService.disconnect() could be slightly reworked to:

spotifyAppRemote?.playerApi?.pause().setResultCallback {
    // if success or something (success may not even be necessary)
        SpotifyAppRemote.disconnect(spotifyAppRemote)
}

in order to ensure pause has had a chance to run

implement permission request

Nearby connections API requires 1-2 dangerous permissions. Add the required code for requesting these permissions from the user.
Add a rationale for why these permissions are necessary.

Add a dead-end screen (that links to settings app?) that is navigated to on permission denial

create toolbar layout

should have spot for logo drawable on left/start and a "More" dropdown menu on right/end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.