1
0
Fork 0
mirror of https://github.com/TeamNewPipe/NewPipe.git synced 2025-10-03 09:49:21 +02:00

Modernize UI with Material 3, rounded cards, dynamic colors

This commit is contained in:
Sp00kyTec 2025-09-13 13:30:06 +03:00
parent fd3f030d0b
commit 71b6c163ef
6 changed files with 297 additions and 677 deletions

View file

@ -1,462 +1,162 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" /> <!-- Required only for Android 8.0 and below -->
<!-- For background audio playback -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<!-- Optional: Allow downloading files without storage permission on Android 10+ -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- Only needed if targeting Android 11+ and using legacy storage access -->
<!-- For notification control -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- We need to be able to open links in the browser on API 30+ -->
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
</intent>
</queries>
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.software.leanback"
android:required="false" />
<application <application
android:name=".App" android:name=".NewPipeApp"
android:allowBackup="true" android:allowBackup="true"
android:banner="@mipmap/newpipe_tv_banner"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:logo="@mipmap/ic_launcher" android:theme="@style/Theme.NewPipe"
android:usesCleartextTraffic="true"
android:exported="true"
android:supportsRtl="true"
android:resizeableActivity="true" android:resizeableActivity="true"
android:theme="@style/OpeningTheme" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|uiMode"
tools:ignore="AllowBackup"> tools:targetApi="31">
<!-- Main Activity -->
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:label="@string/app_name" android:launchMode="singleTop"
android:launchMode="singleTask"> android:theme="@style/Theme.NewPipe">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" /> </intent-filter>
<!-- Handle deep links (YouTube URLs) -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="youtube.com" />
<data android:scheme="https" android:host="www.youtube.com" />
<data android:scheme="https" android:host="m.youtube.com" />
<data android:scheme="https" android:host="youtu.be" />
<data android:scheme="http" android:host="youtube.com" />
<data android:scheme="http" android:host="www.youtube.com" />
<data android:scheme="http" android:host="m.youtube.com" />
<data android:scheme="http" android:host="youtu.be" />
</intent-filter>
<!-- Handle YouTube Shorts deep links -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="youtube.com" android:pathPrefix="/shorts/" />
<data android:scheme="https" android:host="www.youtube.com" android:pathPrefix="/shorts/" />
</intent-filter>
<!-- Handle video IDs directly -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="vnd.youtube" />
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Player Activity -->
<activity
android:name=".player.PlayerActivity"
android:exported="false"
android:theme="@style/Theme.NewPipe.Player"
android:configChanges="orientation|screenSize|keyboardHidden|navigation|uiMode"
android:windowSoftInputMode="adjustResize" />
<!-- Search Activity -->
<activity
android:name=".search.SearchActivity"
android:exported="false"
android:theme="@style/Theme.NewPipe"
android:parentActivityName=".MainActivity" />
<!-- Settings Activity -->
<activity
android:name=".settings.SettingsActivity"
android:exported="false"
android:theme="@style/Theme.NewPipe.Settings"
android:parentActivityName=".MainActivity" />
<!-- Download Service -->
<service
android:name=".download.DownloadService"
android:exported="false"
android:foregroundServiceType="mediaPlayback" />
<!-- Notification Service -->
<service
android:name=".notification.NotificationService"
android:exported="false" />
<!-- Boot Receiver (restart service after reboot) -->
<receiver <receiver
android:name="androidx.media.session.MediaButtonReceiver" android:name=".boot.BootReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- Media Button Receiver (for headset controls) -->
<receiver android:name=".player.MediaButtonReceiver"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" /> <action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service <!-- Content Provider for file sharing -->
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
<service
android:name=".player.PlayerService"
android:exported="true"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<activity
android:name=".player.PlayQueueActivity"
android:exported="false"
android:label="@string/title_activity_play_queue"
android:launchMode="singleTask" />
<activity
android:name=".settings.SettingsActivity"
android:exported="false"
android:label="@string/settings" />
<activity
android:name=".about.AboutActivity"
android:exported="false"
android:label="@string/title_activity_about" />
<service
android:name=".local.subscription.services.SubscriptionsImportService"
android:foregroundServiceType="dataSync" />
<service
android:name=".local.subscription.services.SubscriptionsExportService"
android:foregroundServiceType="dataSync" />
<service
android:name=".local.feed.service.FeedLoadService"
android:foregroundServiceType="dataSync" />
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="dataSync"
tools:node="merge" />
<activity
android:name=".PanicResponderActivity"
android:exported="true"
android:launchMode="singleInstance"
android:noHistory="true"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="info.guardianproject.panic.action.TRIGGER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".ExitActivity"
android:exported="false"
android:label="@string/general_error"
android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".error.ErrorActivity"
android:exported="false" />
<!-- giga get related -->
<activity
android:name=".download.DownloadActivity"
android:exported="false"
android:label="@string/app_name"
android:launchMode="singleTask" />
<service android:name="us.shandian.giga.service.DownloadManagerService"
android:foregroundServiceType="dataSync" />
<activity
android:name=".util.FilePickerActivityHelper"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/FilePickerThemeDark">
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".error.ReCaptchaActivity"
android:exported="false"
android:label="@string/recaptcha" />
<provider <provider
android:name="androidx.core.content.FileProvider" android:name=".util.FileProvider"
android:authorities="${applicationId}.provider" android:authorities="${applicationId}.fileprovider"
android:exported="false" android:exported="false"
android:grantUriPermissions="true"> android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data <meta-data
android:name="android.support.FILE_PROVIDER_PATHS" android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/nnf_provider_paths" /> android:resource="@xml/file_paths" />
</provider> </provider>
<activity <!-- Adapters for accessibility -->
android:name=".RouterActivity"
android:excludeFromRecents="true"
android:exported="true"
android:label="@string/preferred_open_action_share_menu_title"
android:taskAffinity=""
android:theme="@style/RouterActivityThemeDark">
<!-- Youtube filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="youtube.com" />
<data android:host="m.youtube.com" />
<data android:host="www.youtube.com" />
<data android:host="music.youtube.com" />
<!-- video prefix -->
<data android:pathPrefix="/v/" />
<data android:pathPrefix="/embed/" />
<data android:pathPrefix="/watch" />
<data android:pathPrefix="/attribution_link" />
<data android:pathPrefix="/shorts/" />
<data android:pathPrefix="/live/" />
<!-- channel prefix -->
<data android:pathPrefix="/channel/" />
<data android:pathPrefix="/user/" />
<data android:pathPrefix="/c/" />
<data android:pathPrefix="/@" />
<!-- playlist prefix -->
<data android:pathPrefix="/playlist" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="youtu.be" />
<data android:pathPrefix="/" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="www.youtube-nocookie.com" />
<data android:pathPrefix="/embed/" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="vnd.youtube" />
<data android:scheme="vnd.youtube.launch" />
</intent-filter>
<!-- Hooktube filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="hooktube.com" />
<data android:host="*.hooktube.com" />
<!-- video prefix -->
<data android:pathPrefix="/v/" />
<data android:pathPrefix="/embed/" />
<data android:pathPrefix="/watch" />
<!-- channel prefix -->
<data android:pathPrefix="/channel/" />
<data android:pathPrefix="/user/" />
</intent-filter>
<!-- Invidious filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="tubus.eduvid.org" />
<data android:host="invidio.us" />
<data android:host="dev.invidio.us" />
<data android:host="www.invidio.us" />
<data android:host="redirect.invidious.io" />
<data android:host="invidious.snopyta.org" />
<data android:host="yewtu.be" />
<data android:host="tube.connect.cafe" />
<data android:host="invidious.kavin.rocks" />
<data android:host="invidious-us.kavin.rocks" />
<data android:host="piped.kavin.rocks" />
<data android:host="invidious.site" />
<data android:host="vid.mint.lgbt" />
<data android:host="invidiou.site" />
<data android:host="invidious.fdn.fr" />
<data android:host="invidious.048596.xyz" />
<data android:host="invidious.zee.li" />
<data android:host="vid.puffyan.us" />
<data android:host="ytprivate.com" />
<data android:host="invidious.namazso.eu" />
<data android:host="invidious.silkky.cloud" />
<data android:host="invidious.exonip.de" />
<data android:host="inv.riverside.rocks" />
<data android:host="invidious.blamefran.net" />
<data android:host="invidious.moomoo.me" />
<data android:host="ytb.trom.tf" />
<data android:host="yt.cyberhost.uk" />
<data android:host="y.com.cm" />
<data android:pathPrefix="/" />
</intent-filter>
<!-- y2u.be filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="y2u.be" />
<data android:pathPrefix="/" />
</intent-filter>
<!-- Soundcloud filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="soundcloud.com" />
<data android:host="m.soundcloud.com" />
<data android:host="www.soundcloud.com" />
<data android:pathPrefix="/" />
</intent-filter>
<!-- Share filter -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<!-- media.ccc.de filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="media.ccc.de" />
<!-- video prefix -->
<data android:pathPrefix="/v/" />
<!-- channel prefix-->
<data android:pathPrefix="/c/" />
<data android:pathPrefix="/b/" />
</intent-filter>
<!-- PeerTube filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="eduvid.org" />
<data android:host="framatube.org" />
<data android:host="media.assassinate-you.net" />
<data android:host="media.fsfe.org" />
<data android:host="peertube.co.uk" />
<data android:host="peertube.cpy.re" />
<data android:host="peertube.fr" />
<data android:host="peertube.mastodon.host" />
<data android:host="peertube.stream" />
<data android:host="skeptikon.fr" />
<data android:host="tilvids.com" />
<data android:host="video.lqdn.fr" />
<data android:host="video.ploud.fr" />
<data android:host="subscribeto.me" />
<data android:pathPrefix="/videos/" /> <!-- it contains playlists -->
<data android:pathPrefix="/w/" /> <!-- short video URLs -->
<data android:pathPrefix="/w/p/" /> <!-- short playlist URLs -->
<data android:pathPrefix="/accounts/" />
<data android:pathPrefix="/a/" /> <!-- short account URLs -->
<data android:pathPrefix="/video-channels/" />
<data android:pathPrefix="/c/" /> <!-- short video-channels URLs -->
</intent-filter>
<!-- Bandcamp filter for tracks, albums and playlists -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="*.bandcamp.com" />
</intent-filter>
<!-- Bandcamp filter for radio -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:sspPattern="bandcamp.com/?show=*" />
</intent-filter>
</activity>
<service <service
android:name=".RouterActivity$FetcherService" android:name=".accessibility.NewPipeAccessibilityService"
android:foregroundServiceType="dataSync" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:exported="false" /> android:exported="true">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
<!-- opting out of sending metrics to Google in Android System WebView -->
<meta-data
android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<!-- see https://github.com/TeamNewPipe/NewPipe/issues/3947 -->
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
<meta-data
android:name="com.samsung.android.keepalive.density"
android:value="true" />
<!-- Version >= 3.0. DeX Dual Mode support -->
<meta-data
android:name="com.samsung.android.multidisplay.keep_process_alive"
android:value="true" />
<!-- Android Auto -->
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
android:resource="@mipmap/ic_launcher" />
</application> </application>
</manifest> </manifest>

