mirror of
https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
synced 2024-11-10 04:37:25 +01:00
Preparing to support multi user. Use the database to store accounts' info. LoginActivity is successfully refactored. Any other features are unavailable for now.
This commit is contained in:
parent
77d83654aa
commit
7f2bc01180
15
.idea/inspectionProfiles/Project_Default.xml
Normal file
15
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="FieldCanBeLocal" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="EXCLUDE_ANNOS">
|
||||
<value>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="androidx.room.ColumnInfo" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="IGNORE_FIELDS_USED_IN_MULTIPLE_METHODS" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
72
app/src/main/java/Account/Account.java
Normal file
72
app/src/main/java/Account/Account.java
Normal file
@ -0,0 +1,72 @@
|
||||
package Account;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
@Entity(tableName = "accounts")
|
||||
public class Account {
|
||||
@PrimaryKey
|
||||
@NonNull
|
||||
@ColumnInfo(name = "username")
|
||||
private String username;
|
||||
@ColumnInfo(name = "profile_image_url")
|
||||
private String profileImageUrl;
|
||||
@ColumnInfo(name = "banner_image_url")
|
||||
private String bannerImageUrl;
|
||||
@ColumnInfo(name = "karma")
|
||||
private int karma;
|
||||
@ColumnInfo(name = "access_token")
|
||||
private String accessToken;
|
||||
@ColumnInfo(name = "refresh_token")
|
||||
private String refreshToken;
|
||||
@ColumnInfo(name = "code")
|
||||
private String code;
|
||||
@ColumnInfo(name = "is_current_user")
|
||||
private boolean isCurrentUser;
|
||||
|
||||
public Account(@NonNull String username, String accessToken, String refreshToken, String code,
|
||||
String profileImageUrl, String bannerImageUrl, int karma, boolean isCurrentUser) {
|
||||
this.username = username;
|
||||
this.accessToken = accessToken;
|
||||
this.refreshToken = refreshToken;
|
||||
this.code = code;
|
||||
this.profileImageUrl = profileImageUrl;
|
||||
this.bannerImageUrl = bannerImageUrl;
|
||||
this.karma = karma;
|
||||
this.isCurrentUser = isCurrentUser;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getProfileImageUrl() {
|
||||
return profileImageUrl;
|
||||
}
|
||||
|
||||
public String getBannerImageUrl() {
|
||||
return bannerImageUrl;
|
||||
}
|
||||
|
||||
public int getKarma() {
|
||||
return karma;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public boolean isCurrentUser() {
|
||||
return isCurrentUser;
|
||||
}
|
||||
}
|
22
app/src/main/java/Account/AccountDao.java
Normal file
22
app/src/main/java/Account/AccountDao.java
Normal file
@ -0,0 +1,22 @@
|
||||
package Account;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
|
||||
@Dao
|
||||
public interface AccountDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(Account account);
|
||||
|
||||
@Query("DELETE FROM accounts")
|
||||
void deleteAllAccounts();
|
||||
|
||||
@Query("SELECT * FROM accounts WHERE username = :userName COLLATE NOCASE LIMIT 1")
|
||||
LiveData<Account> getAccountLiveData(String userName);
|
||||
|
||||
@Query("SELECT * FROM accounts WHERE username = :userName COLLATE NOCASE LIMIT 1")
|
||||
Account getAccountData(String userName);
|
||||
}
|
40
app/src/main/java/Account/AccountRepository.java
Normal file
40
app/src/main/java/Account/AccountRepository.java
Normal file
@ -0,0 +1,40 @@
|
||||
package Account;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
|
||||
public class AccountRepository {
|
||||
private AccountDao mAccountDao;
|
||||
private LiveData<Account> mAccountLiveData;
|
||||
|
||||
AccountRepository(Application application, String username) {
|
||||
mAccountDao = AccountRoomDatabase.getDatabase(application).accountDao();
|
||||
|
||||
mAccountLiveData = mAccountDao.getAccountLiveData(username);
|
||||
}
|
||||
|
||||
LiveData<Account> getAccountLiveData() {
|
||||
return mAccountLiveData;
|
||||
}
|
||||
|
||||
public void insert(Account Account) {
|
||||
new InsertAsyncTask(mAccountDao).execute(Account);
|
||||
}
|
||||
|
||||
private static class InsertAsyncTask extends AsyncTask<Account, Void, Void> {
|
||||
|
||||
private AccountDao mAsyncTaskDao;
|
||||
|
||||
InsertAsyncTask(AccountDao dao) {
|
||||
mAsyncTaskDao = dao;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(final Account... params) {
|
||||
mAsyncTaskDao.insert(params[0]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
27
app/src/main/java/Account/AccountRoomDatabase.java
Normal file
27
app/src/main/java/Account/AccountRoomDatabase.java
Normal file
@ -0,0 +1,27 @@
|
||||
package Account;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.room.Database;
|
||||
import androidx.room.Room;
|
||||
import androidx.room.RoomDatabase;
|
||||
|
||||
@Database(entities = {Account.class}, version = 1)
|
||||
public abstract class AccountRoomDatabase extends RoomDatabase {
|
||||
private static AccountRoomDatabase INSTANCE;
|
||||
|
||||
public abstract AccountDao accountDao();
|
||||
|
||||
public static AccountRoomDatabase getDatabase(final Context context) {
|
||||
if(INSTANCE == null) {
|
||||
synchronized (AccountRoomDatabase.class) {
|
||||
if(INSTANCE == null) {
|
||||
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
|
||||
AccountRoomDatabase.class, "accounts")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
47
app/src/main/java/Account/AccountViewModel.java
Normal file
47
app/src/main/java/Account/AccountViewModel.java
Normal file
@ -0,0 +1,47 @@
|
||||
package Account;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
public class AccountViewModel extends AndroidViewModel {
|
||||
private AccountRepository mAccountRepository;
|
||||
private LiveData<Account> mAccountLiveData;
|
||||
|
||||
public AccountViewModel(Application application, String id) {
|
||||
super(application);
|
||||
mAccountRepository = new AccountRepository(application, id);
|
||||
mAccountLiveData = mAccountRepository.getAccountLiveData();
|
||||
}
|
||||
|
||||
public LiveData<Account> getAccountLiveData() {
|
||||
return mAccountLiveData;
|
||||
}
|
||||
|
||||
public void insert(Account userData) {
|
||||
mAccountRepository.insert(userData);
|
||||
}
|
||||
|
||||
public static class Factory extends ViewModelProvider.NewInstanceFactory {
|
||||
|
||||
@NonNull
|
||||
private final Application mApplication;
|
||||
|
||||
private final String userName;
|
||||
|
||||
public Factory(@NonNull Application application, String userName) {
|
||||
mApplication = application;
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ViewModel> T create(Class<T> modelClass) {
|
||||
//noinspection unchecked
|
||||
return (T) new AccountViewModel(mApplication, userName);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Retrofit;
|
||||
@ -39,4 +40,28 @@ class FetchMyInfo {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void fetchMyInfo(final Retrofit retrofit, String accessToken,
|
||||
final FetchUserMyListener fetchUserMyListener) {
|
||||
RedditAPI api = retrofit.create(RedditAPI.class);
|
||||
|
||||
Call<String> userInfo = api.getMyInfo(RedditUtils.getOAuthHeader(accessToken));
|
||||
userInfo.enqueue(new Callback<String>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
|
||||
if(response.isSuccessful()) {
|
||||
fetchUserMyListener.onFetchMyInfoSuccess(response.body());
|
||||
} else {
|
||||
Log.i("call failed", response.message());
|
||||
fetchUserMyListener.onFetchMyInfoFail();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
|
||||
Log.i("call failed", t.getMessage());
|
||||
fetchUserMyListener.onFetchMyInfoFail();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@ -21,8 +24,7 @@ import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import Account.AccountRoomDatabase;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
@ -36,6 +38,10 @@ public class LoginActivity extends AppCompatActivity {
|
||||
@Named("no_oauth")
|
||||
Retrofit mRetrofit;
|
||||
|
||||
@Inject
|
||||
@Named("oauth")
|
||||
Retrofit mOauthRetrofit;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -85,41 +91,69 @@ public class LoginActivity extends AppCompatActivity {
|
||||
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
|
||||
if(response.isSuccessful()) {
|
||||
try {
|
||||
JSONObject responseJSON = new JSONObject(response.body());
|
||||
String accountResponse = response.body();
|
||||
if(accountResponse == null) {
|
||||
//Handle error
|
||||
return;
|
||||
}
|
||||
|
||||
JSONObject responseJSON = new JSONObject(accountResponse);
|
||||
String accessToken = responseJSON.getString(RedditUtils.ACCESS_TOKEN_KEY);
|
||||
String refreshToken = responseJSON.getString(RedditUtils.REFRESH_TOKEN_KEY);
|
||||
|
||||
editor.putString(SharedPreferencesUtils.ACCESS_TOKEN_KEY, accessToken);
|
||||
editor.putString(SharedPreferencesUtils.REFRESH_TOKEN_KEY, refreshToken);
|
||||
editor.apply();
|
||||
FetchMyInfo.fetchMyInfo(mOauthRetrofit, accessToken, new FetchMyInfo.FetchUserMyListener() {
|
||||
@Override
|
||||
public void onFetchMyInfoSuccess(String response) {
|
||||
ParseMyInfo.parseMyInfo(response, new ParseMyInfo.ParseMyInfoListener() {
|
||||
@Override
|
||||
public void onParseMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) {
|
||||
new ParseAndInsertAccount(name, accessToken, refreshToken, profileImageUrl, bannerImageUrl,
|
||||
karma, authCode, AccountRoomDatabase.getDatabase(LoginActivity.this).accountDao(),
|
||||
() -> {
|
||||
Intent resultIntent = new Intent();
|
||||
setResult(Activity.RESULT_OK, resultIntent);
|
||||
finish();
|
||||
}).execute();
|
||||
}
|
||||
|
||||
Intent resultIntent = new Intent();
|
||||
setResult(Activity.RESULT_OK, resultIntent);
|
||||
finish();
|
||||
@Override
|
||||
public void onParseMyInfoFail() {
|
||||
Toast.makeText(LoginActivity.this, R.string.parse_user_info_error, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchMyInfoFail() {
|
||||
Toast.makeText(LoginActivity.this, R.string.cannot_fetch_user_info, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(LoginActivity.this, "Error occurred when parsing the JSON response", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(LoginActivity.this, R.string.parse_json_response_error, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(LoginActivity.this, "Error Retrieving the token", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(LoginActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<String> call, Throwable t) {
|
||||
Toast.makeText(LoginActivity.this, "Error Retrieving the token", Toast.LENGTH_SHORT).show();
|
||||
public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
|
||||
Toast.makeText(LoginActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(LoginActivity.this, "Something went wrong. Try again later.", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(LoginActivity.this, R.string.something_went_wrong, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
|
||||
} else if (url.contains("error=access_denied")) {
|
||||
Toast.makeText(LoginActivity.this, "Access denied", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(LoginActivity.this, R.string.access_denied, Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
} else {
|
||||
view.loadUrl(url);
|
||||
@ -142,10 +176,9 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package ml.docilealligator.infinityforreddit;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import Account.Account;
|
||||
import Account.AccountDao;
|
||||
|
||||
class ParseAndInsertAccount extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
interface ParseAndInsertAccountListener {
|
||||
void success();
|
||||
}
|
||||
|
||||
private String username;
|
||||
private String accessToken;
|
||||
private String refreshToken;
|
||||
private String profileImageUrl;
|
||||
private String bannerImageUrl;
|
||||
private int karma;
|
||||
private String code;
|
||||
private AccountDao accountDao;
|
||||
private ParseAndInsertAccountListener parseAndInsertAccountListener;
|
||||
|
||||
ParseAndInsertAccount(String username, String accessToken, String refreshToken, String profileImageUrl, String bannerImageUrl,
|
||||
int karma, String code, AccountDao accountDao,
|
||||
ParseAndInsertAccountListener parseAndInsertAccountListener) {
|
||||
this.username = username;
|
||||
this.accessToken = accessToken;
|
||||
this.refreshToken = refreshToken;
|
||||
this.profileImageUrl = profileImageUrl;
|
||||
this.bannerImageUrl = bannerImageUrl;
|
||||
this.karma = karma;
|
||||
this.code = code;
|
||||
this.accountDao = accountDao;
|
||||
this.parseAndInsertAccountListener = parseAndInsertAccountListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
Account account = new Account(username, accessToken, refreshToken, code, profileImageUrl,
|
||||
bannerImageUrl, karma, true);
|
||||
accountDao.insert(account);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
parseAndInsertAccountListener.success();
|
||||
}
|
||||
}
|
@ -25,6 +25,12 @@
|
||||
<string name="action_send">Send</string>
|
||||
<string name="action_sort">Sort</string>
|
||||
|
||||
<string name="parse_json_response_error">Error occurred when parsing the JSON response</string>
|
||||
<string name="retrieve_token_error">Error Retrieving the token</string>
|
||||
<string name="something_went_wrong">Something went wrong. Try again later.</string>
|
||||
<string name="access_denied">Access denied</string>
|
||||
<string name="parse_user_info_error">Error occurred when parsing the user info</string>
|
||||
|
||||
<string name="tap_to_retry">Error loading image. Tap to retry.</string>
|
||||
<string name="load_posts_error">Error loading posts.\nTap to retry.</string>
|
||||
<string name="search_subreddits_error">Error searching subreddits.\nTap to retry.</string>
|
||||
|
Loading…
Reference in New Issue
Block a user