Compare commits

..

3 Commits

Author SHA1 Message Date
Balazs Toldi
55f4689984
Auto-complete feature for the login page
This commit adds an auto-complete feature to select the users instance. It fetches all the instances from lemmyverse.net so everyone can find their instance :)

Closes #38
2023-11-09 20:17:55 +01:00
Balazs Toldi
9f02969dd2
Add u/HostileEnemy to credits page
Seriously? Why wasn't this there in the first release?!
2023-11-09 19:19:31 +01:00
Balazs Toldi
fd833a65c5
Fix text issues on post detail activity post without preview page 2023-11-09 19:10:12 +01:00
15 changed files with 190 additions and 13 deletions

View File

@ -255,4 +255,13 @@ abstract class NetworkModule {
static LemmyPrivateMessageAPI provideLemmyPrivateMessageAPI(@Named("base") RetrofitHolder retrofit) { static LemmyPrivateMessageAPI provideLemmyPrivateMessageAPI(@Named("base") RetrofitHolder retrofit) {
return new LemmyPrivateMessageAPI(retrofit); return new LemmyPrivateMessageAPI(retrofit);
} }
@Provides
@Named("lemmyVerse")
@Singleton
static Retrofit provideLemmyVerseRetrofit(@Named("base") RetrofitHolder retrofit) {
return retrofit.getRetrofit().newBuilder()
.baseUrl(APIUtils.LEMMYVERSE_API_BASE_URI)
.build();
}
} }

View File

@ -488,7 +488,7 @@ public class LinkResolverActivity extends AppCompatActivity {
String authority = uri.getAuthority(); String authority = uri.getAuthority();
if(authority != null && (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app.link"))) { if(authority != null && (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app.link"))) {
openInCustomTabs(uri, pm, false); openInBrowser(uri, pm, false);
return; return;
} }

View File