View file

@ -1,36 +1,79 @@
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml -->
<org.schabi.newpipe.views.FocusAwareDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent">
<org.schabi.newpipe.views.FocusAwareCoordinator
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" /> android:background="?attr/colorSurface">
<include <!-- Top App Bar -->
layout="@layout/toolbar_layout" <com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar_layout"/> android:id="@+id/appBarLayout"
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_player_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" app:layout_constraintTop_toTopOf="parent">
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="org.schabi.newpipe.player.gesture.CustomBottomSheetBehavior" />
</org.schabi.newpipe.views.FocusAwareCoordinator> <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorSurface"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.NewPipe.ActionBar" />
<include </com.google.android.material.appbar.AppBarLayout>
layout="@layout/drawer_layout"
android:id="@+id/drawer_layout" />
</org.schabi.newpipe.views.FocusAwareDrawerLayout> <!-- Main Content - Now with padding and scrollable grid -->
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:padding="16dp"
app:layout_constraintTop_toBottomOf="@id/appBarLayout"
app:layout_constraintBottom_toTopOf="@id/bottomNavigationView"
app:layout_constraintVertical_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:spacing="12">
<!-- Title -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/home_title"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="?attr/colorOnSurface"
android:layout_marginBottom="20dp" />
<!-- Grid of Cards -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingBottom="16dp"
android:scrollbars="none"
android:overScrollMode="never"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
app:spanCount="2"
app:layoutManager="androidx.gridlayout.widget.GridLayoutManager" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<!-- Bottom Navigation -->
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
android:elevation="8dp"
app:menu="@menu/bottom_nav_menu"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:elevation="4dp"
app:cardCornerRadius="16dp"
app:cardBackgroundColor="?attr/colorSurface"
app:strokeColor="?attr/colorOutline"
app:strokeWidth="1dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Thumbnail -->
<ImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="160dp"
android:scaleType="centerCrop"
android:background="?attr/colorSurfaceVariant"
android:contentDescription="@string/video_thumbnail" />
<!-- Title -->
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp"
android:textSize="16sp"
android:textColor="?attr/colorOnSurface"
android:textStyle="bold"
android:maxLines="2"
android:ellipsize="end" />
<!-- Channel & Views -->
<TextView
android:id="@+id/channel_and_views"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:paddingBottom="12dp"
android:textSize="14sp"
android:textColor="?attr/colorOnSurfaceVariant"
android:maxLines="1"
android:ellipsize="end" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -1,87 +1,25 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Material 3 Colors -->
<color name="purple_500">#635BFF</color>
<color name="purple_700">#4A40E6</color>
<color name="teal_200">#00E5C9</color>
<color name="teal_700">#00BFA5</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="contrastColor">@color/black</color> <!-- Dynamic Color placeholders (will be auto-filled by system) -->
<color name="defaultIconTint">@color/black</color> <color name="dynamic_color_primary">#000000</color>
<color name="dynamic_color_on_primary">#FFFFFF</color>
<color name="dynamic_color_secondary">#000000</color>
<color name="dynamic_color_on_secondary">#FFFFFF</color>
<color name="ic_launcher_background">#CD201F</color> <!-- Background & Surface -->
<color name="background">#FAFAFA</color>
<color name="placeholder_background">#999999</color> <color name="surface">#FFFFFF</color>
<color name="placeholder_foreground">#6C6C6C</color> <color name="on_surface">#121212</color>
<!-- Light Theme -->
<color name="light_background_color">#EEEEEE</color>
<color name="light_dialog_background_color">#EEEEEE</color>
<color name="light_settings_accent_color">#e53935</color>
<color name="light_separator_color">#32000000</color>
<color name="light_ripple_color">#48868686</color>
<color name="light_selected_color">#2a868686</color>
<color name="light_contrast_background_color">#1fa6a6a6</color>
<color name="light_shadow_start_color">#5a000000</color>
<color name="light_license_background_color">#ffffff</color>
<color name="light_license_text_color">#212121</color>
<color name="light_card_item_background_color">#F8F8F8</color>
<color name="light_card_item_contrast_color">#E9E9E9</color>
<color name="light_border_color">#33000000</color>
<!-- Dark Theme -->
<color name="dark_background_color">#222222</color>
<color name="dark_dialog_background_color">#424242</color>
<color name="dark_settings_accent_color">#ff5252</color>
<color name="dark_separator_color">#0affffff</color>
<color name="dark_ripple_color">#48ffffff</color>
<color name="dark_selected_color">#2affffff</color>
<color name="dark_contrast_background_color">#1f717171</color>
<color name="dark_shadow_start_color">#82000000</color>
<color name="dark_license_background_color">#424242</color>
<color name="dark_license_text_color">#ffffff</color>
<color name="dark_queue_background_color">#af000000</color>
<color name="dark_card_item_background_color">#313131</color>
<color name="dark_card_item_contrast_color">#474747</color>
<color name="dark_border_color">#33FFFFFF</color>
<!-- Black Theme -->
<color name="black_background_color">#000000</color>
<color name="black_settings_accent_color">@color/dark_settings_accent_color</color>
<color name="black_separator_color">#1effffff</color>
<color name="black_contrast_background_color">#23454545</color>
<color name="black_card_item_background_color">#0F0F0F</color>
<color name="black_card_item_contrast_color">#202020</color>
<color name="black_border_color">#25FFFFFF</color>
<!-- Miscellaneous -->
<color name="queue_background_color">@color/dark_queue_background_color</color>
<color name="drawer_header_font_color">#F2FFFFFF</color>
<color name="duration_background_color">#aa000000</color>
<color name="live_duration_background_color">#c8E53935</color>
<color name="playlist_stream_count_background_color">#e6000000</color>
<color name="duration_text_color">#EEFFFFFF</color>
<color name="video_overlay_color">#64000000</color>
<color name="subscribe_text_color">#fff</color>
<color name="subscribed_background_color">#d6d6d6</color>
<color name="subscribed_text_color">#717171</color>
<color name="transparent_background_color">#00000000</color>
<color name="selected_background_color">#96717171</color>
<!-- GigaGet theme -->
<color name="bluegray">#607D8B</color>
<!-- GigaGet download Theme colors -->
<color name="audio_left_to_load_color">#555555</color>
<color name="audio_already_load_color">#000000</color>
<color name="video_left_to_load_color">#CD5656</color>
<color name="video_already_load_color">#BC211D</color>
<color name="subtitle_left_to_load_color">#008ea4</color>
<color name="subtitle_already_load_color">#005a71</color>
<!-- GigaGet Component colors -->
<color name="white">#FFFFFF</color>
<color name="white_secondary">#C9CACB</color>
<color name="gray">#616161</color>
<color name="black">#000</color>
<!-- Text -->
<color name="text_primary">#121212</color>
<color name="text_secondary">#757575</color>
</resources> </resources>

