From 67fcb14b0c226f162e0053d526b600eb8be26bbb Mon Sep 17 00:00:00 2001 From: Stefan Schueller Date: Mon, 17 Dec 2018 18:11:41 +0100 Subject: [PATCH 01/13] - WiP --- app/build.gradle | 3 + app/src/main/AndroidManifest.xml | 15 +- .../peertube/activity/LoginActivity.java | 59 +++---- .../peertube/activity/UserActivity.java | 41 +++++ .../peertube/activity/VideoListActivity.java | 6 +- .../java/net/schueller/peertube/model/Me.java | 144 ++++++++++++++++++ .../schueller/peertube/model/OauthClient.java | 5 + .../net/schueller/peertube/model/Token.java | 9 ++ .../network/AuthorizationInterceptor.java | 24 +++ .../peertube/network/GetUserService.java | 14 ++ .../peertube/network/RetrofitInstance.java | 8 + .../network/TokenRenewInterceptor.java | 29 ++++ app/src/main/res/layout/activity_user.xml | 9 ++ app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values/strings.xml | 6 +- 15 files changed, 330 insertions(+), 44 deletions(-) create mode 100644 app/src/main/java/net/schueller/peertube/activity/UserActivity.java create mode 100644 app/src/main/java/net/schueller/peertube/model/Me.java create mode 100644 app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java create mode 100644 app/src/main/java/net/schueller/peertube/network/GetUserService.java create mode 100644 app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java create mode 100644 app/src/main/res/layout/activity_user.xml diff --git a/app/build.gradle b/app/build.gradle index fd7ddba..9212db2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,3 +73,6 @@ android { } } +dependencies { + implementation 'com.android.support.constraint:constraint-layout:+' +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 178aa69..c3e9107 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,18 +16,19 @@ android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> - - + + - + android:resource="@xml/searchable"> - + + + + + \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java index 5118071..40d44df 100644 --- a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java @@ -1,49 +1,33 @@ package net.schueller.peertube.activity; -import android.os.StrictMode; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; -import android.view.View; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; -import android.widget.Toast; import net.schueller.peertube.R; import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.model.OauthClient; import net.schueller.peertube.model.Token; -import net.schueller.peertube.model.VideoList; import net.schueller.peertube.network.AuthenticationService; -import net.schueller.peertube.network.GetVideoDataService; import net.schueller.peertube.network.RetrofitInstance; -import java.io.IOException; - -import okhttp3.FormBody; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; import retrofit2.Call; import retrofit2.Callback; +import retrofit2.Response; public class LoginActivity extends AppCompatActivity { - OkHttpClient client = new OkHttpClient(); - public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private String TAG = "LoginActivity"; - // UI references. private AutoCompleteTextView mEmailView; private EditText mPasswordView; - private View mProgressView; - private View mLoginFormView; @Override protected void onCreate(Bundle savedInstanceState) { @@ -57,17 +41,12 @@ public class LoginActivity extends AppCompatActivity { mEmailView = findViewById(R.id.email); mPasswordView = findViewById(R.id.password); -// if (android.os.Build.VERSION.SDK_INT > 9) { -// StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); -// StrictMode.setThreadPolicy(policy); -// } - } - private void attemptLogin() { + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); // Reset errors. mEmailView.setError(null); @@ -84,15 +63,18 @@ public class LoginActivity extends AppCompatActivity { AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class); Call call = service.getOauthClientLocal(); + call.enqueue(new Callback() { @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.body() != null) { + if (response.isSuccessful()) { + + OauthClient oauthClient = response.body(); Call call2 = service.getAuthenticationToken( - response.body().getClientId(), - response.body().getClientSecret(), + oauthClient.getClientId(), + oauthClient.getClientSecret(), "code", "password", "upload", @@ -103,11 +85,20 @@ public class LoginActivity extends AppCompatActivity { @Override public void onResponse(@NonNull Call call2, @NonNull retrofit2.Response response2) { - if (response2.body() != null) { - Log.wtf(TAG, response2.body().getAccessToken()); - Log.wtf(TAG, response2.body().getExpiresIn()); - Log.wtf(TAG, response2.body().getRefreshToken()); - Log.wtf(TAG, response2.body().getTokenType()); + if (response2.isSuccessful()) { + + Token token = response2.body(); + + SharedPreferences.Editor editor = sharedPref.edit(); + + // TODO: calc expiration + //editor.putInt(getString(R.string.pref_token_expiration), token.getRefreshToken()); + + editor.putString(getString(R.string.pref_token_access), token.getAccessToken()); + editor.putString(getString(R.string.pref_token_refresh), token.getExpiresIn()); + editor.putString(getString(R.string.pref_token_type), token.getTokenType()); + editor.commit(); + } else { Log.wtf(TAG, response2.toString()); } diff --git a/app/src/main/java/net/schueller/peertube/activity/UserActivity.java b/app/src/main/java/net/schueller/peertube/activity/UserActivity.java new file mode 100644 index 0000000..b178c98 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/activity/UserActivity.java @@ -0,0 +1,41 @@ +package net.schueller.peertube.activity; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +import net.schueller.peertube.R; + +public class UserActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_user); + + init(); + } + + private void init() { + // try to get user data + if (!getUserData()) { + Intent intent = new Intent(this, LoginActivity.class); + this.startActivity(intent); + } + } + + private boolean getUserData() { + + // TODO + + return false; + } + + @Override + protected void onResume() { + super.onResume(); + + init(); + + } +} diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java index 5ef84c4..697a4b2 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -103,10 +103,10 @@ public class VideoListActivity extends AppCompatActivity { case R.id.navigation_account: //Log.v(TAG, "navigation_account"); - Toast.makeText(VideoListActivity.this, "Account Not Implemented", Toast.LENGTH_SHORT).show(); +// Toast.makeText(VideoListActivity.this, "Account Not Implemented", Toast.LENGTH_SHORT).show(); -// Intent intent = new Intent(this, LoginActivity.class); -// this.startActivity(intent); + Intent intent = new Intent(this, UserActivity.class); + this.startActivity(intent); return false; } diff --git a/app/src/main/java/net/schueller/peertube/model/Me.java b/app/src/main/java/net/schueller/peertube/model/Me.java new file mode 100644 index 0000000..1a0c96e --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/model/Me.java @@ -0,0 +1,144 @@ +package net.schueller.peertube.model; + +public class Me { + + private Integer id; + private Account account; + private Boolean autoPlayVideo; + private Boolean blocked; + private String blockedReason; + private String createdAt; + private String email; + private String emailVerified; + private String nsfwPolicy; + private Integer role; + private String roleLabel; + private String username; + + // private VideoChannels videoChannels; + private Integer videoQuota; + private Integer videoQuotaDaily; + private String webTorrentEnabled; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Account getAccount() { + return account; + } + + public void setAccount(Account account) { + this.account = account; + } + + public Boolean getAutoPlayVideo() { + return autoPlayVideo; + } + + public void setAutoPlayVideo(Boolean autoPlayVideo) { + this.autoPlayVideo = autoPlayVideo; + } + + public Boolean getBlocked() { + return blocked; + } + + public void setBlocked(Boolean blocked) { + this.blocked = blocked; + } + + public String getBlockedReason() { + return blockedReason; + } + + public void setBlockedReason(String blockedReason) { + this.blockedReason = blockedReason; + } + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEmailVerified() { + return emailVerified; + } + + public void setEmailVerified(String emailVerified) { + this.emailVerified = emailVerified; + } + + public String getNsfwPolicy() { + return nsfwPolicy; + } + + public void setNsfwPolicy(String nsfwPolicy) { + this.nsfwPolicy = nsfwPolicy; + } + + public Integer getRole() { + return role; + } + + public void setRole(Integer role) { + this.role = role; + } + + public String getRoleLabel() { + return roleLabel; + } + + public void setRoleLabel(String roleLabel) { + this.roleLabel = roleLabel; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Integer getVideoQuota() { + return videoQuota; + } + + public void setVideoQuota(Integer videoQuota) { + this.videoQuota = videoQuota; + } + + public Integer getVideoQuotaDaily() { + return videoQuotaDaily; + } + + public void setVideoQuotaDaily(Integer videoQuotaDaily) { + this.videoQuotaDaily = videoQuotaDaily; + } + + public String getWebTorrentEnabled() { + return webTorrentEnabled; + } + + public void setWebTorrentEnabled(String webTorrentEnabled) { + this.webTorrentEnabled = webTorrentEnabled; + } +} + + diff --git a/app/src/main/java/net/schueller/peertube/model/OauthClient.java b/app/src/main/java/net/schueller/peertube/model/OauthClient.java index 35221bc..1bf8944 100644 --- a/app/src/main/java/net/schueller/peertube/model/OauthClient.java +++ b/app/src/main/java/net/schueller/peertube/model/OauthClient.java @@ -1,8 +1,13 @@ package net.schueller.peertube.model; +import com.google.gson.annotations.SerializedName; + public class OauthClient { + @SerializedName("client_id") private String clientId; + + @SerializedName("client_secret") private String clientSecret; public String getClientId() { diff --git a/app/src/main/java/net/schueller/peertube/model/Token.java b/app/src/main/java/net/schueller/peertube/model/Token.java index 4a703ea..9f32316 100644 --- a/app/src/main/java/net/schueller/peertube/model/Token.java +++ b/app/src/main/java/net/schueller/peertube/model/Token.java @@ -1,10 +1,19 @@ package net.schueller.peertube.model; +import com.google.gson.annotations.SerializedName; + public class Token { + @SerializedName("access_token") private String accessToken; + + @SerializedName("expires_in") private String expiresIn; + + @SerializedName("refresh_token") private String refreshToken; + + @SerializedName("token_type") private String tokenType; public String getAccessToken() { diff --git a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java new file mode 100644 index 0000000..da559c0 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java @@ -0,0 +1,24 @@ +package net.schueller.peertube.network; + +import net.schueller.peertube.model.Token; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Response; + +public class AuthorizationInterceptor implements Interceptor { + + public AuthorizationInterceptor() { + + } + + @Override + public Response intercept(Chain chain) throws IOException { + Response mainResponse = chain.proceed(chain.request()); + if (mainResponse.code() == 401 || mainResponse.code() == 403) { + + } + return mainResponse; + } +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/GetUserService.java b/app/src/main/java/net/schueller/peertube/network/GetUserService.java new file mode 100644 index 0000000..7c05bae --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/network/GetUserService.java @@ -0,0 +1,14 @@ +package net.schueller.peertube.network; + +import net.schueller.peertube.model.Me; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.Query; + +public interface GetUserService { + + @GET("users/me") + Call getMe(@Header("Authorization") String authorization); +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java index d8a6cd8..8a00113 100644 --- a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java +++ b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java @@ -1,5 +1,6 @@ package net.schueller.peertube.network; +import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; @@ -11,7 +12,14 @@ public class RetrofitInstance { public static Retrofit getRetrofitInstance(String newBaseUrl) { if (retrofit == null || !newBaseUrl.equals(baseUrl)) { baseUrl = newBaseUrl; + + OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder(); + + okhttpClientBuilder.addInterceptor(new TokenRenewInterceptor()); + okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor()); + retrofit = new retrofit2.Retrofit.Builder() + .client(okhttpClientBuilder.build()) .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .build(); diff --git a/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java b/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java new file mode 100644 index 0000000..2ae3a69 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java @@ -0,0 +1,29 @@ +package net.schueller.peertube.network; + +import net.schueller.peertube.model.Token; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Response; + +public class TokenRenewInterceptor implements Interceptor { + + public TokenRenewInterceptor() { + } + + @Override + public Response intercept(Chain chain) throws IOException { + Response response = chain.proceed(chain.request()); + + // if 'x-auth-token' is available into the response header + // save the new token into session.The header key can be + // different upon implementation of backend. + String newToken = response.header("x-auth-token"); + if (newToken != null) { + + } + + return response; + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_user.xml b/app/src/main/res/layout/activity_user.xml new file mode 100644 index 0000000..39f110a --- /dev/null +++ b/app/src/main/res/layout/activity_user.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 75d7cde..ff3fd89 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -8,7 +8,7 @@ Serveur Email - Mot de passe (optionnel) + Mot de passe Connexion Connexion Cette adresse mail n\'est pas valide diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5ceebec..944603f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,7 +8,7 @@ Server Email - Password (optional) + Password Sign in Sign in This email address is invalid @@ -59,5 +59,9 @@ More Share PeerTube + pref_token_access + pref_token_refresh + pref_token_expiration + pref_token_type From 47cf90727a5634c05373ddc4bd1b73dd9d8b30a5 Mon Sep 17 00:00:00 2001 From: Stefan Schueller Date: Sat, 29 Dec 2018 22:10:13 +0100 Subject: [PATCH 02/13] WIP --- app/src/main/AndroidManifest.xml | 7 +- .../peertube/activity/AccountActivity.java | 123 +++++++++++++++++ .../peertube/activity/LoginActivity.java | 14 +- .../peertube/activity/UserActivity.java | 41 ------ .../peertube/activity/VideoListActivity.java | 41 +++++- .../peertube/application/AppApplication.java | 18 +++ .../network/AuthorizationInterceptor.java | 42 +++++- .../peertube/network/GetUserService.java | 9 ++ .../peertube/network/RetrofitInstance.java | 1 - .../schueller/peertube/network/Session.java | 128 ++++++++++++++++++ .../network/TokenRenewInterceptor.java | 29 ---- app/src/main/res/layout/activity_account.xml | 25 ++++ app/src/main/res/layout/activity_user.xml | 9 -- app/src/main/res/menu/menu_top_user.xml | 12 ++ .../{menu_main.xml => menu_top_videolist.xml} | 0 app/src/main/res/values/strings.xml | 7 + 16 files changed, 411 insertions(+), 95 deletions(-) create mode 100644 app/src/main/java/net/schueller/peertube/activity/AccountActivity.java delete mode 100644 app/src/main/java/net/schueller/peertube/activity/UserActivity.java create mode 100644 app/src/main/java/net/schueller/peertube/application/AppApplication.java create mode 100644 app/src/main/java/net/schueller/peertube/network/Session.java delete mode 100644 app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java create mode 100644 app/src/main/res/layout/activity_account.xml delete mode 100644 app/src/main/res/layout/activity_user.xml create mode 100644 app/src/main/res/menu/menu_top_user.xml rename app/src/main/res/menu/{menu_main.xml => menu_top_videolist.xml} (100%) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5aa5606..de4a1d2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,7 +18,8 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" - tools:ignore="GoogleAppIndexingWarning"> + tools:ignore="GoogleAppIndexingWarning" + android:name=".application.AppApplication"> - diff --git a/app/src/main/java/net/schueller/peertube/activity/AccountActivity.java b/app/src/main/java/net/schueller/peertube/activity/AccountActivity.java new file mode 100644 index 0000000..095c1d4 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/activity/AccountActivity.java @@ -0,0 +1,123 @@ +/* + * Copyright 2018 Stefan Schüller + * + * License: GPL-3.0+ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.schueller.peertube.activity; + +import android.app.SearchManager; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import com.mikepenz.fontawesome_typeface_library.FontAwesome; +import com.mikepenz.iconics.IconicsDrawable; + +import net.schueller.peertube.R; +import net.schueller.peertube.network.Session; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.SearchView; +import androidx.appcompat.widget.Toolbar; + +import static net.schueller.peertube.helper.Constants.DEFAULT_THEME; +import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY; + +public class AccountActivity extends AppCompatActivity { + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_top_user, menu); + + // Set an icon in the ActionBar + menu.findItem(R.id.action_logout).setIcon( + new IconicsDrawable(this, FontAwesome.Icon.faw_sign_out_alt).actionBar()); + + return true; + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + // action with ID action_refresh was selected + + case R.id.action_logout: + Session.getInstance().invalidate(); + Intent intent = new Intent(this, LoginActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + this.startActivity(intent); + return true; + default: + break; + } + + return super.onOptionsItemSelected(item); + } + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Set theme + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + setTheme(getResources().getIdentifier( + sharedPref.getString(THEME_PREF_KEY, DEFAULT_THEME), + "style", + getPackageName()) + ); + + setContentView(R.layout.activity_account); + + // Attaching the layout to the toolbar object + Toolbar toolbar = findViewById(R.id.tool_bar_user); + // Setting toolbar as the ActionBar with setSupportActionBar() call + setSupportActionBar(toolbar); + + init(); + } + + private void init() { + // try to get user data + getUserData(); + } + + private boolean getUserData() { + + // TODO + + return false; + } + + @Override + protected void onResume() { + super.onResume(); + + init(); + + } +} diff --git a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java index e34c397..9ec1427 100644 --- a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java @@ -18,10 +18,10 @@ package net.schueller.peertube.activity; +import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; -import android.support.annotation.NonNull; -import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.AutoCompleteTextView; @@ -35,6 +35,8 @@ import net.schueller.peertube.model.Token; import net.schueller.peertube.network.AuthenticationService; import net.schueller.peertube.network.RetrofitInstance; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -78,6 +80,8 @@ public class LoginActivity extends AppCompatActivity { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + Context context = this; + // Reset errors. mEmailView.setError(null); mPasswordView.setError(null); @@ -129,6 +133,12 @@ public class LoginActivity extends AppCompatActivity { editor.putString(getString(R.string.pref_token_type), token.getTokenType()); editor.commit(); + Log.wtf(TAG, "Logged in"); + + Intent intent = new Intent(context, AccountActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + context.startActivity(intent); + } else { Log.wtf(TAG, response2.toString()); } diff --git a/app/src/main/java/net/schueller/peertube/activity/UserActivity.java b/app/src/main/java/net/schueller/peertube/activity/UserActivity.java deleted file mode 100644 index b178c98..0000000 --- a/app/src/main/java/net/schueller/peertube/activity/UserActivity.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.schueller.peertube.activity; - -import android.content.Intent; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; - -import net.schueller.peertube.R; - -public class UserActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_user); - - init(); - } - - private void init() { - // try to get user data - if (!getUserData()) { - Intent intent = new Intent(this, LoginActivity.class); - this.startActivity(intent); - } - } - - private boolean getUserData() { - - // TODO - - return false; - } - - @Override - protected void onResume() { - super.onResume(); - - init(); - - } -} diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java index bef23d9..ed8b3d4 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -53,8 +53,10 @@ import net.schueller.peertube.R; import net.schueller.peertube.adapter.VideoAdapter; import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.model.VideoList; +import net.schueller.peertube.network.GetUserService; import net.schueller.peertube.network.GetVideoDataService; import net.schueller.peertube.network.RetrofitInstance; +import net.schueller.peertube.network.Session; import net.schueller.peertube.provider.SearchSuggestionsProvider; import net.schueller.peertube.service.VideoPlayerService; @@ -82,6 +84,7 @@ public class VideoListActivity extends AppCompatActivity { private String sort = "-createdAt"; private String filter = null; private String searchQuery = ""; + private Boolean subscriptions = false; private TextView emptyView; private RecyclerView recyclerView; @@ -125,7 +128,7 @@ public class VideoListActivity extends AppCompatActivity { @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.menu_main, menu); + inflater.inflate(R.menu.menu_top_videolist, menu); // Set an icon in the ActionBar menu.findItem(R.id.action_settings).setIcon( @@ -261,6 +264,9 @@ public class VideoListActivity extends AppCompatActivity { Call call; if (!searchQuery.equals("")) { call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter); + } else if (subscriptions) { + GetUserService userService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); + call = userService.getVideosSubscripions(start, count, sort); } else { call = service.getVideosData(start, count, sort, nsfw, filter); } @@ -380,6 +386,7 @@ public class VideoListActivity extends AppCompatActivity { sort = "-createdAt"; currentStart = 0; filter = null; + subscriptions = false; loadVideos(currentStart, count, sort, filter); } @@ -391,6 +398,7 @@ public class VideoListActivity extends AppCompatActivity { sort = "-trending"; currentStart = 0; filter = null; + subscriptions = false; loadVideos(currentStart, count, sort, filter); } @@ -402,24 +410,43 @@ public class VideoListActivity extends AppCompatActivity { sort = "-publishedAt"; filter = "local"; currentStart = 0; + subscriptions = false; loadVideos(currentStart, count, sort, filter); } return true; case R.id.navigation_subscriptions: //Log.v(TAG, "navigation_subscriptions"); - Toast.makeText(VideoListActivity.this, "Subscriptions Not Implemented", Toast.LENGTH_SHORT).show(); - return false; + if (!Session.getInstance().isLoggedIn()) { + Intent intent = new Intent(this, LoginActivity.class); + this.startActivity(intent); + } else { + + if (!isLoading) { + sort = "-publishedAt"; + filter = null; + currentStart = 0; + subscriptions = true; + loadVideos(currentStart, count, sort, filter); + } + } + + return true; case R.id.navigation_account: //Log.v(TAG, "navigation_account"); - Toast.makeText(VideoListActivity.this, "Account Not Implemented", Toast.LENGTH_SHORT).show(); + //Toast.makeText(VideoListActivity.this, "Account Not Implemented", Toast.LENGTH_SHORT).show(); -// Intent intent = new Intent(this, LoginActivity.class); -// this.startActivity(intent); + if (!Session.getInstance().isLoggedIn()) { + Intent intent = new Intent(this, LoginActivity.class); + this.startActivity(intent); + } else { + Intent intent = new Intent(this, AccountActivity.class); + this.startActivity(intent); + } - return false; + return true; } return false; }); diff --git a/app/src/main/java/net/schueller/peertube/application/AppApplication.java b/app/src/main/java/net/schueller/peertube/application/AppApplication.java new file mode 100644 index 0000000..05869b4 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/application/AppApplication.java @@ -0,0 +1,18 @@ +package net.schueller.peertube.application; + +import android.app.Application; +import android.content.Context; + +public class AppApplication extends Application { + private static Application instance; + + @Override + public void onCreate() { + super.onCreate(); + instance = this; + } + + public static Context getContext() { + return instance.getApplicationContext(); + } +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java index da559c0..5329b7b 100644 --- a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java +++ b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java @@ -1,24 +1,58 @@ +/* + * Copyright 2018 Stefan Schüller + * + * License: GPL-3.0+ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.schueller.peertube.network; -import net.schueller.peertube.model.Token; +import android.util.Log; import java.io.IOException; import okhttp3.Interceptor; +import okhttp3.Request; import okhttp3.Response; public class AuthorizationInterceptor implements Interceptor { public AuthorizationInterceptor() { - } @Override public Response intercept(Chain chain) throws IOException { - Response mainResponse = chain.proceed(chain.request()); - if (mainResponse.code() == 401 || mainResponse.code() == 403) { + Session session = Session.getInstance(); + + Response mainResponse = chain.proceed(chain.request()); + Request mainRequest = chain.request(); + + if (session.isLoggedIn()) { + +// if (mainResponse.code() == 401 || mainResponse.code() == 403) { +// session.invalidate(); +// return mainResponse; +// } + + Request.Builder builder = mainRequest.newBuilder().header("Authorization", session.getToken()). + method(mainRequest.method(), mainRequest.body()); + mainResponse = chain.proceed(builder.build()); + Log.v("Authorization", "Intercept: " + session.getToken()); } + return mainResponse; } + } \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/GetUserService.java b/app/src/main/java/net/schueller/peertube/network/GetUserService.java index 7c05bae..7c4d459 100644 --- a/app/src/main/java/net/schueller/peertube/network/GetUserService.java +++ b/app/src/main/java/net/schueller/peertube/network/GetUserService.java @@ -1,6 +1,7 @@ package net.schueller.peertube.network; import net.schueller.peertube.model.Me; +import net.schueller.peertube.model.VideoList; import retrofit2.Call; import retrofit2.http.GET; @@ -11,4 +12,12 @@ public interface GetUserService { @GET("users/me") Call getMe(@Header("Authorization") String authorization); + + @GET("users/me/subscriptions/videos") + Call getVideosSubscripions( + @Query("start") int start, + @Query("count") int count, + @Query("sort") String sort + ); + } \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java index 86fd92c..23e38da 100644 --- a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java +++ b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java @@ -32,7 +32,6 @@ public class RetrofitInstance { OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder(); - okhttpClientBuilder.addInterceptor(new TokenRenewInterceptor()); okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor()); retrofit = new retrofit2.Retrofit.Builder() diff --git a/app/src/main/java/net/schueller/peertube/network/Session.java b/app/src/main/java/net/schueller/peertube/network/Session.java new file mode 100644 index 0000000..525cbb9 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/network/Session.java @@ -0,0 +1,128 @@ +/* + * Copyright 2018 Stefan Schüller + * + * License: GPL-3.0+ + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.schueller.peertube.network; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +import net.schueller.peertube.R; +import net.schueller.peertube.application.AppApplication; + +public class Session { + + private static volatile Session sSoleInstance; + private static SharedPreferences sharedPreferences; + + //private constructor. + private Session(){ + + Context context = AppApplication.getContext(); + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + + //Prevent form the reflection api. + if (sSoleInstance != null){ + throw new RuntimeException("Use getInstance() method to get the single instance of this class."); + } + } + + public static Session getInstance() { + if (sSoleInstance == null) { //if there is no instance available... create new one + synchronized (Session.class) { + if (sSoleInstance == null) sSoleInstance = new Session(); + } + } + + return sSoleInstance; + } + + //Make singleton from serialize and deserialize operation. + protected Session readResolve() { + return getInstance(); + } + + + + public boolean isLoggedIn() { + // check if token exist or not + // return true if exist otherwise false + // assuming that token exists + + //Log.v("Session", "isLoggedIn: " + (getToken() != null)); + + return getToken() != null; + } + + public void saveToken(String token) { + // save the token + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(AppApplication.getContext().getString(R.string.pref_token_access), token); + editor.commit(); + } + + public String getToken() { + // return the token that was saved earlier + + String token = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_token_access), null); + String type = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_token_type), "Bearer"); + + if (token != null) { + return type + " " + token; + } + + return null; + } + + public void saveUsername(String username) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(AppApplication.getContext().getString(R.string.pref_auth_username), username); + editor.commit(); + } + + public String getEmail() { + return sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_auth_username), null); + } + + public void savePassword(String password) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(AppApplication.getContext().getString(R.string.pref_auth_password), password); + editor.commit(); + } + + public String getPassword() { + return sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_auth_password), null); + + } + + public void invalidate() { + // get called when user become logged out + // delete token and other user info + // (i.e: email, password) + // from the storage + + Context context = AppApplication.getContext(); + + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(context.getString(R.string.pref_auth_password), null); + editor.putString(context.getString(R.string.pref_auth_username), null); + editor.putString(context.getString(R.string.pref_token_access), null); + + editor.commit(); + } +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java b/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java deleted file mode 100644 index 2ae3a69..0000000 --- a/app/src/main/java/net/schueller/peertube/network/TokenRenewInterceptor.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.schueller.peertube.network; - -import net.schueller.peertube.model.Token; - -import java.io.IOException; - -import okhttp3.Interceptor; -import okhttp3.Response; - -public class TokenRenewInterceptor implements Interceptor { - - public TokenRenewInterceptor() { - } - - @Override - public Response intercept(Chain chain) throws IOException { - Response response = chain.proceed(chain.request()); - - // if 'x-auth-token' is available into the response header - // save the new token into session.The header key can be - // different upon implementation of backend. - String newToken = response.header("x-auth-token"); - if (newToken != null) { - - } - - return response; - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_account.xml b/app/src/main/res/layout/activity_account.xml new file mode 100644 index 0000000..bc4f3a5 --- /dev/null +++ b/app/src/main/res/layout/activity_account.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_user.xml b/app/src/main/res/layout/activity_user.xml deleted file mode 100644 index 39f110a..0000000 --- a/app/src/main/res/layout/activity_user.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/menu_top_user.xml b/app/src/main/res/menu/menu_top_user.xml new file mode 100644 index 0000000..efd2356 --- /dev/null +++ b/app/src/main/res/menu/menu_top_user.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_top_videolist.xml similarity index 100% rename from app/src/main/res/menu/menu_main.xml rename to app/src/main/res/menu/menu_top_videolist.xml diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 36158aa..524f60d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,6 +22,7 @@ Search Settings + Logout Home @@ -96,9 +97,15 @@ Background Playback If enabled, continues to play video in background. Local + + Account + + pref_token_access pref_token_refresh pref_token_expiration pref_token_type + pref_auth_username + pref_auth_password From 6e2ef7875193bf3a5ee8d4271676219891bf8847 Mon Sep 17 00:00:00 2001 From: lishoujun Date: Tue, 1 Jan 2019 02:15:35 +0800 Subject: [PATCH 03/13] add languages MultiSelectListPreference. but not all languages. --- .../schueller/peertube/activity/VideoListActivity.java | 7 ++++--- .../peertube/network/GetVideoDataService.java | 8 ++++++-- app/src/main/res/values/array.xml | 10 ++++++++++ app/src/main/res/values/strings.xml | 5 +++++ app/src/main/res/xml/pref_general.xml | 8 ++++++++ 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java index bef23d9..e850419 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -60,6 +60,7 @@ import net.schueller.peertube.service.VideoPlayerService; import java.util.ArrayList; +import java.util.Set; import retrofit2.Call; import retrofit2.Callback; @@ -253,16 +254,16 @@ public class VideoListActivity extends AppCompatActivity { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); String nsfw = sharedPref.getBoolean("pref_show_nsfw", false) ? "both" : "false"; - + Set languages = sharedPref.getStringSet("pref_language", null); String apiBaseURL = APIUrlHelper.getUrlWithVersion(this); GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); Call call; if (!searchQuery.equals("")) { - call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter); + call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter, languages); } else { - call = service.getVideosData(start, count, sort, nsfw, filter); + call = service.getVideosData(start, count, sort, nsfw, filter, languages); } /*Log the URL called*/ diff --git a/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java b/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java index b66b727..2159070 100644 --- a/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java +++ b/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java @@ -20,6 +20,8 @@ package net.schueller.peertube.network; import net.schueller.peertube.model.Video; import net.schueller.peertube.model.VideoList; +import java.util.Set; + import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Path; @@ -32,7 +34,8 @@ public interface GetVideoDataService { @Query("count") int count, @Query("sort") String sort, @Query("nsfw") String nsfw, - @Query("filter") String filter + @Query("filter") String filter, + @Query("languageOneOf") Set languages ); @GET("videos/{id}") @@ -47,6 +50,7 @@ public interface GetVideoDataService { @Query("sort") String sort, @Query("nsfw") String nsfw, @Query("search") String search, - @Query("filter") String filter + @Query("filter") String filter, + @Query("languageOneOf") Set languages ); } \ No newline at end of file diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index 1625c00..6c5083b 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -44,5 +44,15 @@ AppTheme.GRAY AppTheme.BLUEGRAY + + @string/en + @string/fr + + + + en + fr + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8f8f546..cd8057d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -47,6 +47,8 @@ Show NSFW NSFW content will be shown if enabled. + Show Languages + Select languages be shown. UrlVideoPlayActivity Torrent Video Player Video playback via a torrent stream. This requires Storage Permissions. (Alpha, not stable!) @@ -65,6 +67,9 @@ App Theme Restart App for theme to take effect. + English + French + Red Pink Purple diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index d287b5d..98b1da9 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -22,6 +22,14 @@ android:summary="@string/pref_description_show_nsfw" android:defaultValue="false" /> + + Date: Mon, 31 Dec 2018 20:32:22 +0100 Subject: [PATCH 04/13] wip --- .../peertube/activity/VideoListActivity.java | 5 +++-- .../network/AuthorizationInterceptor.java | 7 +++++-- app/src/main/res/layout/activity_login.xml | 16 ++++++++-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java index ed8b3d4..4fdaa84 100644 --- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java @@ -421,6 +421,7 @@ public class VideoListActivity extends AppCompatActivity { if (!Session.getInstance().isLoggedIn()) { Intent intent = new Intent(this, LoginActivity.class); this.startActivity(intent); + return false; } else { if (!isLoading) { @@ -430,9 +431,9 @@ public class VideoListActivity extends AppCompatActivity { subscriptions = true; loadVideos(currentStart, count, sort, filter); } + return true; } - return true; case R.id.navigation_account: //Log.v(TAG, "navigation_account"); @@ -446,7 +447,7 @@ public class VideoListActivity extends AppCompatActivity { this.startActivity(intent); } - return true; + return false; } return false; }); diff --git a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java index 5329b7b..438797e 100644 --- a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java +++ b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java @@ -41,11 +41,14 @@ public class AuthorizationInterceptor implements Interceptor { if (session.isLoggedIn()) { -// if (mainResponse.code() == 401 || mainResponse.code() == 403) { + if (mainResponse.code() == 401 || mainResponse.code() == 403) { // session.invalidate(); // return mainResponse; -// } + Log.v("Authorization", "Intercept code: " + mainResponse.code()); + } + + // add authentication header to each request if we are logged in Request.Builder builder = mainRequest.newBuilder().header("Authorization", session.getToken()). method(mainRequest.method(), mainRequest.body()); mainResponse = chain.proceed(builder.build()); diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 82d760d..9187735 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -10,26 +10,26 @@ android:paddingTop="@dimen/activity_vertical_margin" tools:context="net.schueller.peertube.activity.LoginActivity"> - - + + + + + From f485f4efa74d72f2cc6726881fb90b9d648edda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Schu=CC=88ller?= Date: Mon, 31 Dec 2018 20:45:08 +0100 Subject: [PATCH 05/13] - Added all supported languages --- app/src/main/res/values/array.xml | 380 ++++++++++++++++++++++++++++ app/src/main/res/values/strings.xml | 194 +++++++++++++- 2 files changed, 572 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index 6c5083b..e842230 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -45,13 +45,393 @@ AppTheme.BLUEGRAY + @string/ab + @string/aa + @string/af + @string/ak + @string/sq + @string/ase + @string/am + @string/ar + @string/an + @string/hy + @string/as + @string/av + @string/ay + @string/az + @string/bm + @string/ba + @string/eu + @string/be + @string/bn + @string/bi + @string/bs + @string/bzs + @string/br + @string/bfi + @string/bg + @string/my + @string/ca + @string/ch + @string/ce + @string/zh + @string/csl + @string/cv + @string/kw + @string/co + @string/cr + @string/hr + @string/cs + @string/cse + @string/da + @string/dsl + @string/dv + @string/nl + @string/dz @string/en + @string/eo + @string/et + @string/ee + @string/fo + @string/fj + @string/fi @string/fr + @string/fsl + @string/ff + @string/gl + @string/lg + @string/ka + @string/de + @string/gsg + @string/gn + @string/gu + @string/ht + @string/ha + @string/he + @string/hz + @string/hi + @string/ho + @string/hu + @string/is + @string/ig + @string/id + @string/iu + @string/ik + @string/ga + @string/it + @string/ja + @string/jsl + @string/jv + @string/kl + @string/kn + @string/kr + @string/ks + @string/kk + @string/km + @string/ki + @string/rw + @string/ky + @string/tlh + @string/kv + @string/kg + @string/ko + @string/avk + @string/kj + @string/ku + @string/lo + @string/lv + @string/li + @string/ln + @string/lt + @string/jbo + @string/lu + @string/lb + @string/mk + @string/mg + @string/ms + @string/ml + @string/mt + @string/gv + @string/mi + @string/mr + @string/mh + @string/el + @string/mn + @string/na + @string/nv + @string/ng + @string/ne + @string/nd + @string/se + @string/no + @string/nb + @string/nn + @string/ny + @string/oc + @string/oj + @string/or + @string/om + @string/os + @string/pks + @string/pa + @string/fa + @string/pl + @string/pt + @string/ps + @string/qu + @string/ro + @string/rm + @string/rn + @string/ru + @string/rsl + @string/sm + @string/sg + @string/sc + @string/sdl + @string/gd + @string/sr + @string/sh + @string/sn + @string/ii + @string/sd + @string/si + @string/sk + @string/sl + @string/so + @string/sfs + @string/nr + @string/st + @string/es + @string/su + @string/sw + @string/ss + @string/sv + @string/swl + @string/tl + @string/ty + @string/tg + @string/ta + @string/tt + @string/te + @string/th + @string/bo + @string/ti + @string/to + @string/ts + @string/tn + @string/tr + @string/tk + @string/tw + @string/ug + @string/uk + @string/ur + @string/uz + @string/ve + @string/vi + @string/wa + @string/cy + @string/fy + @string/wo + @string/xh + @string/yi + @string/yo + @string/za + @string/zu + ab + aa + af + ak + sq + ase + am + ar + an + hy + as + av + ay + az + bm + ba + eu + be + bn + bi + bs + bzs + br + bfi + bg + my + ca + ch + ce + zh + csl + cv + kw + co + cr + hr + cs + cse + da + dsl + dv + nl + dz en + eo + et + ee + fo + fj + fi fr + fsl + ff + gl + lg + ka + de + gsg + gn + gu + ht + ha + he + hz + hi + ho + hu + is + ig + id + iu + ik + ga + it + ja + jsl + jv + kl + kn + kr + ks + kk + km + ki + rw + ky + tlh + kv + kg + ko + avk + kj + ku + lo + lv + li + ln + lt + jbo + lu + lb + mk + mg + ms + ml + mt + gv + mi + mr + mh + el + mn + na + nv + ng + ne + nd + se + no + nb + nn + ny + oc + oj + or + om + os + pks + pa + fa + pl + pt + ps + qu + ro + rm + rn + ru + rsl + sm + sg + sc + sdl + gd + sr + sh + sn + ii + sd + si + sk + sl + so + sfs + nr + st + es + su + sw + ss + sv + swl + tl + ty + tg + ta + tt + te + th + bo + ti + to + ts + tn + tr + tk + tw + ug + uk + ur + uz + ve + vi + wa + cy + fy + wo + xh + yi + yo + za + zu diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cd8057d..aac92cf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -47,8 +47,8 @@ Show NSFW NSFW content will be shown if enabled. - Show Languages - Select languages be shown. + Languages filter + Select video languages that should be shown. None selected will show all videos in all languages. UrlVideoPlayActivity Torrent Video Player Video playback via a torrent stream. This requires Storage Permissions. (Alpha, not stable!) @@ -67,8 +67,198 @@ App Theme Restart App for theme to take effect. + Abkhazian + Afar + Afrikaans + Akan + Albanian + American Sign Language + Amharic + Arabic + Aragonese + Armenian + Assamese + Avaric + Aymara + Azerbaijani + Bambara + Bashkir + Basque + Belarusian + Bengali + Bislama + Bosnian + Brazilian Sign Language + Breton + British Sign Language + Bulgarian + Burmese + Catalan + Chamorro + Chechen + Chinese + Chinese Sign Language + Chuvash + Cornish + Corsican + Cree + Croatian + Czech + Czech Sign Language + Danish + Danish Sign Language + Dhivehi + Dutch + Dzongkha English + Esperanto + Estonian + Ewe + Faroese + Fijian + Finnish French + French Sign Language + Fulah + Galician + Ganda + Georgian + German + German Sign Language + Guarani + Gujarati + Haitian + Hausa + Hebrew + Herero + Hindi + Hiri Motu + Hungarian + Icelandic + Igbo + Indonesian + Inuktitut + Inupiaq + Irish + Italian + Japanese + Japanese Sign Language + Javanese + Kalaallisut + Kannada + Kanuri + Kashmiri + Kazakh + Khmer + Kikuyu + Kinyarwanda + Kirghiz + Klingon + Komi + Kongo + Korean + Kotava + Kuanyama + Kurdish + Lao + Latvian + Limburgan + Lingala + Lithuanian + Lojban + Luba-Katanga + Luxembourgish + Macedonian + Malagasy + Malay (macrolanguage) + Malayalam + Maltese + Manx + Maori + Marathi + Marshallese + Modern Greek (1453-) + Mongolian + Nauru + Navajo + Ndonga + Nepali (macrolanguage) + North Ndebele + Northern Sami + Norwegian + Norwegian Bokmål + Norwegian Nynorsk + Nyanja + Occitan + Ojibwa + Oriya (macrolanguage) + Oromo + Ossetian + Pakistan Sign Language + Panjabi + Persian + Polish + Portuguese + Pushto + Quechua + Romanian + Romansh + Rundi + Russian + Russian Sign Language + Samoan + Sango + Sardinian + Saudi Arabian Sign Language + Scottish Gaelic + Serbian + Serbo-Croatian + Shona + Sichuan Yi + Sindhi + Sinhala + Slovak + Slovenian + Somali + South African Sign Language + South Ndebele + Southern Sotho + Spanish + Sundanese + Swahili (macrolanguage) + Swati + Swedish + Swedish Sign Language + Tagalog + Tahitian + Tajik + Tamil + Tatar + Telugu + Thai + Tibetan + Tigrinya + Tonga (Tonga Islands) + Tsonga + Tswana + Turkish + Turkmen + Twi + Uighur + Ukrainian + Urdu + Uzbek + Venda + Vietnamese + Walloon + Welsh + Western Frisian + Wolof + Xhosa + Yiddish + Yoruba + Zhuang + Zulu Red Pink From ce70a0d15d81eb2a819cf5dcd3258bd6642a775d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Schu=CC=88ller?= Date: Mon, 31 Dec 2018 20:45:50 +0100 Subject: [PATCH 06/13] - Version bump --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d51e17c..8b69e35 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "net.schueller.peertube" minSdkVersion 21 targetSdkVersion 28 - versionCode 1018 - versionName "1.0.18" + versionCode 1019 + versionName "1.0.19" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) From 275355bf9ec70d74624a0e5e469955bb11a1d0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Schu=CC=88ller?= Date: Mon, 31 Dec 2018 20:48:36 +0100 Subject: [PATCH 07/13] - Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e48cd4..fc7448a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### Version 1.0.19 Tag: v1.0.19 (2018-12-31) + * Video Language Filter (@lishoujun) + ### Version 1.0.18 Tag: v1.0.18 (2018-12-31) * Bug Fixes * Arabic translation update From 216417ffe2711179bc9bba77673899f67982be40 Mon Sep 17 00:00:00 2001 From: Rex_sa <13156001+rex07@users.noreply.github.com> Date: Mon, 31 Dec 2018 23:45:33 +0300 Subject: [PATCH 08/13] fix --- app/src/main/res/values-ar/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index e090072..ab8ed73 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -35,8 +35,8 @@ - \0020-\0020 - \0020مشاهدات + \u0020-\u0020 + \u0020 مشاهدات \@ @@ -49,7 +49,7 @@ مشغل فيديو التورنت تشغيل الفيديو عبر بث التورنت . يتطلب هذا أذونات التخزين. (ألفا ، غير مستقر!) الرخصة - GNU Affero General Public License v3.0\n + رخصة جنو العمومية v3.0\n \n إن أذونات هذا الترخيص الأقوى للحقوق المتروكة مشروطة بإتاحة الشفرة المصدرية الكاملة للأعمال والتعديلات المرخصة ، والتي تشتمل على أعمال أكبر باستخدام عمل مرخص ، تحت نفس الترخيص. يجب الحفاظ على حقوق النشر وإشعارات الترخيص. يقدم المساهمون منحة صريحة لحقوق البراءة. عند استخدام إصدار معدل لتوفير خدمة عبر شبكة ، يجب توفير شفرة المصدر الكاملة للإصدار المعدل. الإصدار @@ -91,7 +91,7 @@ التشغيل في الخلفية - إن تم تنشيطه، ستواصل الفيديو في الإشتغال في الخلفية. + إن تم تنشيطه، سيستمر تشغيل الفيديو في الخلفية. المحلي From cbe2bb45e30455635b316c01846aa4df14ee0a89 Mon Sep 17 00:00:00 2001 From: lishoujun Date: Tue, 1 Jan 2019 12:40:46 +0800 Subject: [PATCH 09/13] update dependence. minor change --- app/build.gradle | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8b69e35..a317844 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,6 +9,11 @@ android { versionCode 1019 versionName "1.0.19" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + ext { + libVersions = [ + exoplayer: '2.9.3' + ] + } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) @@ -41,13 +46,13 @@ android { // implementation "com.github.TorrentStream:TorrentStreamServer-Android:1.0.1" // implementation 'org.webrtc:google-webrtc:1.0.+' - // video player - implementation 'com.google.android.exoplayer:exoplayer-core:2.9.2' - implementation 'com.google.android.exoplayer:exoplayer-dash:2.9.2' - implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.2' - implementation 'com.google.android.exoplayer:exoplayer-hls:2.9.2' - implementation 'com.google.android.exoplayer:exoplayer-smoothstreaming:2.9.2' - implementation 'com.google.android.exoplayer:extension-mediasession:2.9.2' + // video player repo:jcenter() + implementation "com.google.android.exoplayer:exoplayer-core:$libVersions.exoplayer" + implementation "com.google.android.exoplayer:exoplayer-dash:$libVersions.exoplayer" + implementation "com.google.android.exoplayer:exoplayer-ui:$libVersions.exoplayer" + implementation "com.google.android.exoplayer:exoplayer-hls:$libVersions.exoplayer" + implementation "com.google.android.exoplayer:exoplayer-smoothstreaming:$libVersions.exoplayer" + implementation "com.google.android.exoplayer:extension-mediasession:$libVersions.exoplayer" // testing testImplementation 'junit:junit:4.12' From 654e2be93356a49660db7c413651cc1195121dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Schu=CC=88ller?= Date: Tue, 1 Jan 2019 23:56:26 +0100 Subject: [PATCH 10/13] - Basic Login --- CHANGELOG.md | 4 + app/build.gradle | 4 +- .../peertube/activity/AccountActivity.java | 63 +++++++- .../peertube/activity/LoginActivity.java | 26 ++++ .../network/AuthorizationInterceptor.java | 20 ++- .../peertube/network/GetUserService.java | 2 +- app/src/main/res/layout/activity_account.xml | 29 +++- app/src/main/res/layout/activity_login.xml | 139 ++++++++++-------- 8 files changed, 212 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc7448a..a3e7768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### Version 1.0.20 Tag: v1.0.20 (2019-01-02) + * Added basic login framework + * AR Strings update (@rex07) + ### Version 1.0.19 Tag: v1.0.19 (2018-12-31) * Video Language Filter (@lishoujun) diff --git a/app/build.gradle b/app/build.gradle index 80729aa..7d6b93b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "net.schueller.peertube" minSdkVersion 21 targetSdkVersion 28 - versionCode 1019 - versionName "1.0.19" + versionCode 1020 + versionName "1.0.20" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) diff --git a/app/src/main/java/net/schueller/peertube/activity/AccountActivity.java b/app/src/main/java/net/schueller/peertube/activity/AccountActivity.java index 095c1d4..755c5c3 100644 --- a/app/src/main/java/net/schueller/peertube/activity/AccountActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/AccountActivity.java @@ -29,16 +29,28 @@ import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.widget.TextView; import com.mikepenz.fontawesome_typeface_library.FontAwesome; import com.mikepenz.iconics.IconicsDrawable; import net.schueller.peertube.R; +import net.schueller.peertube.helper.APIUrlHelper; +import net.schueller.peertube.model.Me; +import net.schueller.peertube.model.OauthClient; +import net.schueller.peertube.model.Token; +import net.schueller.peertube.network.AuthenticationService; +import net.schueller.peertube.network.GetUserService; +import net.schueller.peertube.network.RetrofitInstance; import net.schueller.peertube.network.Session; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; import static net.schueller.peertube.helper.Constants.DEFAULT_THEME; import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY; @@ -46,6 +58,8 @@ import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY; public class AccountActivity extends AppCompatActivity { + private static final String TAG = "AccountActivity"; + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); @@ -70,6 +84,7 @@ public class AccountActivity extends AppCompatActivity { Intent intent = new Intent(this, LoginActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); this.startActivity(intent); + finish(); return true; default: break; @@ -78,6 +93,12 @@ public class AccountActivity extends AppCompatActivity { return super.onOptionsItemSelected(item); } + @Override + public boolean onSupportNavigateUp() { + finish(); // close this activity as oppose to navigating up + + return false; + } @Override protected void onCreate(Bundle savedInstanceState) { @@ -93,10 +114,16 @@ public class AccountActivity extends AppCompatActivity { setContentView(R.layout.activity_account); + // Attaching the layout to the toolbar object Toolbar toolbar = findViewById(R.id.tool_bar_user); // Setting toolbar as the ActionBar with setSupportActionBar() call setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeAsUpIndicator( + new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar() + ); + init(); } @@ -110,7 +137,41 @@ public class AccountActivity extends AppCompatActivity { // TODO - return false; + + String apiBaseURL = APIUrlHelper.getUrlWithVersion(this); + + GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); + + Call call = service.getMe(); + + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + + if (response.isSuccessful()) { + + Me me = response.body(); + + TextView username = findViewById(R.id.account_username); + TextView email = findViewById(R.id.account_email); + + username.setText(me.getUsername()); + email.setText(me.getEmail()); + + Log.v(TAG, me.getEmail()); + + } + + + } + + @Override + public void onFailure(Call call, Throwable t) { + + } + }); + + return true; } @Override diff --git a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java index 9ec1427..a1cc45c 100644 --- a/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/LoginActivity.java @@ -27,6 +27,10 @@ import android.util.Log; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.EditText; +import android.widget.Toast; + +import com.mikepenz.fontawesome_typeface_library.FontAwesome; +import com.mikepenz.iconics.IconicsDrawable; import net.schueller.peertube.R; import net.schueller.peertube.helper.APIUrlHelper; @@ -37,6 +41,7 @@ import net.schueller.peertube.network.RetrofitInstance; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -73,8 +78,24 @@ public class LoginActivity extends AppCompatActivity { mEmailView = findViewById(R.id.email); mPasswordView = findViewById(R.id.password); + + // Attaching the layout to the toolbar object + Toolbar toolbar = findViewById(R.id.tool_bar_login); + // Setting toolbar as the ActionBar with setSupportActionBar() call + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeAsUpIndicator( + new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar() + ); + } + @Override + public boolean onSupportNavigateUp() { + finish(); // close this activity as oppose to navigating up + + return false; + } private void attemptLogin() { @@ -139,8 +160,13 @@ public class LoginActivity extends AppCompatActivity { intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(intent); + finish(); // close this activity + } else { Log.wtf(TAG, response2.toString()); + + Toast.makeText(LoginActivity.this, "Login Error!", Toast.LENGTH_LONG).show(); + } } diff --git a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java index 438797e..37786c7 100644 --- a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java +++ b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java @@ -31,6 +31,8 @@ public class AuthorizationInterceptor implements Interceptor { public AuthorizationInterceptor() { } + + @Override public Response intercept(Chain chain) throws IOException { @@ -41,18 +43,20 @@ public class AuthorizationInterceptor implements Interceptor { if (session.isLoggedIn()) { - if (mainResponse.code() == 401 || mainResponse.code() == 403) { -// session.invalidate(); -// return mainResponse; - Log.v("Authorization", "Intercept code: " + mainResponse.code()); - - } - // add authentication header to each request if we are logged in Request.Builder builder = mainRequest.newBuilder().header("Authorization", session.getToken()). method(mainRequest.method(), mainRequest.body()); + // Log.v("Authorization", "Intercept: " + session.getToken()); + + // build request mainResponse = chain.proceed(builder.build()); - Log.v("Authorization", "Intercept: " + session.getToken()); + + // logout on auth error + if (mainResponse.code() == 401 || mainResponse.code() == 403) { + session.invalidate(); + Log.v("Authorization", "Intercept: Logout forced"); + } + } return mainResponse; diff --git a/app/src/main/java/net/schueller/peertube/network/GetUserService.java b/app/src/main/java/net/schueller/peertube/network/GetUserService.java index 7c4d459..850b9f5 100644 --- a/app/src/main/java/net/schueller/peertube/network/GetUserService.java +++ b/app/src/main/java/net/schueller/peertube/network/GetUserService.java @@ -11,7 +11,7 @@ import retrofit2.http.Query; public interface GetUserService { @GET("users/me") - Call getMe(@Header("Authorization") String authorization); + Call getMe(); @GET("users/me/subscriptions/videos") Call getVideosSubscripions( diff --git a/app/src/main/res/layout/activity_account.xml b/app/src/main/res/layout/activity_account.xml index bc4f3a5..bfa68ce 100644 --- a/app/src/main/res/layout/activity_account.xml +++ b/app/src/main/res/layout/activity_account.xml @@ -1,10 +1,11 @@ - + tools:context=".activity.AccountActivity" + android:orientation="vertical"> - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 9187735..6ea1ec6 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -3,74 +3,93 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" - android:orientation="vertical" - android:paddingBottom="@dimen/activity_vertical_margin" - android:paddingLeft="@dimen/activity_horizontal_margin" - android:paddingRight="@dimen/activity_horizontal_margin" - android:paddingTop="@dimen/activity_vertical_margin" - tools:context="net.schueller.peertube.activity.LoginActivity"> + android:orientation="vertical"> - - - + android:orientation="vertical"> - - - + android:elevation="4dp" /> - + + + + + + android:layout_height="match_parent"> - - - - - - - - - - - -