Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.d4rk.androidtutorials.java.data.repository;

import android.content.Intent;

import com.d4rk.androidtutorials.java.data.source.HomeLocalDataSource;
import com.d4rk.androidtutorials.java.data.source.HomeRemoteDataSource;
import com.d4rk.androidtutorials.java.data.source.HomeRemoteDataSource.PromotedAppsCallback;

/**
* Default implementation of {@link HomeRepository} combining local and remote sources.
*/
public class DefaultHomeRepository implements HomeRepository {

private final HomeRemoteDataSource remoteDataSource;
private final HomeLocalDataSource localDataSource;

public DefaultHomeRepository(HomeRemoteDataSource remoteDataSource,
HomeLocalDataSource localDataSource) {
this.remoteDataSource = remoteDataSource;
this.localDataSource = localDataSource;
}

@Override
public Intent getPlayStoreIntent() {
return localDataSource.getPlayStoreIntent();
}

@Override
public Intent getAppPlayStoreIntent(String packageName) {
return localDataSource.getAppPlayStoreIntent(packageName);
}

@Override
public String getDailyTip() {
return localDataSource.getDailyTip();
}

@Override
public void fetchPromotedApps(PromotedAppsCallback callback) {
remoteDataSource.fetchPromotedApps(callback);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.d4rk.androidtutorials.java.data.repository;

import com.d4rk.androidtutorials.java.data.model.QuizQuestion;
import com.d4rk.androidtutorials.java.data.source.QuizLocalDataSource;

import java.util.List;

/**
* Default implementation of {@link QuizRepository} using a local data source.
*/
public class DefaultQuizRepository implements QuizRepository {

private final QuizLocalDataSource localDataSource;

public DefaultQuizRepository(QuizLocalDataSource localDataSource) {
this.localDataSource = localDataSource;
}

@Override
public List<QuizQuestion> loadQuestions() {
return localDataSource.loadQuestions();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.d4rk.androidtutorials.java.data.repository;

import android.content.Intent;

import com.d4rk.androidtutorials.java.data.model.PromotedApp;
import com.d4rk.androidtutorials.java.data.source.HomeRemoteDataSource.PromotedAppsCallback;

/**
* Abstraction over home data operations.
*/
public interface HomeRepository {

Intent getPlayStoreIntent();

Intent getAppPlayStoreIntent(String packageName);

String getDailyTip();

void fetchPromotedApps(PromotedAppsCallback callback);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.d4rk.androidtutorials.java.data.repository;

import com.d4rk.androidtutorials.java.data.model.QuizQuestion;

import java.util.List;

/**
* Abstraction over quiz data operations.
*/
public interface QuizRepository {
List<QuizQuestion> loadQuestions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.d4rk.androidtutorials.java.data.source;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;

import com.d4rk.androidtutorials.java.R;

/**
* Default implementation that reads from Android resources.
*/
public class DefaultHomeLocalDataSource implements HomeLocalDataSource {

private final Context context;

public DefaultHomeLocalDataSource(Context context) {
this.context = context.getApplicationContext();
}

@Override
public Intent getPlayStoreIntent() {
String playStoreUrl = "https://play.google.com/store/apps/details?id=com.d4rk.androidtutorials";
return buildPlayStoreIntent(playStoreUrl);
}

@Override
public Intent getAppPlayStoreIntent(String packageName) {
String url = "https://play.google.com/store/apps/details?id=" + packageName;
return buildPlayStoreIntent(url);
}

@Override
public String getDailyTip() {
String[] tips = context.getResources().getStringArray(R.array.daily_tips);
long daysSinceEpoch = System.currentTimeMillis() / (24L * 60 * 60 * 1000);
int index = (int) (daysSinceEpoch % tips.length);
return tips[index];
}

private Intent buildPlayStoreIntent(String url) {
Intent playStoreIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
playStoreIntent.setPackage("com.android.vending");
if (playStoreIntent.resolveActivity(context.getPackageManager()) != null) {
return playStoreIntent;
}
return new Intent(Intent.ACTION_VIEW, Uri.parse(url));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.d4rk.androidtutorials.java.data.source;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.JsonObjectRequest;
import com.d4rk.androidtutorials.java.data.model.PromotedApp;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Volley based implementation of {@link HomeRemoteDataSource}.
*/
public class DefaultHomeRemoteDataSource implements HomeRemoteDataSource {

private final RequestQueue requestQueue;
private final String apiUrl;

public DefaultHomeRemoteDataSource(RequestQueue requestQueue, String apiUrl) {
this.requestQueue = requestQueue;
this.apiUrl = apiUrl;
}

@Override
public void fetchPromotedApps(PromotedAppsCallback callback) {
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.GET,
apiUrl,
null,
response -> {
List<PromotedApp> result = new ArrayList<>();
try {
JSONArray apps = response.getJSONObject("data").getJSONArray("apps");
for (int i = 0; i < apps.length(); i++) {
JSONObject obj = apps.getJSONObject(i);
String pkg = obj.getString("packageName");
if (pkg.contains("com.d4rk.androidtutorials")) {
continue;
}
result.add(new PromotedApp(
obj.getString("name"),
pkg,
obj.getString("iconLogo")
));
}
} catch (JSONException e) {
result = Collections.emptyList();
}
callback.onResult(result);
},
error -> callback.onResult(Collections.emptyList())
);
requestQueue.add(request);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.d4rk.androidtutorials.java.ui.screens.quiz.repository;
package com.d4rk.androidtutorials.java.data.source;

import android.content.Context;
import android.content.res.AssetManager;

import com.d4rk.androidtutorials.java.data.model.QuizQuestion;

Expand All @@ -16,25 +16,21 @@
import java.util.List;

/**
* Repository responsible for loading quiz question data from JSON assets.
* Reads quiz questions from the assets folder.
*/
public class QuizRepository {
public class DefaultQuizLocalDataSource implements QuizLocalDataSource {

private final Context context;
private final AssetManager assetManager;

public QuizRepository(Context context) {
this.context = context.getApplicationContext();
public DefaultQuizLocalDataSource(AssetManager assetManager) {
this.assetManager = assetManager;
}

/**
* Loads the quiz questions from the assets folder.
*/
@Override
public List<QuizQuestion> loadQuestions() {
try {
InputStream is = context.getAssets().open("quiz_questions.json");
try (InputStream is = assetManager.open("quiz_questions.json")) {
byte[] buffer = new byte[is.available()];
int read = is.read(buffer);
is.close();
String json = new String(buffer, 0, read, StandardCharsets.UTF_8);
JSONArray array = new JSONArray(json);
List<QuizQuestion> result = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.d4rk.androidtutorials.java.data.source;

import android.content.Intent;

/**
* Local data access for the home feature.
*/
public interface HomeLocalDataSource {

Intent getPlayStoreIntent();

Intent getAppPlayStoreIntent(String packageName);

String getDailyTip();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.d4rk.androidtutorials.java.data.source;

import com.d4rk.androidtutorials.java.data.model.PromotedApp;

import java.util.List;

/**
* Contract for fetching home screen data from remote sources.
*/
public interface HomeRemoteDataSource {

interface PromotedAppsCallback {
void onResult(List<PromotedApp> apps);
}

void fetchPromotedApps(PromotedAppsCallback callback);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.d4rk.androidtutorials.java.data.source;

import com.d4rk.androidtutorials.java.data.model.QuizQuestion;

import java.util.List;

/**
* Contract for reading quiz data from local storage.
*/
public interface QuizLocalDataSource {
List<QuizQuestion> loadQuestions();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.d4rk.androidtutorials.java.domain.home;

import com.d4rk.androidtutorials.java.ui.screens.home.repository.HomeRepository;
import com.d4rk.androidtutorials.java.data.repository.HomeRepository;

/** Use case that provides the daily tip text. */
public class GetDailyTipUseCase {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.d4rk.androidtutorials.java.domain.home;

import com.d4rk.androidtutorials.java.data.model.PromotedApp;
import com.d4rk.androidtutorials.java.ui.screens.home.repository.HomeRepository;
import com.d4rk.androidtutorials.java.data.repository.HomeRepository;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.d4rk.androidtutorials.java.domain.quiz;

import com.d4rk.androidtutorials.java.data.model.QuizQuestion;
import com.d4rk.androidtutorials.java.ui.screens.quiz.repository.QuizRepository;
import com.d4rk.androidtutorials.java.data.repository.QuizRepository;
import java.util.List;

/** Loads quiz questions from assets. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.android.volley.toolbox.Volley;
import com.d4rk.androidtutorials.java.R;
import com.d4rk.androidtutorials.java.data.model.PromotedApp;
import com.d4rk.androidtutorials.java.ui.screens.home.repository.HomeRepository;
import com.d4rk.androidtutorials.java.data.repository.DefaultHomeRepository;
import com.d4rk.androidtutorials.java.data.repository.HomeRepository;
import com.d4rk.androidtutorials.java.data.source.DefaultHomeLocalDataSource;
import com.d4rk.androidtutorials.java.data.source.DefaultHomeRemoteDataSource;
import com.d4rk.androidtutorials.java.data.source.HomeLocalDataSource;
import com.d4rk.androidtutorials.java.data.source.HomeRemoteDataSource;
import com.d4rk.androidtutorials.java.domain.home.GetDailyTipUseCase;
import com.d4rk.androidtutorials.java.domain.home.GetPromotedAppsUseCase;

Expand All @@ -31,7 +37,12 @@ public class HomeViewModel extends AndroidViewModel {

public HomeViewModel(@NonNull Application application) {
super(application);
homeRepository = new HomeRepository(application);
HomeRemoteDataSource remote = new DefaultHomeRemoteDataSource(
Volley.newRequestQueue(application),
"https://raw.githubusercontent.com/D4rK7355608/com.d4rk.apis/refs/heads/main/App%20Toolkit/release/en/home/api_android_apps.json"
);
HomeLocalDataSource local = new DefaultHomeLocalDataSource(application);
homeRepository = new DefaultHomeRepository(remote, local);
getDailyTipUseCase = new GetDailyTipUseCase(homeRepository);
getPromotedAppsUseCase = new GetPromotedAppsUseCase(homeRepository);

Expand Down
Loading