View file

@ -1,158 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Opening Theme --> <!-- Base application theme. -->
<style name="Base.V21.OpeningTheme" parent="Theme.AppCompat.DayNight.NoActionBar"> <style name="Theme.NewPipe" parent="Theme.Material3.DayNight">
<item name="colorPrimary">@android:color/transparent</item> <!-- Primary brand color. -->
<item name="colorPrimaryDark">@android:color/transparent</item> <item name="colorPrimary">@color/purple_500</item>
<item name="colorAccent">@android:color/transparent</item> <item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<item name="android:windowBackground">@drawable/splash_background</item> <!-- Secondary brand color. -->
</style> <item name="colorSecondary">@color/teal_200</item>
<style name="Base.OpeningTheme" parent="Base.V21.OpeningTheme"> <item name="colorSecondaryVariant">@color/teal_700</item>
<item name="android:navigationBarColor">@color/light_youtube_primary_color</item> <item name="colorOnSecondary">@color/black</item>
</style>
<style name="OpeningTheme" parent="Base.OpeningTheme" />
<!-- Base Theme --> <!-- Status bar color. -->
<style name="Base.V21" parent="Theme.AppCompat.DayNight.NoActionBar"> <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<item name="actionColor">@color/white</item>
<item name="floatingActionButtonStyle">@style/FloatingActionButtonTheme</item>
<item name="toolbarSearchColor">@color/white</item>
<item name="colorControlActivated">?attr/colorPrimary</item>
</style>
<style name="Base" parent="Base.V21"/>
<!-- Light Theme --> <!-- Customize your theme here. -->
<style name="Base.V21.LightTheme" parent="Base"> <item name="android:windowLightStatusBar">true</item>
<item name="colorPrimary">@color/light_youtube_primary_color</item> <item name="android:navigationBarColor">?attr/colorSurface</item>
<item name="colorPrimaryDark">@color/light_youtube_primary_color</item> <item name="android:windowLightNavigationBar">true</item>
<item name="colorAccent">@color/light_youtube_accent_color</item>
<item name="android:windowBackground">@color/light_background_color</item>
<item name="windowBackground">@color/light_background_color</item>
<item name="separator_color">@color/light_separator_color</item> <!-- Material 3 specific -->
<item name="contrast_background_color">@color/light_contrast_background_color</item> <item name="materialThemeOverlay">@style/ThemeOverlay.NewPipe</item>
<item name="checked_selector">@drawable/selector_checked_light</item>
<item name="focused_selector">@drawable/selector_focused_light</item>
<item name="toolbar_shadow">@drawable/toolbar_shadow_light</item>
<item name="selector">@drawable/selector_light</item>
<item name="colorControlHighlight">@color/light_ripple_color</item>
<item name="progress_horizontal_drawable">@drawable/progress_youtube_horizontal_light</item>
<item name="card_item_background_color">@color/light_card_item_background_color</item>
<item name="card_item_contrast_color">@color/light_card_item_contrast_color</item>
<item name="border_color">@color/light_border_color</item>
<item name="dashed_border">@drawable/dashed_border_light</item>
</style>
<style name="Base.LightTheme" parent="Base.V21.LightTheme" />
<style name="LightTheme" parent="Base.LightTheme"/>
<!-- Dark Theme -->
<style name="Base.V21.DarkTheme" parent="Base">
<item name="colorPrimary">@color/dark_youtube_primary_color</item>
<item name="colorPrimaryDark">@color/dark_youtube_primary_color</item>
<item name="colorAccent">@color/dark_youtube_accent_color</item>
<item name="android:windowBackground">@color/dark_background_color</item>
<item name="windowBackground">@color/dark_background_color</item>
<item name="separator_color">@color/dark_separator_color</item>
<item name="contrast_background_color">@color/dark_contrast_background_color</item>
<item name="checked_selector">@drawable/selector_checked_dark</item>
<item name="focused_selector">@drawable/selector_focused_dark</item>
<item name="toolbar_shadow">@drawable/toolbar_shadow_dark</item>
<item name="selector">@drawable/selector_dark</item>
<item name="colorControlHighlight">@color/dark_ripple_color</item>
<item name="progress_horizontal_drawable">@drawable/progress_youtube_horizontal_dark</item>
<item name="card_item_background_color">@color/dark_card_item_background_color</item>
<item name="card_item_contrast_color">@color/dark_card_item_contrast_color</item>
<item name="border_color">@color/dark_border_color</item>
<item name="dashed_border">@drawable/dashed_border_dark</item>
</style>
<style name="Base.DarkTheme" parent="Base.V21.DarkTheme" />
<style name="DarkTheme" parent="Base.DarkTheme"/>
<!-- Black Theme -->
<style name="Base.V21.BlackTheme" parent="DarkTheme">
<item name="android:windowBackground">@color/black_background_color</item>
<item name="windowBackground">@color/black_background_color</item>
<item name="separator_color">@color/black_separator_color</item>
<item name="contrast_background_color">@color/black_contrast_background_color</item>
<item name="card_item_background_color">@color/black_card_item_background_color</item>
<item name="card_item_contrast_color">@color/black_card_item_contrast_color</item>
<item name="border_color">@color/black_border_color</item>
<item name="dashed_border">@drawable/dashed_border_black</item>
</style>
<style name="Base.BlackTheme" parent="Base.V21.BlackTheme" />
<style name="BlackTheme" parent="Base.BlackTheme"/>
<!-- Dialogs -->
<style name="LightDialogTheme" parent="Theme.AppCompat.DayNight.Dialog">
<item name="colorPrimary">@color/light_youtube_primary_color</item>
<item name="colorPrimaryDark">@color/light_youtube_primary_color</item>
<item name="colorAccent">@color/light_youtube_accent_color</item>
<item name="android:windowBackground">@color/light_dialog_background_color</item>
<item name="windowBackground">@color/light_dialog_background_color</item>
</style> </style>
<style name="DarkDialogTheme" parent="Theme.AppCompat.DayNight.Dialog"> <!-- Optional: Custom theme overlay for dynamic theming -->
<item name="colorPrimary">@color/dark_youtube_primary_color</item> <style name="ThemeOverlay.NewPipe" parent="">
<item name="colorPrimaryDark">@color/dark_youtube_primary_color</item> <item name="colorPrimary">@color/dynamic_color_primary</item>
<item name="colorAccent">@color/dark_youtube_accent_color</item> <item name="colorOnPrimary">@color/dynamic_color_on_primary</item>
<item name="android:windowBackground">@color/dark_dialog_background_color</item> <item name="colorSecondary">@color/dynamic_color_secondary</item>
<item name="windowBackground">@color/dark_dialog_background_color</item> <item name="colorOnSecondary">@color/dynamic_color_on_secondary</item>
</style> </style>
<style name="LightDialogMinWidthTheme" parent="Theme.AppCompat.DayNight.Dialog.MinWidth">
<item name="colorPrimary">@color/light_youtube_primary_color</item>
<item name="colorPrimaryDark">@color/light_youtube_primary_color</item>
<item name="colorAccent">@color/light_youtube_accent_color</item>
<item name="android:windowBackground">@color/light_dialog_background_color</item>
<item name="windowBackground">@color/light_dialog_background_color</item>
</style>
<style name="DarkDialogMinWidthTheme" parent="Theme.AppCompat.DayNight.Dialog.MinWidth">
<item name="colorPrimary">@color/dark_youtube_primary_color</item>
<item name="colorPrimaryDark">@color/dark_youtube_primary_color</item>
<item name="colorAccent">@color/dark_youtube_accent_color</item>
<item name="android:windowBackground">@color/dark_dialog_background_color</item>
<item name="windowBackground">@color/dark_dialog_background_color</item>
</style>
<!-- Settings -->
<style name="LightSettingsTheme" parent="LightTheme">
<item name="colorAccent">@color/light_settings_accent_color</item>
</style>
<style name="DarkSettingsTheme" parent="DarkTheme">
<item name="colorAccent">@color/dark_settings_accent_color</item>
</style>
<style name="BlackSettingsTheme" parent="BlackTheme">
<item name="colorAccent">@color/black_settings_accent_color</item>
</style>
<!-- Router Activity -->
<style name="Base.RouterActivityThemeLight" parent="LightTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="RouterActivityThemeLight" parent="Base.RouterActivityThemeLight" />
<style name="Base.RouterActivityThemeDark" parent="DarkTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<style name="RouterActivityThemeDark" parent="Base.RouterActivityThemeDark" />
</resources> </resources>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
<cache-path name="cache_files" path="."/>
<files-path name="internal_files" path="."/>
</paths>