Skip to content

Commit c3aa4e7

Browse files
brais-fProfpatsch
authored andcommitted
Added the new compose screen with its components and events
1 parent 2eb85bd commit c3aa4e7

33 files changed

Lines changed: 1523 additions & 6 deletions

app/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,11 @@ dependencies {
310310
// Coroutines interop
311311
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx3:1.8.1'
312312

313-
// Hilt
313+
// Hilt & Dagger
314314
implementation("com.google.dagger:hilt-android:2.51.1")
315315
kapt("com.google.dagger:hilt-compiler:2.51.1")
316+
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
317+
kapt("androidx.hilt:hilt-compiler:1.2.0")
316318

317319
// Scroll
318320
implementation 'com.github.nanihadesuka:LazyColumnScrollbar:2.2.0'

app/src/main/java/org/schabi/newpipe/MainActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@
9494
import java.util.List;
9595
import java.util.Objects;
9696

97+
import dagger.hilt.android.AndroidEntryPoint;
98+
99+
@AndroidEntryPoint
97100
public class MainActivity extends AppCompatActivity {
98101
private static final String TAG = "MainActivity";
99102
@SuppressWarnings("ConstantConditions")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.schabi.newpipe.dependency_injection
2+
3+
import android.content.Context
4+
import android.content.SharedPreferences
5+
import androidx.preference.PreferenceManager
6+
import dagger.Module
7+
import dagger.Provides
8+
import dagger.hilt.InstallIn
9+
import dagger.hilt.android.qualifiers.ApplicationContext
10+
import dagger.hilt.components.SingletonComponent
11+
import org.schabi.newpipe.error.usecases.OpenErrorActivity
12+
import javax.inject.Singleton
13+
14+
@Module
15+
@InstallIn(SingletonComponent::class)
16+
object AppModule {
17+
@Provides
18+
@Singleton
19+
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
20+
PreferenceManager.getDefaultSharedPreferences(context)
21+
22+
@Provides
23+
@Singleton
24+
fun provideOpenActivity(
25+
@ApplicationContext context: Context,
26+
): OpenErrorActivity = OpenErrorActivity(context)
27+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.schabi.newpipe.dependency_injection
2+
3+
import android.content.Context
4+
import androidx.room.Room
5+
import dagger.Module
6+
import dagger.Provides
7+
import dagger.hilt.InstallIn
8+
import dagger.hilt.android.qualifiers.ApplicationContext
9+
import dagger.hilt.components.SingletonComponent
10+
import org.schabi.newpipe.database.AppDatabase
11+
import org.schabi.newpipe.database.AppDatabase.DATABASE_NAME
12+
import org.schabi.newpipe.database.Migrations.MIGRATION_1_2
13+
import org.schabi.newpipe.database.Migrations.MIGRATION_2_3
14+
import org.schabi.newpipe.database.Migrations.MIGRATION_3_4
15+
import org.schabi.newpipe.database.Migrations.MIGRATION_4_5
16+
import org.schabi.newpipe.database.Migrations.MIGRATION_5_6
17+
import org.schabi.newpipe.database.Migrations.MIGRATION_6_7
18+
import org.schabi.newpipe.database.Migrations.MIGRATION_7_8
19+
import org.schabi.newpipe.database.Migrations.MIGRATION_8_9
20+
import org.schabi.newpipe.database.history.dao.SearchHistoryDAO
21+
import org.schabi.newpipe.database.history.dao.StreamHistoryDAO
22+
import org.schabi.newpipe.database.stream.dao.StreamDAO
23+
import org.schabi.newpipe.database.stream.dao.StreamStateDAO
24+
import javax.inject.Singleton
25+
26+
@InstallIn(SingletonComponent::class)
27+
@Module
28+
class DatabaseModule {
29+
30+
@Provides
31+
@Singleton
32+
fun provideAppDatabase(@ApplicationContext appContext: Context): AppDatabase =
33+
Room.databaseBuilder(
34+
appContext,
35+
AppDatabase::class.java,
36+
DATABASE_NAME
37+
).addMigrations(
38+
MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5,
39+
MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9
40+
).build()
41+
42+
@Provides
43+
fun provideStreamStateDao(appDatabase: AppDatabase): StreamStateDAO =
44+
appDatabase.streamStateDAO()
45+
46+
@Provides
47+
fun providesStreamDao(appDatabase: AppDatabase): StreamDAO = appDatabase.streamDAO()
48+
49+
@Provides
50+
fun provideStreamHistoryDao(appDatabase: AppDatabase): StreamHistoryDAO =
51+
appDatabase.streamHistoryDAO()
52+
53+
@Provides
54+
fun provideSearchHistoryDao(appDatabase: AppDatabase): SearchHistoryDAO =
55+
appDatabase.searchHistoryDAO()
56+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.schabi.newpipe.error.usecases
2+
3+
import android.content.Context
4+
import android.content.Intent
5+
import org.schabi.newpipe.error.ErrorActivity
6+
import org.schabi.newpipe.error.ErrorInfo
7+
8+
class OpenErrorActivity(
9+
private val context: Context,
10+
) {
11+
operator fun invoke(errorInfo: ErrorInfo) {
12+
val intent = Intent(context, ErrorActivity::class.java)
13+
intent.putExtra(ErrorActivity.ERROR_INFO, errorInfo)
14+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
15+
16+
context.startActivity(intent)
17+
}
18+
}

app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import androidx.annotation.NonNull;
1515
import androidx.annotation.Nullable;
16+
import androidx.appcompat.app.AlertDialog;
1617
import androidx.viewbinding.ViewBinding;
1718

1819
import com.evernote.android.state.State;
@@ -27,6 +28,7 @@
2728
import org.schabi.newpipe.databinding.PlaylistControlBinding;
2829
import org.schabi.newpipe.databinding.StatisticPlaylistControlBinding;
2930
import org.schabi.newpipe.error.ErrorInfo;
31+
import org.schabi.newpipe.error.ErrorUtil;
3032
import org.schabi.newpipe.error.UserAction;
3133
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
3234
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
@@ -35,7 +37,6 @@
3537
import org.schabi.newpipe.local.BaseLocalListFragment;
3638
import org.schabi.newpipe.player.playqueue.PlayQueue;
3739
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
38-
import org.schabi.newpipe.settings.HistorySettingsFragment;
3940
import org.schabi.newpipe.util.NavigationHelper;
4041
import org.schabi.newpipe.util.OnClickGesture;
4142
import org.schabi.newpipe.util.PlayButtonHelper;
@@ -161,14 +162,72 @@ public void held(final LocalItem selectedItem) {
161162
@Override
162163
public boolean onOptionsItemSelected(final MenuItem item) {
163164
if (item.getItemId() == R.id.action_history_clear) {
164-
HistorySettingsFragment
165-
.openDeleteWatchHistoryDialog(requireContext(), recordManager, disposables);
165+
openDeleteWatchHistoryDialog(requireContext(), recordManager, disposables);
166166
} else {
167167
return super.onOptionsItemSelected(item);
168168
}
169169
return true;
170170
}
171171

172+
private static void openDeleteWatchHistoryDialog(
173+
@NonNull final Context context,
174+
final HistoryRecordManager recordManager,
175+
final CompositeDisposable disposables
176+
) {
177+
new AlertDialog.Builder(context)
178+
.setTitle(R.string.delete_view_history_alert)
179+
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
180+
.setPositiveButton(R.string.delete, ((dialog, which) -> {
181+
disposables.add(getDeletePlaybackStatesDisposable(context, recordManager));
182+
disposables.add(getWholeStreamHistoryDisposable(context, recordManager));
183+
disposables.add(getRemoveOrphanedRecordsDisposable(context, recordManager));
184+
}))
185+
.show();
186+
}
187+
188+
private static Disposable getDeletePlaybackStatesDisposable(
189+
@NonNull final Context context,
190+
final HistoryRecordManager recordManager
191+
) {
192+
return recordManager.deleteCompleteStreamStateHistory()
193+
.observeOn(AndroidSchedulers.mainThread())
194+
.subscribe(
195+
howManyDeleted -> Toast.makeText(context,
196+
R.string.watch_history_states_deleted, Toast.LENGTH_SHORT).show(),
197+
throwable -> ErrorUtil.openActivity(context,
198+
new ErrorInfo(throwable, UserAction.DELETE_FROM_HISTORY,
199+
"Delete playback states"))
200+
);
201+
}
202+
203+
private static Disposable getWholeStreamHistoryDisposable(
204+
@NonNull final Context context,
205+
final HistoryRecordManager recordManager
206+
) {
207+
return recordManager.deleteWholeStreamHistory()
208+
.observeOn(AndroidSchedulers.mainThread())
209+
.subscribe(
210+
howManyDeleted -> Toast.makeText(context,
211+
R.string.watch_history_deleted, Toast.LENGTH_SHORT).show(),
212+
throwable -> ErrorUtil.openActivity(context,
213+
new ErrorInfo(throwable, UserAction.DELETE_FROM_HISTORY,
214+
"Delete from history"))
215+
);
216+
}
217+
218+
private static Disposable getRemoveOrphanedRecordsDisposable(
219+
@NonNull final Context context, final HistoryRecordManager recordManager) {
220+
return recordManager.removeOrphanedRecords()
221+
.observeOn(AndroidSchedulers.mainThread())
222+
.subscribe(
223+
howManyDeleted -> {
224+
},
225+
throwable -> ErrorUtil.openActivity(context,
226+
new ErrorInfo(throwable, UserAction.DELETE_FROM_HISTORY,
227+
"Clear orphaned records"))
228+
);
229+
}
230+
172231
///////////////////////////////////////////////////////////////////////////
173232
// Fragment LifeCycle - Loading
174233
///////////////////////////////////////////////////////////////////////////
@@ -307,7 +366,7 @@ private void toggleSortMode() {
307366
sortMode = StatisticSortMode.LAST_PLAYED;
308367
setTitle(getString(R.string.title_last_played));
309368
headerBinding.sortButtonIcon.setImageResource(
310-
R.drawable.ic_filter_list);
369+
R.drawable.ic_filter_list);
311370
headerBinding.sortButtonText.setText(R.string.title_most_played);
312371
}
313372
startLoading(true);

app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343

4444
import java.util.concurrent.TimeUnit;
4545

46+
import dagger.hilt.android.AndroidEntryPoint;
47+
48+
4649
/*
4750
* Created by Christian Schabesberger on 31.08.15.
4851
*
@@ -63,6 +66,7 @@
6366
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
6467
*/
6568

69+
@AndroidEntryPoint
6670
public class SettingsActivity extends AppCompatActivity implements
6771
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback,
6872
PreferenceSearchResultListener {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package org.schabi.newpipe.settings.components.irreversible_preference
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.Spacer
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.material3.MaterialTheme
10+
import androidx.compose.material3.Text
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.runtime.derivedStateOf
13+
import androidx.compose.runtime.getValue
14+
import androidx.compose.runtime.remember
15+
import androidx.compose.ui.Alignment
16+
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.draw.alpha
18+
import androidx.compose.ui.tooling.preview.Preview
19+
import org.schabi.newpipe.ui.theme.AppTheme
20+
import org.schabi.newpipe.ui.theme.SizeTokens.SpacingExtraSmall
21+
import org.schabi.newpipe.ui.theme.SizeTokens.SpacingMedium
22+
23+
@Composable
24+
fun IrreversiblePreferenceComponent(
25+
title: String,
26+
summary: String,
27+
onClick: () -> Unit,
28+
modifier: Modifier = Modifier,
29+
enabled: Boolean = true,
30+
) {
31+
val clickModifier = if (enabled) {
32+
Modifier.clickable { onClick() }
33+
} else {
34+
Modifier
35+
}
36+
Row(
37+
modifier = clickModifier.then(modifier),
38+
verticalAlignment = Alignment.CenterVertically,
39+
) {
40+
val alpha by remember {
41+
derivedStateOf {
42+
if (enabled) 1f else 0.38f
43+
}
44+
}
45+
Column(
46+
modifier = Modifier.padding(SpacingMedium)
47+
) {
48+
Text(
49+
text = title,
50+
modifier = Modifier.alpha(alpha),
51+
)
52+
Spacer(modifier = Modifier.padding(SpacingExtraSmall))
53+
Text(
54+
text = summary,
55+
style = MaterialTheme.typography.labelSmall,
56+
modifier = Modifier.alpha(alpha * 0.6f),
57+
)
58+
}
59+
}
60+
}
61+
62+
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
63+
@Composable
64+
private fun IrreversiblePreferenceComponentPreview() {
65+
val title = "Wipe cached metadata"
66+
val summary = "Remove all cached webpage data"
67+
AppTheme {
68+
Column {
69+
70+
IrreversiblePreferenceComponent(
71+
title = title,
72+
summary = summary,
73+
onClick = {},
74+
modifier = Modifier.fillMaxWidth()
75+
)
76+
IrreversiblePreferenceComponent(
77+
title = title,
78+
summary = summary,
79+
onClick = {},
80+
modifier = Modifier.fillMaxWidth(),
81+
enabled = false
82+
)
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)