diff --git a/app/build.gradle b/app/build.gradle index e5f2fc08..cc65616b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,11 +7,8 @@ android { buildToolsVersion '33.0.0' defaultConfig { - applicationId 'com.cappielloantonio.tempo' minSdkVersion 24 targetSdkVersion 34 - versionCode 11 - versionName '3.4.4' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' @@ -25,6 +22,24 @@ android { } } + flavorDimensions "default" + + productFlavors { + tempo { + dimension "default" + applicationId 'com.cappielloantonio.tempo' + versionCode 11 + versionName '3.4.4' + } + + notquitemy { + dimension "default" + applicationId "com.cappielloantonio.notquitemy.tempo" + versionCode 1 + versionName "1.0.0" + } + } + buildTypes { release { shrinkResources true @@ -68,7 +83,7 @@ dependencies { implementation 'androidx.core:core-splashscreen:1.0.1' // Google GMS - implementation 'com.google.android.gms:play-services-cast-framework:21.3.0' + tempoImplementation 'com.google.android.gms:play-services-cast-framework:21.3.0' // Android Material implementation 'com.google.android.material:material:1.9.0' @@ -82,7 +97,7 @@ dependencies { implementation 'androidx.media3:media3-common:1.0.2' implementation 'androidx.media3:media3-exoplayer:1.0.2' implementation 'androidx.media3:media3-ui:1.0.2' - implementation 'androidx.media3:media3-cast:1.0.2' + tempoImplementation 'androidx.media3:media3-cast:1.0.2' annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1' annotationProcessor 'androidx.room:room-compiler:2.5.2' diff --git a/app/src/main/java/com/cappielloantonio/tempo/service/MediaService.kt b/app/src/main/java/com/cappielloantonio/tempo/service/MediaService.kt deleted file mode 100644 index 944e2ffd..00000000 --- a/app/src/main/java/com/cappielloantonio/tempo/service/MediaService.kt +++ /dev/null @@ -1,316 +0,0 @@ -package com.cappielloantonio.tempo.service - -import android.annotation.SuppressLint -import android.app.PendingIntent.FLAG_IMMUTABLE -import android.app.PendingIntent.FLAG_UPDATE_CURRENT -import android.app.TaskStackBuilder -import android.content.Intent -import android.os.Bundle -import androidx.media3.cast.CastPlayer -import androidx.media3.cast.SessionAvailabilityListener -import androidx.media3.common.* -import androidx.media3.common.util.UnstableApi -import androidx.media3.exoplayer.ExoPlayer -import androidx.media3.exoplayer.source.DefaultMediaSourceFactory -import androidx.media3.session.* -import androidx.media3.session.MediaSession.ControllerInfo -import com.cappielloantonio.tempo.R -import com.cappielloantonio.tempo.ui.activity.MainActivity -import com.cappielloantonio.tempo.util.Constants -import com.cappielloantonio.tempo.util.DownloadUtil -import com.cappielloantonio.tempo.util.UIUtil -import com.google.android.gms.cast.framework.CastContext -import com.google.common.collect.ImmutableList -import com.google.common.util.concurrent.Futures -import com.google.common.util.concurrent.ListenableFuture - - -@UnstableApi -class MediaService : MediaLibraryService(), SessionAvailabilityListener { - private val librarySessionCallback = CustomMediaLibrarySessionCallback() - - private lateinit var player: ExoPlayer - private lateinit var castPlayer: CastPlayer - private lateinit var mediaLibrarySession: MediaLibrarySession - private lateinit var customCommands: List - - private var customLayout = ImmutableList.of() - - companion object { - private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON = - "android.media3.session.demo.SHUFFLE_ON" - private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF = - "android.media3.session.demo.SHUFFLE_OFF" - } - - override fun onCreate() { - super.onCreate() - - initializeCustomCommands() - initializePlayer() - initializeCastPlayer() - initializeMediaLibrarySession() - initializePlayerListener() - - setPlayer( - null, - if (this::castPlayer.isInitialized && castPlayer.isCastSessionAvailable) castPlayer else player - ) - } - - override fun onGetSession(controllerInfo: ControllerInfo): MediaLibrarySession { - return mediaLibrarySession - } - - override fun onDestroy() { - releasePlayer() - super.onDestroy() - } - - private inner class CustomMediaLibrarySessionCallback : MediaLibrarySession.Callback { - - override fun onConnect( - session: MediaSession, - controller: ControllerInfo - ): MediaSession.ConnectionResult { - val connectionResult = super.onConnect(session, controller) - val availableSessionCommands = connectionResult.availableSessionCommands.buildUpon() - - customCommands.forEach { commandButton -> - // TODO: Aggiungere i comandi personalizzati - // commandButton.sessionCommand?.let { availableSessionCommands.add(it) } - } - - return MediaSession.ConnectionResult.accept( - availableSessionCommands.build(), - connectionResult.availablePlayerCommands - ) - } - - override fun onPostConnect(session: MediaSession, controller: ControllerInfo) { - if (!customLayout.isEmpty() && controller.controllerVersion != 0) { - ignoreFuture(mediaLibrarySession.setCustomLayout(controller, customLayout)) - } - } - - override fun onCustomCommand( - session: MediaSession, - controller: ControllerInfo, - customCommand: SessionCommand, - args: Bundle - ): ListenableFuture { - if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) { - player.shuffleModeEnabled = true - customLayout = ImmutableList.of(customCommands[1]) - session.setCustomLayout(customLayout) - } else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) { - player.shuffleModeEnabled = false - customLayout = ImmutableList.of(customCommands[0]) - session.setCustomLayout(customLayout) - } - - return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) - } - - /* override fun onGetLibraryRoot( - session: MediaLibrarySession, - browser: ControllerInfo, - params: LibraryParams? - ): ListenableFuture> { - return Futures.immediateFuture(LibraryResult.ofItem(MediaItemTree.getRootItem(), params)) - } - - override fun onGetItem( - session: MediaLibrarySession, - browser: ControllerInfo, - mediaId: String - ): ListenableFuture> { - val item = - MediaItemTree.getItem(mediaId) - ?: return Futures.immediateFuture( - LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE) - ) - return Futures.immediateFuture(LibraryResult.ofItem(item, /* params= */ null)) - } - - override fun onSubscribe( - session: MediaLibrarySession, - browser: ControllerInfo, - parentId: String, - params: LibraryParams? - ): ListenableFuture> { - val children = - MediaItemTree.getChildren(parentId) - ?: return Futures.immediateFuture( - LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE) - ) - session.notifyChildrenChanged(browser, parentId, children.size, params) - return Futures.immediateFuture(LibraryResult.ofVoid()) - } - - override fun onGetChildren( - session: MediaLibrarySession, - browser: ControllerInfo, - parentId: String, - page: Int, - pageSize: Int, - params: LibraryParams? - ): ListenableFuture>> { - val children = - MediaItemTree.getChildren(parentId) - ?: return Futures.immediateFuture( - LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE) - ) - - return Futures.immediateFuture(LibraryResult.ofItemList(children, params)) - }*/ - - override fun onAddMediaItems( - mediaSession: MediaSession, - controller: ControllerInfo, - mediaItems: List - ): ListenableFuture> { - val updatedMediaItems = mediaItems.map { - it.buildUpon() - .setUri(it.requestMetadata.mediaUri) - .setMediaMetadata(it.mediaMetadata) - .setMimeType(MimeTypes.BASE_TYPE_AUDIO) - .build() - } - return Futures.immediateFuture(updatedMediaItems) - } - } - - private fun initializeCustomCommands() { - customCommands = - listOf( - getShuffleCommandButton( - SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY) - ), - getShuffleCommandButton( - SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF, Bundle.EMPTY) - ) - ) - - customLayout = ImmutableList.of(customCommands[0]) - } - - private fun initializePlayer() { - player = ExoPlayer.Builder(this) - .setRenderersFactory(getRenderersFactory()) - .setMediaSourceFactory(getMediaSourceFactory()) - .setAudioAttributes(AudioAttributes.DEFAULT, true) - .setHandleAudioBecomingNoisy(true) - .setWakeMode(C.WAKE_MODE_NETWORK) - .build() - } - - private fun initializeCastPlayer() { - if (UIUtil.isCastApiAvailable(this)) { - castPlayer = CastPlayer(CastContext.getSharedInstance(this)) - castPlayer.setSessionAvailabilityListener(this) - } - } - - private fun initializeMediaLibrarySession() { - val sessionActivityPendingIntent = - TaskStackBuilder.create(this).run { - addNextIntent(Intent(this@MediaService, MainActivity::class.java)) - getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT) - } - - mediaLibrarySession = - MediaLibrarySession.Builder(this, player, librarySessionCallback) - .setSessionActivity(sessionActivityPendingIntent) - .build() - - if (!customLayout.isEmpty()) { - mediaLibrarySession.setCustomLayout(customLayout) - } - } - - private fun initializePlayerListener() { - player.addListener(object : Player.Listener { - override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { - if (mediaItem == null) return - - if(reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) { - MediaManager.setLastPlayedTimestamp(mediaItem) - } - } - - override fun onIsPlayingChanged(isPlaying: Boolean) { - if (!isPlaying) { - MediaManager.setPlayingPausedTimestamp( - player.currentMediaItem, - player.currentPosition - ) - } - } - - override fun onPositionDiscontinuity( - oldPosition: Player.PositionInfo, - newPosition: Player.PositionInfo, - reason: Int - ) { - super.onPositionDiscontinuity(oldPosition, newPosition, reason) - - if(reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) { - if (oldPosition.mediaItem?.mediaMetadata?.extras?.getString("type") == Constants.MEDIA_TYPE_MUSIC) { - MediaManager.scrobble(oldPosition.mediaItem) - MediaManager.saveChronology(oldPosition.mediaItem) - } - - if (newPosition.mediaItem?.mediaMetadata?.extras?.getString("type") == Constants.MEDIA_TYPE_MUSIC) { - MediaManager.setLastPlayedTimestamp(newPosition.mediaItem) - } - } - } - }) - } - - private fun setPlayer(oldPlayer: Player?, newPlayer: Player) { - if (oldPlayer === newPlayer) return - oldPlayer?.stop() - mediaLibrarySession.player = newPlayer - } - - private fun releasePlayer() { - if (this::castPlayer.isInitialized) castPlayer.setSessionAvailabilityListener(null) - if (this::castPlayer.isInitialized) castPlayer.release() - player.release() - mediaLibrarySession.release() - } - - @SuppressLint("PrivateResource") - private fun getShuffleCommandButton(sessionCommand: SessionCommand): CommandButton { - val isOn = sessionCommand.customAction == CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON - return CommandButton.Builder() - .setDisplayName( - getString( - if (isOn) R.string.exo_controls_shuffle_on_description - else R.string.exo_controls_shuffle_off_description - ) - ) - .setSessionCommand(sessionCommand) - .setIconResId(if (isOn) R.drawable.exo_icon_shuffle_off else R.drawable.exo_icon_shuffle_on) - .build() - } - - private fun ignoreFuture(customLayout: ListenableFuture) { - /* Do nothing. */ - } - - private fun getRenderersFactory() = DownloadUtil.buildRenderersFactory(this, false) - - private fun getMediaSourceFactory() = - DefaultMediaSourceFactory(this).setDataSourceFactory(DownloadUtil.getDataSourceFactory(this)) - - override fun onCastSessionAvailable() { - setPlayer(player, castPlayer) - } - - override fun onCastSessionUnavailable() { - setPlayer(castPlayer, player) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java b/app/src/main/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java index 7a984236..a33386c5 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java @@ -19,9 +19,8 @@ import androidx.media3.session.SessionToken; import com.cappielloantonio.tempo.service.DownloaderService; import com.cappielloantonio.tempo.service.MediaService; import com.cappielloantonio.tempo.ui.dialog.BatteryOptimizationDialog; +import com.cappielloantonio.tempo.util.Flavors; import com.cappielloantonio.tempo.util.Preferences; -import com.cappielloantonio.tempo.util.UIUtil; -import com.google.android.gms.cast.framework.CastContext; import com.google.android.material.elevation.SurfaceColors; import com.google.common.util.concurrent.ListenableFuture; @@ -34,7 +33,7 @@ public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - initializeCastContext(); + Flavors.initializeCastContext(this); initializeDownloader(); checkBatteryOptimization(); checkPermission(); @@ -54,7 +53,7 @@ public class BaseActivity extends AppCompatActivity { } private void checkBatteryOptimization() { - if (detectBatteryOptimization() && Preferences.askForOptimization()) { + if (detectBatteryOptimization() && Boolean.TRUE.equals(Preferences.askForOptimization())) { showBatteryOptimizationDialog(); } } @@ -98,10 +97,6 @@ public class BaseActivity extends AppCompatActivity { } } - private void initializeCastContext() { - if (UIUtil.isCastApiAvailable(this)) CastContext.getSharedInstance(this); - } - private void setNavigationBarColor() { getWindow().setNavigationBarColor(SurfaceColors.getColorForElevation(this, 10)); } diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java index 2ad61fd5..36c46420 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java @@ -3,9 +3,6 @@ package com.cappielloantonio.tempo.ui.fragment; import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -28,7 +25,7 @@ import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter; import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.viewmodel.DownloadViewModel; -import com.google.android.gms.cast.framework.CastButtonFactory; +import com.google.android.material.appbar.MaterialToolbar; import com.google.common.util.concurrent.ListenableFuture; import java.util.Objects; @@ -43,18 +40,7 @@ public class DownloadFragment extends Fragment implements ClickCallback { private ListenableFuture mediaBrowserListenableFuture; - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.media_route_menu_item); - } + private MaterialToolbar materialToolbar; @Nullable @Override @@ -97,22 +83,11 @@ public class DownloadFragment extends Fragment implements ClickCallback { bind = null; } - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_downloadFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_downloadFragment_to_settingsFragment); - return true; - } - - return false; - } - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); + materialToolbar = bind.getRoot().findViewById(R.id.toolbar); + + activity.setSupportActionBar(materialToolbar); + Objects.requireNonNull(materialToolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); } private void initDownloadedSongView() { diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java index a88e0bf5..8cb4dffc 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java @@ -2,9 +2,6 @@ package com.cappielloantonio.tempo.ui.fragment; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -18,7 +15,9 @@ import com.cappielloantonio.tempo.databinding.FragmentHomeBinding; import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.fragment.pager.HomePager; import com.cappielloantonio.tempo.util.Preferences; -import com.google.android.gms.cast.framework.CastButtonFactory; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.MaterialToolbar; +import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; import java.util.Objects; @@ -30,18 +29,9 @@ public class HomeFragment extends Fragment { private FragmentHomeBinding bind; private MainActivity activity; - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.media_route_menu_item); - } + private MaterialToolbar materialToolbar; + private AppBarLayout appBarLayout; + private TabLayout tabLayout; @Nullable @Override @@ -73,22 +63,18 @@ public class HomeFragment extends Fragment { bind = null; } - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_homeFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_homeFragment_to_settingsFragment); - return true; - } - - return false; - } - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); + appBarLayout = bind.getRoot().findViewById(R.id.toolbar_fragment); + materialToolbar = bind.getRoot().findViewById(R.id.toolbar); + + activity.setSupportActionBar(materialToolbar); + Objects.requireNonNull(materialToolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); + + tabLayout = new TabLayout(requireContext()); + tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); + tabLayout.setTabMode(TabLayout.MODE_FIXED); + + appBarLayout.addView(tabLayout); } private void initHomePager() { @@ -106,13 +92,13 @@ public class HomeFragment extends Fragment { bind.homeViewPager.setOffscreenPageLimit(3); bind.homeViewPager.setUserInputEnabled(false); - new TabLayoutMediator(bind.homeTabLayout, bind.homeViewPager, + new TabLayoutMediator(tabLayout, bind.homeViewPager, (tab, position) -> { tab.setText(pager.getPageTitle(position)); // tab.setIcon(pager.getPageIcon(position)); } ).attach(); - bind.homeTabLayout.setVisibility(Preferences.isPodcastSectionVisible() || Preferences.isRadioSectionVisible() ? View.VISIBLE : View.GONE); + tabLayout.setVisibility(Preferences.isPodcastSectionVisible() || Preferences.isRadioSectionVisible() ? View.VISIBLE : View.GONE); } } diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java index 6ceef14c..f97be710 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java @@ -2,9 +2,6 @@ package com.cappielloantonio.tempo.ui.fragment; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -30,7 +27,7 @@ import com.cappielloantonio.tempo.ui.adapter.PlaylistHorizontalAdapter; import com.cappielloantonio.tempo.ui.dialog.PlaylistEditorDialog; import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.viewmodel.LibraryViewModel; -import com.google.android.gms.cast.framework.CastButtonFactory; +import com.google.android.material.appbar.MaterialToolbar; import java.util.Objects; @@ -46,21 +43,9 @@ public class LibraryFragment extends Fragment implements ClickCallback { private AlbumAdapter albumAdapter; private ArtistAdapter artistAdapter; private GenreAdapter genreAdapter; - private PlaylistHorizontalAdapter playlistHorizontalAdapter; - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.media_route_menu_item); - } + private MaterialToolbar materialToolbar; @Nullable @Override @@ -100,19 +85,6 @@ public class LibraryFragment extends Fragment implements ClickCallback { bind = null; } - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_libraryFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_libraryFragment_to_settingsFragment); - return true; - } - - return false; - } - private void init() { bind.albumCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_albumCatalogueFragment)); bind.artistCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_artistCatalogueFragment)); @@ -142,8 +114,10 @@ public class LibraryFragment extends Fragment implements ClickCallback { } private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); + materialToolbar = bind.getRoot().findViewById(R.id.toolbar); + + activity.setSupportActionBar(materialToolbar); + Objects.requireNonNull(materialToolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); } private void initMusicFolderView() { diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/UIUtil.java b/app/src/main/java/com/cappielloantonio/tempo/util/UIUtil.java index 99a37eb5..7462a8b5 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/util/UIUtil.java +++ b/app/src/main/java/com/cappielloantonio/tempo/util/UIUtil.java @@ -7,9 +7,6 @@ import android.graphics.drawable.InsetDrawable; import androidx.recyclerview.widget.DividerItemDecoration; -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; - public class UIUtil { public static int getSpanCount(int itemCount, int maxSpan) { int itemSize = itemCount == 0 ? 1 : itemCount; @@ -21,10 +18,6 @@ public class UIUtil { } } - public static boolean isCastApiAvailable(Context context) { - return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS; - } - public static DividerItemDecoration getDividerItemDecoration(Context context) { int[] ATTRS = new int[]{android.R.attr.listDivider}; diff --git a/app/src/main/res/layout/fragment_download.xml b/app/src/main/res/layout/fragment_download.xml index e092ef30..cd4fc0c6 100644 --- a/app/src/main/res/layout/fragment_download.xml +++ b/app/src/main/res/layout/fragment_download.xml @@ -4,40 +4,11 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - - - - - - - - + android:layout_height="wrap_content" /> - - - - - - - - - - - - - - + android:layout_height="wrap_content" /> - - - - - - - - - - - - + android:layout_height="wrap_content" /> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_toolbar.xml b/app/src/main/res/layout/layout_toolbar.xml new file mode 100644 index 00000000..3661258a --- /dev/null +++ b/app/src/main/res/layout/layout_toolbar.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0b9716bc..4235ed37 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -256,4 +256,6 @@ Name Random No description available + + Hello blank fragment \ No newline at end of file diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/service/MediaService.kt b/app/src/notquitemy/java/com/cappielloantonio/tempo/service/MediaService.kt index 944e2ffd..1a445eb9 100644 --- a/app/src/notquitemy/java/com/cappielloantonio/tempo/service/MediaService.kt +++ b/app/src/notquitemy/java/com/cappielloantonio/tempo/service/MediaService.kt @@ -6,8 +6,6 @@ import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.app.TaskStackBuilder import android.content.Intent import android.os.Bundle -import androidx.media3.cast.CastPlayer -import androidx.media3.cast.SessionAvailabilityListener import androidx.media3.common.* import androidx.media3.common.util.UnstableApi import androidx.media3.exoplayer.ExoPlayer @@ -18,19 +16,16 @@ import com.cappielloantonio.tempo.R import com.cappielloantonio.tempo.ui.activity.MainActivity import com.cappielloantonio.tempo.util.Constants import com.cappielloantonio.tempo.util.DownloadUtil -import com.cappielloantonio.tempo.util.UIUtil -import com.google.android.gms.cast.framework.CastContext import com.google.common.collect.ImmutableList import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture @UnstableApi -class MediaService : MediaLibraryService(), SessionAvailabilityListener { +class MediaService : MediaLibraryService() { private val librarySessionCallback = CustomMediaLibrarySessionCallback() private lateinit var player: ExoPlayer - private lateinit var castPlayer: CastPlayer private lateinit var mediaLibrarySession: MediaLibrarySession private lateinit var customCommands: List @@ -48,14 +43,10 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { initializeCustomCommands() initializePlayer() - initializeCastPlayer() initializeMediaLibrarySession() initializePlayerListener() - setPlayer( - null, - if (this::castPlayer.isInitialized && castPlayer.isCastSessionAvailable) castPlayer else player - ) + setPlayer(player) } override fun onGetSession(controllerInfo: ControllerInfo): MediaLibrarySession { @@ -112,59 +103,6 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } - /* override fun onGetLibraryRoot( - session: MediaLibrarySession, - browser: ControllerInfo, - params: LibraryParams? - ): ListenableFuture> { - return Futures.immediateFuture(LibraryResult.ofItem(MediaItemTree.getRootItem(), params)) - } - - override fun onGetItem( - session: MediaLibrarySession, - browser: ControllerInfo, - mediaId: String - ): ListenableFuture> { - val item = - MediaItemTree.getItem(mediaId) - ?: return Futures.immediateFuture( - LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE) - ) - return Futures.immediateFuture(LibraryResult.ofItem(item, /* params= */ null)) - } - - override fun onSubscribe( - session: MediaLibrarySession, - browser: ControllerInfo, - parentId: String, - params: LibraryParams? - ): ListenableFuture> { - val children = - MediaItemTree.getChildren(parentId) - ?: return Futures.immediateFuture( - LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE) - ) - session.notifyChildrenChanged(browser, parentId, children.size, params) - return Futures.immediateFuture(LibraryResult.ofVoid()) - } - - override fun onGetChildren( - session: MediaLibrarySession, - browser: ControllerInfo, - parentId: String, - page: Int, - pageSize: Int, - params: LibraryParams? - ): ListenableFuture>> { - val children = - MediaItemTree.getChildren(parentId) - ?: return Futures.immediateFuture( - LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE) - ) - - return Futures.immediateFuture(LibraryResult.ofItemList(children, params)) - }*/ - override fun onAddMediaItems( mediaSession: MediaSession, controller: ControllerInfo, @@ -205,13 +143,6 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { .build() } - private fun initializeCastPlayer() { - if (UIUtil.isCastApiAvailable(this)) { - castPlayer = CastPlayer(CastContext.getSharedInstance(this)) - castPlayer.setSessionAvailabilityListener(this) - } - } - private fun initializeMediaLibrarySession() { val sessionActivityPendingIntent = TaskStackBuilder.create(this).run { @@ -234,7 +165,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { if (mediaItem == null) return - if(reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) { + if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) { MediaManager.setLastPlayedTimestamp(mediaItem) } } @@ -255,7 +186,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { ) { super.onPositionDiscontinuity(oldPosition, newPosition, reason) - if(reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) { + if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) { if (oldPosition.mediaItem?.mediaMetadata?.extras?.getString("type") == Constants.MEDIA_TYPE_MUSIC) { MediaManager.scrobble(oldPosition.mediaItem) MediaManager.saveChronology(oldPosition.mediaItem) @@ -269,15 +200,11 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { }) } - private fun setPlayer(oldPlayer: Player?, newPlayer: Player) { - if (oldPlayer === newPlayer) return - oldPlayer?.stop() - mediaLibrarySession.player = newPlayer + private fun setPlayer(player: Player) { + mediaLibrarySession.player = player } private fun releasePlayer() { - if (this::castPlayer.isInitialized) castPlayer.setSessionAvailabilityListener(null) - if (this::castPlayer.isInitialized) castPlayer.release() player.release() mediaLibrarySession.release() } @@ -306,11 +233,5 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { private fun getMediaSourceFactory() = DefaultMediaSourceFactory(this).setDataSourceFactory(DownloadUtil.getDataSourceFactory(this)) - override fun onCastSessionAvailable() { - setPlayer(player, castPlayer) - } - override fun onCastSessionUnavailable() { - setPlayer(castPlayer, player) - } } \ No newline at end of file diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java b/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java deleted file mode 100644 index 69cb87ed..00000000 --- a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.cappielloantonio.tempo.ui.activity.base; - -import android.Manifest; -import android.content.ComponentName; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.os.PowerManager; - -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import androidx.media3.common.util.UnstableApi; -import androidx.media3.exoplayer.offline.DownloadService; -import androidx.media3.session.MediaBrowser; -import androidx.media3.session.SessionToken; - -import com.cappielloantonio.tempo.service.DownloaderService; -import com.cappielloantonio.tempo.service.MediaService; -import com.cappielloantonio.tempo.ui.dialog.BatteryOptimizationDialog; -import com.cappielloantonio.tempo.util.Preferences; -import com.google.android.material.elevation.SurfaceColors; -import com.google.common.util.concurrent.ListenableFuture; - -@UnstableApi -public class BaseActivity extends AppCompatActivity { - private static final String TAG = "BaseActivity"; - - private ListenableFuture mediaBrowserListenableFuture; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - initializeDownloader(); - checkBatteryOptimization(); - checkPermission(); - } - - @Override - protected void onStart() { - super.onStart(); - setNavigationBarColor(); - initializeBrowser(); - } - - @Override - protected void onStop() { - releaseBrowser(); - super.onStop(); - } - - private void checkBatteryOptimization() { - if (detectBatteryOptimization() && Preferences.askForOptimization()) { - showBatteryOptimizationDialog(); - } - } - - private void checkPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, 101); - } - } - } - - private boolean detectBatteryOptimization() { - String packageName = getPackageName(); - PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); - return !powerManager.isIgnoringBatteryOptimizations(packageName); - } - - private void showBatteryOptimizationDialog() { - BatteryOptimizationDialog dialog = new BatteryOptimizationDialog(); - dialog.show(getSupportFragmentManager(), null); - } - - private void initializeBrowser() { - mediaBrowserListenableFuture = new MediaBrowser.Builder(this, new SessionToken(this, new ComponentName(this, MediaService.class))).buildAsync(); - } - - private void releaseBrowser() { - MediaBrowser.releaseFuture(mediaBrowserListenableFuture); - } - - public ListenableFuture getMediaBrowserListenableFuture() { - return mediaBrowserListenableFuture; - } - - private void initializeDownloader() { - try { - DownloadService.start(this, DownloaderService.class); - } catch (IllegalStateException e) { - DownloadService.startForeground(this, DownloaderService.class); - } - } - - private void setNavigationBarColor() { - getWindow().setNavigationBarColor(SurfaceColors.getColorForElevation(this, 10)); - } -} diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java b/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java deleted file mode 100644 index f89f562a..00000000 --- a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.cappielloantonio.tempo.ui.fragment; - -import android.content.ComponentName; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.media3.common.util.UnstableApi; -import androidx.media3.session.MediaBrowser; -import androidx.media3.session.SessionToken; -import androidx.navigation.Navigation; -import androidx.recyclerview.widget.LinearLayoutManager; - -import com.cappielloantonio.tempo.R; -import com.cappielloantonio.tempo.databinding.FragmentDownloadBinding; -import com.cappielloantonio.tempo.interfaces.ClickCallback; -import com.cappielloantonio.tempo.service.MediaManager; -import com.cappielloantonio.tempo.service.MediaService; -import com.cappielloantonio.tempo.ui.activity.MainActivity; -import com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter; -import com.cappielloantonio.tempo.util.Constants; -import com.cappielloantonio.tempo.viewmodel.DownloadViewModel; -import com.google.common.util.concurrent.ListenableFuture; - -import java.util.Objects; - -@UnstableApi -public class DownloadFragment extends Fragment implements ClickCallback { - private FragmentDownloadBinding bind; - private MainActivity activity; - private DownloadViewModel downloadViewModel; - - private DownloadHorizontalAdapter downloadHorizontalAdapter; - - private ListenableFuture mediaBrowserListenableFuture; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - activity = (MainActivity) getActivity(); - - bind = FragmentDownloadBinding.inflate(inflater, container, false); - View view = bind.getRoot(); - downloadViewModel = new ViewModelProvider(requireActivity()).get(DownloadViewModel.class); - - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - initAppBar(); - initDownloadedSongView(); - } - - @Override - public void onStart() { - super.onStart(); - - initializeMediaBrowser(); - activity.setBottomNavigationBarVisibility(true); - activity.setBottomSheetVisibility(true); - } - - @Override - public void onStop() { - releaseMediaBrowser(); - super.onStop(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - bind = null; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_downloadFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_downloadFragment_to_settingsFragment); - return true; - } - - return false; - } - - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); - } - - private void initDownloadedSongView() { - bind.downloadedTracksRecyclerView.setHasFixedSize(true); - - downloadHorizontalAdapter = new DownloadHorizontalAdapter(this); - bind.downloadedTracksRecyclerView.setAdapter(downloadHorizontalAdapter); - downloadViewModel.getDownloadedTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { - if (songs != null) { - if (songs.isEmpty()) { - if (bind != null) { - bind.emptyDownloadLayout.setVisibility(View.VISIBLE); - bind.fragmentDownloadNestedScrollView.setVisibility(View.GONE); - - bind.downloadDownloadedTracksPlaceholder.placeholder.setVisibility(View.VISIBLE); - bind.downloadDownloadedTracksSector.setVisibility(View.GONE); - } - } else { - if (bind != null) { - bind.emptyDownloadLayout.setVisibility(View.GONE); - bind.fragmentDownloadNestedScrollView.setVisibility(View.VISIBLE); - - bind.downloadDownloadedTracksPlaceholder.placeholder.setVisibility(View.GONE); - bind.downloadDownloadedTracksSector.setVisibility(View.VISIBLE); - - bind.downloadedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); - - downloadHorizontalAdapter.setItems(songs); - } - } - - if (bind != null) bind.loadingProgressBar.setVisibility(View.GONE); - } - }); - } - - private void initializeMediaBrowser() { - mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); - } - - private void releaseMediaBrowser() { - MediaBrowser.releaseFuture(mediaBrowserListenableFuture); - } - - @Override - public void onMediaClick(Bundle bundle) { - MediaManager.startQueue(mediaBrowserListenableFuture, bundle.getParcelableArrayList(Constants.TRACKS_OBJECT), bundle.getInt(Constants.ITEM_POSITION)); - activity.setBottomSheetInPeek(true); - } - - @Override - public void onMediaLongClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); - } -} diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java b/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java deleted file mode 100644 index 05c67979..00000000 --- a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.cappielloantonio.tempo.ui.fragment; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.media3.common.util.UnstableApi; - -import com.cappielloantonio.tempo.R; -import com.cappielloantonio.tempo.databinding.FragmentHomeBinding; -import com.cappielloantonio.tempo.ui.activity.MainActivity; -import com.cappielloantonio.tempo.ui.fragment.pager.HomePager; -import com.cappielloantonio.tempo.util.Preferences; -import com.google.android.material.tabs.TabLayoutMediator; - -import java.util.Objects; - -@UnstableApi -public class HomeFragment extends Fragment { - private static final String TAG = "HomeFragment"; - - private FragmentHomeBinding bind; - private MainActivity activity; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - activity = (MainActivity) getActivity(); - bind = FragmentHomeBinding.inflate(inflater, container, false); - return bind.getRoot(); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - initAppBar(); - initHomePager(); - } - - @Override - public void onStart() { - super.onStart(); - - activity.setBottomNavigationBarVisibility(true); - activity.setBottomSheetVisibility(true); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - bind = null; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_homeFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_homeFragment_to_settingsFragment); - return true; - } - - return false; - } - - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); - } - - private void initHomePager() { - HomePager pager = new HomePager(this); - - pager.addFragment(new HomeTabMusicFragment(), "Music", R.drawable.ic_home); - - if (Preferences.isPodcastSectionVisible()) - pager.addFragment(new HomeTabPodcastFragment(), "Podcast", R.drawable.ic_graphic_eq); - - if (Preferences.isRadioSectionVisible()) - pager.addFragment(new HomeTabRadioFragment(), "Radio", R.drawable.ic_play_for_work); - - bind.homeViewPager.setAdapter(pager); - bind.homeViewPager.setOffscreenPageLimit(3); - bind.homeViewPager.setUserInputEnabled(false); - - new TabLayoutMediator(bind.homeTabLayout, bind.homeViewPager, - (tab, position) -> { - tab.setText(pager.getPageTitle(position)); - // tab.setIcon(pager.getPageIcon(position)); - } - ).attach(); - - bind.homeTabLayout.setVisibility(Preferences.isPodcastSectionVisible() || Preferences.isRadioSectionVisible() ? View.VISIBLE : View.GONE); - } -} diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java b/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java deleted file mode 100644 index 5529c93c..00000000 --- a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java +++ /dev/null @@ -1,306 +0,0 @@ -package com.cappielloantonio.tempo.ui.fragment; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.media3.common.util.UnstableApi; -import androidx.navigation.Navigation; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; - -import com.cappielloantonio.tempo.R; -import com.cappielloantonio.tempo.databinding.FragmentLibraryBinding; -import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper; -import com.cappielloantonio.tempo.interfaces.ClickCallback; -import com.cappielloantonio.tempo.ui.activity.MainActivity; -import com.cappielloantonio.tempo.ui.adapter.AlbumAdapter; -import com.cappielloantonio.tempo.ui.adapter.ArtistAdapter; -import com.cappielloantonio.tempo.ui.adapter.GenreAdapter; -import com.cappielloantonio.tempo.ui.adapter.MusicFolderAdapter; -import com.cappielloantonio.tempo.ui.adapter.PlaylistHorizontalAdapter; -import com.cappielloantonio.tempo.ui.dialog.PlaylistEditorDialog; -import com.cappielloantonio.tempo.util.Constants; -import com.cappielloantonio.tempo.viewmodel.LibraryViewModel; - -import java.util.Objects; - -@UnstableApi -public class LibraryFragment extends Fragment implements ClickCallback { - private static final String TAG = "LibraryFragment"; - - private FragmentLibraryBinding bind; - private MainActivity activity; - private LibraryViewModel libraryViewModel; - - private MusicFolderAdapter musicFolderAdapter; - private AlbumAdapter albumAdapter; - private ArtistAdapter artistAdapter; - private GenreAdapter genreAdapter; - - private PlaylistHorizontalAdapter playlistHorizontalAdapter; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - activity = (MainActivity) getActivity(); - - bind = FragmentLibraryBinding.inflate(inflater, container, false); - View view = bind.getRoot(); - libraryViewModel = new ViewModelProvider(requireActivity()).get(LibraryViewModel.class); - - init(); - - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - initAppBar(); - initMusicFolderView(); - initAlbumView(); - initArtistView(); - initGenreView(); - initPlaylistSlideView(); - } - - @Override - public void onStart() { - super.onStart(); - activity.setBottomNavigationBarVisibility(true); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - bind = null; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_libraryFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_libraryFragment_to_settingsFragment); - return true; - } - - return false; - } - - private void init() { - bind.albumCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_albumCatalogueFragment)); - bind.artistCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_artistCatalogueFragment)); - bind.genreCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_genreCatalogueFragment)); - bind.playlistCatalogueTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.PLAYLIST_ALL, Constants.PLAYLIST_ALL); - activity.navController.navigate(R.id.action_libraryFragment_to_playlistCatalogueFragment, bundle); - }); - - bind.albumCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshAlbumSample(getViewLifecycleOwner()); - return true; - }); - bind.artistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshArtistSample(getViewLifecycleOwner()); - return true; - }); - bind.genreCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshGenreSample(getViewLifecycleOwner()); - return true; - }); - bind.playlistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshPlaylistSample(getViewLifecycleOwner()); - return true; - }); - } - - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); - } - - private void initMusicFolderView() { - bind.musicFolderRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); - bind.musicFolderRecyclerView.setHasFixedSize(true); - - musicFolderAdapter = new MusicFolderAdapter(this); - bind.musicFolderRecyclerView.setAdapter(musicFolderAdapter); - libraryViewModel.getMusicFolders(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), musicFolders -> { - if (musicFolders == null) { - if (bind != null) - bind.libraryMusicFolderPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryMusicFolderSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.libraryMusicFolderPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryMusicFolderSector.setVisibility(!musicFolders.isEmpty() ? View.VISIBLE : View.GONE); - - musicFolderAdapter.setItems(musicFolders); - } - }); - } - - private void initAlbumView() { - bind.albumRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.albumRecyclerView.setHasFixedSize(true); - - albumAdapter = new AlbumAdapter(this); - bind.albumRecyclerView.setAdapter(albumAdapter); - libraryViewModel.getAlbumSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { - if (albums == null) { - if (bind != null) - bind.libraryAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryAlbumSector.setVisibility(View.GONE); - } else { - if (bind != null) bind.libraryAlbumPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryAlbumSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); - - albumAdapter.setItems(albums); - } - }); - - CustomLinearSnapHelper albumSnapHelper = new CustomLinearSnapHelper(); - albumSnapHelper.attachToRecyclerView(bind.albumRecyclerView); - } - - private void initArtistView() { - bind.artistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.artistRecyclerView.setHasFixedSize(true); - - artistAdapter = new ArtistAdapter(this, false, false); - bind.artistRecyclerView.setAdapter(artistAdapter); - libraryViewModel.getArtistSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { - if (artists == null) { - if (bind != null) - bind.libraryArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryArtistSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.libraryArtistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); - - artistAdapter.setItems(artists); - } - }); - - CustomLinearSnapHelper artistSnapHelper = new CustomLinearSnapHelper(); - artistSnapHelper.attachToRecyclerView(bind.artistRecyclerView); - } - - private void initGenreView() { - bind.genreRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3, GridLayoutManager.HORIZONTAL, false)); - bind.genreRecyclerView.setHasFixedSize(true); - - genreAdapter = new GenreAdapter(this); - bind.genreRecyclerView.setAdapter(genreAdapter); - - libraryViewModel.getGenreSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), genres -> { - if (genres == null) { - if (bind != null) - bind.libraryGenrePlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryGenresSector.setVisibility(View.GONE); - } else { - if (bind != null) bind.libraryGenrePlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryGenresSector.setVisibility(!genres.isEmpty() ? View.VISIBLE : View.GONE); - - genreAdapter.setItems(genres); - } - }); - - CustomLinearSnapHelper genreSnapHelper = new CustomLinearSnapHelper(); - genreSnapHelper.attachToRecyclerView(bind.genreRecyclerView); - } - - private void initPlaylistSlideView() { - bind.playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); - bind.playlistRecyclerView.setHasFixedSize(true); - - playlistHorizontalAdapter = new PlaylistHorizontalAdapter(this); - bind.playlistRecyclerView.setAdapter(playlistHorizontalAdapter); - libraryViewModel.getPlaylistSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), playlists -> { - if (playlists == null) { - if (bind != null) - bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryPlaylistSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryPlaylistSector.setVisibility(!playlists.isEmpty() ? View.VISIBLE : View.GONE); - - playlistHorizontalAdapter.setItems(playlists); - } - }); - } - - @Override - public void onAlbumClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); - } - - @Override - public void onAlbumLongClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); - } - - @Override - public void onArtistClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); - } - - @Override - public void onArtistLongClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); - } - - @Override - public void onGenreClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.songListPageFragment, bundle); - } - - @Override - public void onPlaylistClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle); - } - - @Override - public void onPlaylistLongClick(Bundle bundle) { - PlaylistEditorDialog dialog = new PlaylistEditorDialog(); - dialog.setArguments(bundle); - dialog.show(activity.getSupportFragmentManager(), null); - } - - @Override - public void onMusicFolderClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.indexFragment, bundle); - } -} diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/ToolbarFragment.java b/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/ToolbarFragment.java new file mode 100644 index 00000000..2ad74c89 --- /dev/null +++ b/app/src/notquitemy/java/com/cappielloantonio/tempo/ui/fragment/ToolbarFragment.java @@ -0,0 +1,65 @@ +package com.cappielloantonio.tempo.ui.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.media3.common.util.UnstableApi; + +import com.cappielloantonio.tempo.R; +import com.cappielloantonio.tempo.databinding.FragmentToolbarBinding; +import com.cappielloantonio.tempo.ui.activity.MainActivity; + +@UnstableApi +public class ToolbarFragment extends Fragment { + private static final String TAG = "ToolbarFragment"; + + private FragmentToolbarBinding bind; + private MainActivity activity; + + public ToolbarFragment() { + // Required empty public constructor + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.main_page_menu, menu); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + activity = (MainActivity) getActivity(); + + bind = FragmentToolbarBinding.inflate(inflater, container, false); + View view = bind.getRoot(); + + return view; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_search) { + activity.navController.navigate(R.id.searchFragment); + return true; + } else if (item.getItemId() == R.id.action_settings) { + activity.navController.navigate(R.id.settingsFragment); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/util/Flavors.java b/app/src/notquitemy/java/com/cappielloantonio/tempo/util/Flavors.java new file mode 100644 index 00000000..68d23509 --- /dev/null +++ b/app/src/notquitemy/java/com/cappielloantonio/tempo/util/Flavors.java @@ -0,0 +1,9 @@ +package com.cappielloantonio.tempo.util; + +import android.content.Context; + +public class Flavors { + public static void initializeCastContext(Context context) { + + } +} diff --git a/app/src/notquitemy/java/com/cappielloantonio/tempo/util/UIUtil.java b/app/src/notquitemy/java/com/cappielloantonio/tempo/util/UIUtil.java deleted file mode 100644 index 7462a8b5..00000000 --- a/app/src/notquitemy/java/com/cappielloantonio/tempo/util/UIUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.cappielloantonio.tempo.util; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.InsetDrawable; - -import androidx.recyclerview.widget.DividerItemDecoration; - -public class UIUtil { - public static int getSpanCount(int itemCount, int maxSpan) { - int itemSize = itemCount == 0 ? 1 : itemCount; - - if (itemSize / maxSpan > 0) { - return maxSpan; - } else { - return itemSize % maxSpan; - } - } - - public static DividerItemDecoration getDividerItemDecoration(Context context) { - int[] ATTRS = new int[]{android.R.attr.listDivider}; - - TypedArray a = context.obtainStyledAttributes(ATTRS); - Drawable divider = a.getDrawable(0); - InsetDrawable insetDivider = new InsetDrawable(divider, 42, 0, 42, 42); - a.recycle(); - - DividerItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL); - itemDecoration.setDrawable(insetDivider); - - return itemDecoration; - } -} diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt b/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt index 944e2ffd..edccf37d 100644 --- a/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt +++ b/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt @@ -18,8 +18,9 @@ import com.cappielloantonio.tempo.R import com.cappielloantonio.tempo.ui.activity.MainActivity import com.cappielloantonio.tempo.util.Constants import com.cappielloantonio.tempo.util.DownloadUtil -import com.cappielloantonio.tempo.util.UIUtil import com.google.android.gms.cast.framework.CastContext +import com.google.android.gms.common.ConnectionResult +import com.google.android.gms.common.GoogleApiAvailability import com.google.common.collect.ImmutableList import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture @@ -206,7 +207,9 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { } private fun initializeCastPlayer() { - if (UIUtil.isCastApiAvailable(this)) { + if (GoogleApiAvailability.getInstance() + .isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS + ) { castPlayer = CastPlayer(CastContext.getSharedInstance(this)) castPlayer.setSessionAvailabilityListener(this) } @@ -234,7 +237,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { if (mediaItem == null) return - if(reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) { + if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) { MediaManager.setLastPlayedTimestamp(mediaItem) } } @@ -255,7 +258,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { ) { super.onPositionDiscontinuity(oldPosition, newPosition, reason) - if(reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) { + if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) { if (oldPosition.mediaItem?.mediaMetadata?.extras?.getString("type") == Constants.MEDIA_TYPE_MUSIC) { MediaManager.scrobble(oldPosition.mediaItem) MediaManager.saveChronology(oldPosition.mediaItem) diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java b/app/src/tempo/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java deleted file mode 100644 index 7a984236..00000000 --- a/app/src/tempo/java/com/cappielloantonio/tempo/ui/activity/base/BaseActivity.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.cappielloantonio.tempo.ui.activity.base; - -import android.Manifest; -import android.content.ComponentName; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.os.PowerManager; - -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import androidx.media3.common.util.UnstableApi; -import androidx.media3.exoplayer.offline.DownloadService; -import androidx.media3.session.MediaBrowser; -import androidx.media3.session.SessionToken; - -import com.cappielloantonio.tempo.service.DownloaderService; -import com.cappielloantonio.tempo.service.MediaService; -import com.cappielloantonio.tempo.ui.dialog.BatteryOptimizationDialog; -import com.cappielloantonio.tempo.util.Preferences; -import com.cappielloantonio.tempo.util.UIUtil; -import com.google.android.gms.cast.framework.CastContext; -import com.google.android.material.elevation.SurfaceColors; -import com.google.common.util.concurrent.ListenableFuture; - -@UnstableApi -public class BaseActivity extends AppCompatActivity { - private static final String TAG = "BaseActivity"; - - private ListenableFuture mediaBrowserListenableFuture; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - initializeCastContext(); - initializeDownloader(); - checkBatteryOptimization(); - checkPermission(); - } - - @Override - protected void onStart() { - super.onStart(); - setNavigationBarColor(); - initializeBrowser(); - } - - @Override - protected void onStop() { - releaseBrowser(); - super.onStop(); - } - - private void checkBatteryOptimization() { - if (detectBatteryOptimization() && Preferences.askForOptimization()) { - showBatteryOptimizationDialog(); - } - } - - private void checkPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, 101); - } - } - } - - private boolean detectBatteryOptimization() { - String packageName = getPackageName(); - PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); - return !powerManager.isIgnoringBatteryOptimizations(packageName); - } - - private void showBatteryOptimizationDialog() { - BatteryOptimizationDialog dialog = new BatteryOptimizationDialog(); - dialog.show(getSupportFragmentManager(), null); - } - - private void initializeBrowser() { - mediaBrowserListenableFuture = new MediaBrowser.Builder(this, new SessionToken(this, new ComponentName(this, MediaService.class))).buildAsync(); - } - - private void releaseBrowser() { - MediaBrowser.releaseFuture(mediaBrowserListenableFuture); - } - - public ListenableFuture getMediaBrowserListenableFuture() { - return mediaBrowserListenableFuture; - } - - private void initializeDownloader() { - try { - DownloadService.start(this, DownloaderService.class); - } catch (IllegalStateException e) { - DownloadService.startForeground(this, DownloaderService.class); - } - } - - private void initializeCastContext() { - if (UIUtil.isCastApiAvailable(this)) CastContext.getSharedInstance(this); - } - - private void setNavigationBarColor() { - getWindow().setNavigationBarColor(SurfaceColors.getColorForElevation(this, 10)); - } -} diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java b/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java deleted file mode 100644 index 2ad61fd5..00000000 --- a/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/DownloadFragment.java +++ /dev/null @@ -1,170 +0,0 @@ -package com.cappielloantonio.tempo.ui.fragment; - -import android.content.ComponentName; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.media3.common.util.UnstableApi; -import androidx.media3.session.MediaBrowser; -import androidx.media3.session.SessionToken; -import androidx.navigation.Navigation; -import androidx.recyclerview.widget.LinearLayoutManager; - -import com.cappielloantonio.tempo.R; -import com.cappielloantonio.tempo.databinding.FragmentDownloadBinding; -import com.cappielloantonio.tempo.interfaces.ClickCallback; -import com.cappielloantonio.tempo.service.MediaManager; -import com.cappielloantonio.tempo.service.MediaService; -import com.cappielloantonio.tempo.ui.activity.MainActivity; -import com.cappielloantonio.tempo.ui.adapter.DownloadHorizontalAdapter; -import com.cappielloantonio.tempo.util.Constants; -import com.cappielloantonio.tempo.viewmodel.DownloadViewModel; -import com.google.android.gms.cast.framework.CastButtonFactory; -import com.google.common.util.concurrent.ListenableFuture; - -import java.util.Objects; - -@UnstableApi -public class DownloadFragment extends Fragment implements ClickCallback { - private FragmentDownloadBinding bind; - private MainActivity activity; - private DownloadViewModel downloadViewModel; - - private DownloadHorizontalAdapter downloadHorizontalAdapter; - - private ListenableFuture mediaBrowserListenableFuture; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.media_route_menu_item); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - activity = (MainActivity) getActivity(); - - bind = FragmentDownloadBinding.inflate(inflater, container, false); - View view = bind.getRoot(); - downloadViewModel = new ViewModelProvider(requireActivity()).get(DownloadViewModel.class); - - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - initAppBar(); - initDownloadedSongView(); - } - - @Override - public void onStart() { - super.onStart(); - - initializeMediaBrowser(); - activity.setBottomNavigationBarVisibility(true); - activity.setBottomSheetVisibility(true); - } - - @Override - public void onStop() { - releaseMediaBrowser(); - super.onStop(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - bind = null; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_downloadFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_downloadFragment_to_settingsFragment); - return true; - } - - return false; - } - - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); - } - - private void initDownloadedSongView() { - bind.downloadedTracksRecyclerView.setHasFixedSize(true); - - downloadHorizontalAdapter = new DownloadHorizontalAdapter(this); - bind.downloadedTracksRecyclerView.setAdapter(downloadHorizontalAdapter); - downloadViewModel.getDownloadedTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { - if (songs != null) { - if (songs.isEmpty()) { - if (bind != null) { - bind.emptyDownloadLayout.setVisibility(View.VISIBLE); - bind.fragmentDownloadNestedScrollView.setVisibility(View.GONE); - - bind.downloadDownloadedTracksPlaceholder.placeholder.setVisibility(View.VISIBLE); - bind.downloadDownloadedTracksSector.setVisibility(View.GONE); - } - } else { - if (bind != null) { - bind.emptyDownloadLayout.setVisibility(View.GONE); - bind.fragmentDownloadNestedScrollView.setVisibility(View.VISIBLE); - - bind.downloadDownloadedTracksPlaceholder.placeholder.setVisibility(View.GONE); - bind.downloadDownloadedTracksSector.setVisibility(View.VISIBLE); - - bind.downloadedTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); - - downloadHorizontalAdapter.setItems(songs); - } - } - - if (bind != null) bind.loadingProgressBar.setVisibility(View.GONE); - } - }); - } - - private void initializeMediaBrowser() { - mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); - } - - private void releaseMediaBrowser() { - MediaBrowser.releaseFuture(mediaBrowserListenableFuture); - } - - @Override - public void onMediaClick(Bundle bundle) { - MediaManager.startQueue(mediaBrowserListenableFuture, bundle.getParcelableArrayList(Constants.TRACKS_OBJECT), bundle.getInt(Constants.ITEM_POSITION)); - activity.setBottomSheetInPeek(true); - } - - @Override - public void onMediaLongClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); - } -} diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java b/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java deleted file mode 100644 index a88e0bf5..00000000 --- a/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/HomeFragment.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.cappielloantonio.tempo.ui.fragment; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.media3.common.util.UnstableApi; - -import com.cappielloantonio.tempo.R; -import com.cappielloantonio.tempo.databinding.FragmentHomeBinding; -import com.cappielloantonio.tempo.ui.activity.MainActivity; -import com.cappielloantonio.tempo.ui.fragment.pager.HomePager; -import com.cappielloantonio.tempo.util.Preferences; -import com.google.android.gms.cast.framework.CastButtonFactory; -import com.google.android.material.tabs.TabLayoutMediator; - -import java.util.Objects; - -@UnstableApi -public class HomeFragment extends Fragment { - private static final String TAG = "HomeFragment"; - - private FragmentHomeBinding bind; - private MainActivity activity; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.media_route_menu_item); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - activity = (MainActivity) getActivity(); - bind = FragmentHomeBinding.inflate(inflater, container, false); - return bind.getRoot(); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - initAppBar(); - initHomePager(); - } - - @Override - public void onStart() { - super.onStart(); - - activity.setBottomNavigationBarVisibility(true); - activity.setBottomSheetVisibility(true); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - bind = null; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_homeFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_homeFragment_to_settingsFragment); - return true; - } - - return false; - } - - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); - } - - private void initHomePager() { - HomePager pager = new HomePager(this); - - pager.addFragment(new HomeTabMusicFragment(), "Music", R.drawable.ic_home); - - if (Preferences.isPodcastSectionVisible()) - pager.addFragment(new HomeTabPodcastFragment(), "Podcast", R.drawable.ic_graphic_eq); - - if (Preferences.isRadioSectionVisible()) - pager.addFragment(new HomeTabRadioFragment(), "Radio", R.drawable.ic_play_for_work); - - bind.homeViewPager.setAdapter(pager); - bind.homeViewPager.setOffscreenPageLimit(3); - bind.homeViewPager.setUserInputEnabled(false); - - new TabLayoutMediator(bind.homeTabLayout, bind.homeViewPager, - (tab, position) -> { - tab.setText(pager.getPageTitle(position)); - // tab.setIcon(pager.getPageIcon(position)); - } - ).attach(); - - bind.homeTabLayout.setVisibility(Preferences.isPodcastSectionVisible() || Preferences.isRadioSectionVisible() ? View.VISIBLE : View.GONE); - } -} diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java b/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java deleted file mode 100644 index 6ceef14c..00000000 --- a/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/LibraryFragment.java +++ /dev/null @@ -1,308 +0,0 @@ -package com.cappielloantonio.tempo.ui.fragment; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.media3.common.util.UnstableApi; -import androidx.navigation.Navigation; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; - -import com.cappielloantonio.tempo.R; -import com.cappielloantonio.tempo.databinding.FragmentLibraryBinding; -import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper; -import com.cappielloantonio.tempo.interfaces.ClickCallback; -import com.cappielloantonio.tempo.ui.activity.MainActivity; -import com.cappielloantonio.tempo.ui.adapter.AlbumAdapter; -import com.cappielloantonio.tempo.ui.adapter.ArtistAdapter; -import com.cappielloantonio.tempo.ui.adapter.GenreAdapter; -import com.cappielloantonio.tempo.ui.adapter.MusicFolderAdapter; -import com.cappielloantonio.tempo.ui.adapter.PlaylistHorizontalAdapter; -import com.cappielloantonio.tempo.ui.dialog.PlaylistEditorDialog; -import com.cappielloantonio.tempo.util.Constants; -import com.cappielloantonio.tempo.viewmodel.LibraryViewModel; -import com.google.android.gms.cast.framework.CastButtonFactory; - -import java.util.Objects; - -@UnstableApi -public class LibraryFragment extends Fragment implements ClickCallback { - private static final String TAG = "LibraryFragment"; - - private FragmentLibraryBinding bind; - private MainActivity activity; - private LibraryViewModel libraryViewModel; - - private MusicFolderAdapter musicFolderAdapter; - private AlbumAdapter albumAdapter; - private ArtistAdapter artistAdapter; - private GenreAdapter genreAdapter; - - private PlaylistHorizontalAdapter playlistHorizontalAdapter; - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.main_page_menu, menu); - CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.media_route_menu_item); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - activity = (MainActivity) getActivity(); - - bind = FragmentLibraryBinding.inflate(inflater, container, false); - View view = bind.getRoot(); - libraryViewModel = new ViewModelProvider(requireActivity()).get(LibraryViewModel.class); - - init(); - - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - initAppBar(); - initMusicFolderView(); - initAlbumView(); - initArtistView(); - initGenreView(); - initPlaylistSlideView(); - } - - @Override - public void onStart() { - super.onStart(); - activity.setBottomNavigationBarVisibility(true); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - bind = null; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_search) { - activity.navController.navigate(R.id.action_libraryFragment_to_searchFragment); - return true; - } else if (item.getItemId() == R.id.action_settings) { - activity.navController.navigate(R.id.action_libraryFragment_to_settingsFragment); - return true; - } - - return false; - } - - private void init() { - bind.albumCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_albumCatalogueFragment)); - bind.artistCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_artistCatalogueFragment)); - bind.genreCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_genreCatalogueFragment)); - bind.playlistCatalogueTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.PLAYLIST_ALL, Constants.PLAYLIST_ALL); - activity.navController.navigate(R.id.action_libraryFragment_to_playlistCatalogueFragment, bundle); - }); - - bind.albumCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshAlbumSample(getViewLifecycleOwner()); - return true; - }); - bind.artistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshArtistSample(getViewLifecycleOwner()); - return true; - }); - bind.genreCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshGenreSample(getViewLifecycleOwner()); - return true; - }); - bind.playlistCatalogueSampleTextViewRefreshable.setOnLongClickListener(view -> { - libraryViewModel.refreshPlaylistSample(getViewLifecycleOwner()); - return true; - }); - } - - private void initAppBar() { - activity.setSupportActionBar(bind.toolbar); - Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); - } - - private void initMusicFolderView() { - bind.musicFolderRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); - bind.musicFolderRecyclerView.setHasFixedSize(true); - - musicFolderAdapter = new MusicFolderAdapter(this); - bind.musicFolderRecyclerView.setAdapter(musicFolderAdapter); - libraryViewModel.getMusicFolders(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), musicFolders -> { - if (musicFolders == null) { - if (bind != null) - bind.libraryMusicFolderPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryMusicFolderSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.libraryMusicFolderPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryMusicFolderSector.setVisibility(!musicFolders.isEmpty() ? View.VISIBLE : View.GONE); - - musicFolderAdapter.setItems(musicFolders); - } - }); - } - - private void initAlbumView() { - bind.albumRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.albumRecyclerView.setHasFixedSize(true); - - albumAdapter = new AlbumAdapter(this); - bind.albumRecyclerView.setAdapter(albumAdapter); - libraryViewModel.getAlbumSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { - if (albums == null) { - if (bind != null) - bind.libraryAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryAlbumSector.setVisibility(View.GONE); - } else { - if (bind != null) bind.libraryAlbumPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryAlbumSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); - - albumAdapter.setItems(albums); - } - }); - - CustomLinearSnapHelper albumSnapHelper = new CustomLinearSnapHelper(); - albumSnapHelper.attachToRecyclerView(bind.albumRecyclerView); - } - - private void initArtistView() { - bind.artistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.artistRecyclerView.setHasFixedSize(true); - - artistAdapter = new ArtistAdapter(this, false, false); - bind.artistRecyclerView.setAdapter(artistAdapter); - libraryViewModel.getArtistSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { - if (artists == null) { - if (bind != null) - bind.libraryArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryArtistSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.libraryArtistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); - - artistAdapter.setItems(artists); - } - }); - - CustomLinearSnapHelper artistSnapHelper = new CustomLinearSnapHelper(); - artistSnapHelper.attachToRecyclerView(bind.artistRecyclerView); - } - - private void initGenreView() { - bind.genreRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3, GridLayoutManager.HORIZONTAL, false)); - bind.genreRecyclerView.setHasFixedSize(true); - - genreAdapter = new GenreAdapter(this); - bind.genreRecyclerView.setAdapter(genreAdapter); - - libraryViewModel.getGenreSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), genres -> { - if (genres == null) { - if (bind != null) - bind.libraryGenrePlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryGenresSector.setVisibility(View.GONE); - } else { - if (bind != null) bind.libraryGenrePlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryGenresSector.setVisibility(!genres.isEmpty() ? View.VISIBLE : View.GONE); - - genreAdapter.setItems(genres); - } - }); - - CustomLinearSnapHelper genreSnapHelper = new CustomLinearSnapHelper(); - genreSnapHelper.attachToRecyclerView(bind.genreRecyclerView); - } - - private void initPlaylistSlideView() { - bind.playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); - bind.playlistRecyclerView.setHasFixedSize(true); - - playlistHorizontalAdapter = new PlaylistHorizontalAdapter(this); - bind.playlistRecyclerView.setAdapter(playlistHorizontalAdapter); - libraryViewModel.getPlaylistSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), playlists -> { - if (playlists == null) { - if (bind != null) - bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.libraryPlaylistSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.libraryPlaylistSector.setVisibility(!playlists.isEmpty() ? View.VISIBLE : View.GONE); - - playlistHorizontalAdapter.setItems(playlists); - } - }); - } - - @Override - public void onAlbumClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); - } - - @Override - public void onAlbumLongClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); - } - - @Override - public void onArtistClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); - } - - @Override - public void onArtistLongClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); - } - - @Override - public void onGenreClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.songListPageFragment, bundle); - } - - @Override - public void onPlaylistClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle); - } - - @Override - public void onPlaylistLongClick(Bundle bundle) { - PlaylistEditorDialog dialog = new PlaylistEditorDialog(); - dialog.setArguments(bundle); - dialog.show(activity.getSupportFragmentManager(), null); - } - - @Override - public void onMusicFolderClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.indexFragment, bundle); - } -} diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/ToolbarFragment.java b/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/ToolbarFragment.java new file mode 100644 index 00000000..d3f36bb7 --- /dev/null +++ b/app/src/tempo/java/com/cappielloantonio/tempo/ui/fragment/ToolbarFragment.java @@ -0,0 +1,67 @@ +package com.cappielloantonio.tempo.ui.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.media3.common.util.UnstableApi; + +import com.cappielloantonio.tempo.R; +import com.cappielloantonio.tempo.databinding.FragmentToolbarBinding; +import com.cappielloantonio.tempo.ui.activity.MainActivity; +import com.google.android.gms.cast.framework.CastButtonFactory; + +@UnstableApi +public class ToolbarFragment extends Fragment { + private static final String TAG = "ToolbarFragment"; + + private FragmentToolbarBinding bind; + private MainActivity activity; + + public ToolbarFragment() { + // Required empty public constructor + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.main_page_menu, menu); + CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.media_route_menu_item); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + activity = (MainActivity) getActivity(); + + bind = FragmentToolbarBinding.inflate(inflater, container, false); + View view = bind.getRoot(); + + return view; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_search) { + activity.navController.navigate(R.id.searchFragment); + return true; + } else if (item.getItemId() == R.id.action_settings) { + activity.navController.navigate(R.id.settingsFragment); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/util/Flavors.java b/app/src/tempo/java/com/cappielloantonio/tempo/util/Flavors.java new file mode 100644 index 00000000..4bed2921 --- /dev/null +++ b/app/src/tempo/java/com/cappielloantonio/tempo/util/Flavors.java @@ -0,0 +1,14 @@ +package com.cappielloantonio.tempo.util; + +import android.content.Context; + +import com.google.android.gms.cast.framework.CastContext; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +public class Flavors { + public static void initializeCastContext(Context context) { + if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS) + CastContext.getSharedInstance(context); + } +} diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/util/UIUtil.java b/app/src/tempo/java/com/cappielloantonio/tempo/util/UIUtil.java deleted file mode 100644 index 99a37eb5..00000000 --- a/app/src/tempo/java/com/cappielloantonio/tempo/util/UIUtil.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.cappielloantonio.tempo.util; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.InsetDrawable; - -import androidx.recyclerview.widget.DividerItemDecoration; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; - -public class UIUtil { - public static int getSpanCount(int itemCount, int maxSpan) { - int itemSize = itemCount == 0 ? 1 : itemCount; - - if (itemSize / maxSpan > 0) { - return maxSpan; - } else { - return itemSize % maxSpan; - } - } - - public static boolean isCastApiAvailable(Context context) { - return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS; - } - - public static DividerItemDecoration getDividerItemDecoration(Context context) { - int[] ATTRS = new int[]{android.R.attr.listDivider}; - - TypedArray a = context.obtainStyledAttributes(ATTRS); - Drawable divider = a.getDrawable(0); - InsetDrawable insetDivider = new InsetDrawable(divider, 42, 0, 42, 42); - a.recycle(); - - DividerItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL); - itemDecoration.setDrawable(insetDivider); - - return itemDecoration; - } -}