@ -10,12 +10,14 @@ import android.text.Editable;
import android.util.Log; import android.util.Log;
import android.view.InflateException; import android.view.InflateException;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatAutoCompleteTextView;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.coordinatorlayout.widget.CoordinatorLayout;
@ -28,6 +30,8 @@ import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import javax.inject.Inject; import javax.inject.Inject;
@ -40,11 +44,15 @@ import eu.toldi.infinityforlemmy.Infinity;
import eu.toldi.infinityforlemmy.R; import eu.toldi.infinityforlemmy.R;
import eu.toldi.infinityforlemmy.RedditDataRoomDatabase; import eu.toldi.infinityforlemmy.RedditDataRoomDatabase;
import eu.toldi.infinityforlemmy.RetrofitHolder; import eu.toldi.infinityforlemmy.RetrofitHolder;
import eu.toldi.infinityforlemmy.adapters.CustomArrayAdapter;
import eu.toldi.infinityforlemmy.apis.LemmyAPI; import eu.toldi.infinityforlemmy.apis.LemmyAPI;
import eu.toldi.infinityforlemmy.asynctasks.ParseAndInsertNewAccount; import eu.toldi.infinityforlemmy.asynctasks.ParseAndInsertNewAccount;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper; import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
import eu.toldi.infinityforlemmy.customviews.slidr.Slidr; import eu.toldi.infinityforlemmy.customviews.slidr.Slidr;
import eu.toldi.infinityforlemmy.dto.AccountLoginDTO; import eu.toldi.infinityforlemmy.dto.AccountLoginDTO;
import eu.toldi.infinityforlemmy.lemmyverse.FetchInstancesListener;
import eu.toldi.infinityforlemmy.lemmyverse.LemmyInstance;
import eu.toldi.infinityforlemmy.lemmyverse.LemmyVerseFetchInstances;
import eu.toldi.infinityforlemmy.site.FetchSiteInfo; import eu.toldi.infinityforlemmy.site.FetchSiteInfo;
import eu.toldi.infinityforlemmy.site.SiteInfo; import eu.toldi.infinityforlemmy.site.SiteInfo;
import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils; import eu.toldi.infinityforlemmy.utils.SharedPreferencesUtils;
@ -69,7 +77,7 @@ public class LoginActivity extends BaseActivity {
TextView twoFAInfoTextView; TextView twoFAInfoTextView;
@BindView(R.id.instance_url_input) @BindView(R.id.instance_url_input)
TextInputEditText instance_input; AppCompatAutoCompleteTextView instance_input;
@BindView(R.id.username_input) @BindView(R.id.username_input)
TextInputEditText username_input; TextInputEditText username_input;
@BindView(R.id.user_password_input) @BindView(R.id.user_password_input)
@ -86,9 +94,11 @@ public class LoginActivity extends BaseActivity {
@Inject @Inject
@Named("no_oauth") @Named("no_oauth")
RetrofitHolder mRetrofit; RetrofitHolder mRetrofit;
@Inject @Inject
@Named("oauth") @Named("lemmyVerse")
Retrofit mOauthRetrofit; Retrofit mLemmyVerseRetrofit;
@Inject @Inject
RedditDataRoomDatabase mRedditDataRoomDatabase; RedditDataRoomDatabase mRedditDataRoomDatabase;
@Inject @Inject
@ -139,6 +149,20 @@ public class LoginActivity extends BaseActivity {
isAgreeToUserAgreement = savedInstanceState.getBoolean(IS_AGREE_TO_USER_AGGREMENT_STATE); isAgreeToUserAgreement = savedInstanceState.getBoolean(IS_AGREE_TO_USER_AGGREMENT_STATE);
} }
LemmyVerseFetchInstances.INSTANCE.fetchInstances(mLemmyVerseRetrofit, new FetchInstancesListener() {
@Override
public void onFetchInstancesSuccess(@NonNull List<LemmyInstance> instances) {
ArrayList<String> instanceNames = new ArrayList<>();
for (LemmyInstance instance : instances) {
instanceNames.add(instance.getFqdn());
}
ArrayAdapter<String> adapter = new CustomArrayAdapter(LoginActivity.this, android.R.layout.simple_dropdown_item_1line, instanceNames, mCustomThemeWrapper);
instance_input.setAdapter(adapter);
}
});
loginButton.setOnClickListener(view -> { loginButton.setOnClickListener(view -> {
Log.i("LoginActivity", "Login button clicked"); Log.i("LoginActivity", "Login button clicked");
if (!checkFields()) if (!checkFields())
@ -338,6 +362,7 @@ public class LoginActivity extends BaseActivity {
if (typeface != null) { if (typeface != null) {
twoFAInfoTextView.setTypeface(typeface); twoFAInfoTextView.setTypeface(typeface);
} }
instance_input.setTextColor(mCustomThemeWrapper.getPrimaryTextColor());
} }
@Override @Override

View File

@ -0,0 +1,41 @@
package eu.toldi.infinityforlemmy.adapters;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import java.util.List;
import eu.toldi.infinityforlemmy.customtheme.CustomThemeWrapper;
public class CustomArrayAdapter extends ArrayAdapter<String> {
CustomThemeWrapper customThemeWrapper;
public CustomArrayAdapter(@NonNull Context context, int textViewResourceId, @NonNull List<String> objects, CustomThemeWrapper customThemeWrapper) {
super(context, textViewResourceId, objects);
this.customThemeWrapper = customThemeWrapper;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView itemView = (TextView) super.getView(position, convertView, parent);
itemView.setTextColor(customThemeWrapper.getPrimaryTextColor()); // Set the text color
itemView.setBackgroundColor(customThemeWrapper.getBackgroundColor()); // Set the background color
// Apply any other styling as needed
return itemView;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView itemView = (TextView) super.getDropDownView(position, convertView, parent);
itemView.setTextColor(customThemeWrapper.getPrimaryTextColor()); // Set the text color
itemView.setBackgroundColor(customThemeWrapper.getBackgroundColor()); // Set the background color
// Apply any other styling as needed
return itemView;
}
}

View File

@ -34,6 +34,16 @@ public class CreditsPreferenceFragment extends CustomFontPreferenceFragmentCompa
Preference ufoAndCowPreference = findPreference(SharedPreferencesUtils.UFO_CAPTURING_ANIMATION); Preference ufoAndCowPreference = findPreference(SharedPreferencesUtils.UFO_CAPTURING_ANIMATION);
Preference loveAnimationPreference = findPreference(SharedPreferencesUtils.LOVE_ANIMATION); Preference loveAnimationPreference = findPreference(SharedPreferencesUtils.LOVE_ANIMATION);
Preference lockScreenPreference = findPreference(SharedPreferencesUtils.LOCK_SCREEN_ANIMATION); Preference lockScreenPreference = findPreference(SharedPreferencesUtils.LOCK_SCREEN_ANIMATION);
Preference originalAppPreference = findPreference(SharedPreferencesUtils.ORIGINAL_APP);
if (originalAppPreference != null) {
originalAppPreference.setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(activity, LinkResolverActivity.class);
intent.setData(Uri.parse("https://www.reddit.com/user/Hostilenemy/"));
startActivity(intent);
return true;
});
}
if (iconForegroundPreference != null) { if (iconForegroundPreference != null) {
iconForegroundPreference.setOnPreferenceClickListener(preference -> { iconForegroundPreference.setOnPreferenceClickListener(preference -> {

View File

@ -115,6 +115,7 @@ public class APIUtils {
public static final String REVEDDIT_ORIGIN = "https://www.reveddit.com"; public static final String REVEDDIT_ORIGIN = "https://www.reveddit.com";
public static final String REFERER_KEY = "Referer"; public static final String REFERER_KEY = "Referer";
public static final String REVEDDIT_REFERER = "https://www.reveddit.com/"; public static final String REVEDDIT_REFERER = "https://www.reveddit.com/";
public static final String LEMMYVERSE_API_BASE_URI = "https://data.lemmyverse.net";
public static Map<String, String> getHttpBasicAuthHeader() { public static Map<String, String> getHttpBasicAuthHeader() {
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();

View File

@ -217,6 +217,8 @@ public class SharedPreferencesUtils {
public static final String USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER = "use_bottom_toolbar_in_media_viewer"; public static final String USE_BOTTOM_TOOLBAR_IN_MEDIA_VIEWER = "use_bottom_toolbar_in_media_viewer";
public static final String HIDE_ACCOUNT_KARMA_NAV_BAR = "hide_account_karma"; public static final String HIDE_ACCOUNT_KARMA_NAV_BAR = "hide_account_karma";
public static final String LOCK_SCREEN_ANIMATION = "lock_screen_animation"; public static final String LOCK_SCREEN_ANIMATION = "lock_screen_animation";
public static final String ORIGINAL_APP = "original_app";
public static final String ENABLE_FOLD_SUPPORT = "enable_fold_support"; public static final String ENABLE_FOLD_SUPPORT = "enable_fold_support";
public static final String LOOP_VIDEO = "loop_video"; public static final String LOOP_VIDEO = "loop_video";
public static final String DEFAULT_PLAYBACK_SPEED = "default_playback_speed"; public static final String DEFAULT_PLAYBACK_SPEED = "default_playback_speed";

View File

@ -0,0 +1,13 @@
package eu.toldi.infinityforlemmy.apis
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Headers
interface LemmyVerseAPI {
@Headers("Content-Type: application/json")
@GET("/data/instance.min.json")
fun getInstanceList(): Call<String?>?
}

View File

@ -0,0 +1,3 @@
package eu.toldi.infinityforlemmy.lemmyverse
data class LemmyInstance(val name: String, val fqdn: String)

View File

@ -0,0 +1,39 @@
package eu.toldi.infinityforlemmy.lemmyverse
import eu.toldi.infinityforlemmy.apis.LemmyVerseAPI
import retrofit2.Retrofit
object LemmyVerseFetchInstances {
fun fetchInstances(
lemmyVerseRetrofit: Retrofit,
fetchInstancesListener: FetchInstancesListener
) {
val lemmyVerseAPI = lemmyVerseRetrofit.create(LemmyVerseAPI::class.java)
val call = lemmyVerseAPI.getInstanceList()
call?.enqueue(object : retrofit2.Callback<String?> {
override fun onResponse(
call: retrofit2.Call<String?>,
response: retrofit2.Response<String?>
) {
if (response.isSuccessful) {
val instances = LemmyVerseParseInstances.parseInstances(response.body())
fetchInstancesListener.onFetchInstancesSuccess(instances)
} else {
fetchInstancesListener.onFetchInstancesSuccess(listOf())
}
}
override fun onFailure(call: retrofit2.Call<String?>, t: Throwable) {
fetchInstancesListener.onFetchInstancesSuccess(listOf())
}
})
}
}
fun interface FetchInstancesListener {
fun onFetchInstancesSuccess(instances: List<LemmyInstance>)
}

View File

@ -0,0 +1,24 @@
package eu.toldi.infinityforlemmy.lemmyverse
import org.json.JSONArray
object LemmyVerseParseInstances {
fun parseInstances(body: String?): List<LemmyInstance> {
val instances: MutableList<LemmyInstance> = ArrayList()
try {
val jsonBody = JSONArray(body)
for (i in 0 until jsonBody.length()) {
val jsonInstance = jsonBody.getJSONObject(i)
val name = jsonInstance.getString("name")
val url = jsonInstance.getString("base")
instances.add(LemmyInstance(name, url))
}
} catch (e: Exception) {
e.printStackTrace()
}
return instances
}
}

View File

@ -50,13 +50,15 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/instance_url"> android:hint="@string/instance_url">
<com.google.android.material.textfield.TextInputEditText <androidx.appcompat.widget.AppCompatAutoCompleteTextView
android:id="@+id/instance_url_input" android:id="@+id/instance_url_input"
style="@style/Widget.MaterialComponents.AutoCompleteTextView.FilledBox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:hint="@string/instance_url" android:hint="@string/instance_url"
android:inputType="textUri" android:inputType="textUri"
android:maxLines="1" /> android:maxLines="1"
android:paddingTop="16dp" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -66,7 +68,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="3dp" android:layout_marginLeft="3dp"
android:layout_marginRight="3dp" android:layout_marginRight="3dp"
android:text="The URL of you prefered Lemmy instance with or without the https:// prefix" /> android:text="@string/the_url_of_you_prefered_lemmy_instance_with_or_without_the_https_prefix" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -68,14 +68,13 @@
android:id="@+id/user_instance_text_view_item_post_detail_no_preview_link" android:id="@+id/user_instance_text_view_item_post_detail_no_preview_link"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="?attr/font_family"
android:textSize="?attr/font_default"
android:maxLines="1"
android:ellipsize="end" android:ellipsize="end"
android:fontFamily="?attr/font_family"
android:maxLines="1"
android:textSize="?attr/font_default"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@+id/community_instance_text_view_item_post_detail_no_preview_link"
app:layout_constraintStart_toEndOf="@+id/user_text_view_item_post_detail_no_preview" app:layout_constraintStart_toEndOf="@+id/user_text_view_item_post_detail_no_preview"
app:layout_constraintTop_toBottomOf="@+id/subreddit_text_view_item_post_detail_no_preview" /> app:layout_constraintTop_toBottomOf="@+id/community_instance_text_view_item_post_detail_no_preview_link" />
<TextView <TextView
android:id="@+id/author_flair_text_view_item_post_detail_no_preview" android:id="@+id/author_flair_text_view_item_post_detail_no_preview"

View File

@ -1452,4 +1452,7 @@
<string name="icon_original_label">Original Icon</string> <string name="icon_original_label">Original Icon</string>
<string name="settings_credits_new_icon">New app icon (Cosmic Lemmy)</string> <string name="settings_credits_new_icon">New app icon (Cosmic Lemmy)</string>
<string name="settings_credits_new_icon_summary">Made by David Gerla</string> <string name="settings_credits_new_icon_summary">Made by David Gerla</string>
<string name="original_app">The original Reddit app</string>
<string name="settings_credits_original_app_description">"Infinity was created by u/Hostilenemy "</string>
<string name="the_url_of_you_prefered_lemmy_instance_with_or_without_the_https_prefix">The URL of you prefered Lemmy instance with or without the https:// prefix</string>
</resources> </resources>

View File

@ -2,6 +2,12 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen 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">
<eu.toldi.infinityforlemmy.customviews.CustomFontPreference
android:key="original_app"
app:title="@string/original_app"
android:summary="@string/settings_credits_original_app_description" />
<eu.toldi.infinityforlemmy.customviews.CustomFontPreference <eu.toldi.infinityforlemmy.customviews.CustomFontPreference
android:key="new_icon_foreground" android:key="new_icon_foreground"
app:title="@string/settings_credits_new_icon" app:title="@string/settings_credits_new_icon"