commit
cc5476e438
|
@ -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)
|
### Version 1.0.19 Tag: v1.0.19 (2018-12-31)
|
||||||
* Video Language Filter (@lishoujun)
|
* Video Language Filter (@lishoujun)
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ android {
|
||||||
applicationId "net.schueller.peertube"
|
applicationId "net.schueller.peertube"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 1019
|
versionCode 1020
|
||||||
versionName "1.0.19"
|
versionName "1.0.20"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
@ -71,3 +71,6 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation 'com.android.support.constraint:constraint-layout:+'
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:ignore="GoogleAppIndexingWarning">
|
tools:ignore="GoogleAppIndexingWarning"
|
||||||
|
android:name=".application.AppApplication">
|
||||||
|
|
||||||
<activity android:name=".activity.VideoListActivity"
|
<activity android:name=".activity.VideoListActivity"
|
||||||
android:theme="@style/AppTheme.NoActionBar"
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
|
@ -48,6 +49,14 @@
|
||||||
android:theme="@style/AppTheme.NoActionBar"
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
android:label="@string/title_activity_settings" />
|
android:label="@string/title_activity_settings" />
|
||||||
|
|
||||||
|
<activity android:name=".activity.SelectServerActivity"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar"/>
|
||||||
|
|
||||||
|
<activity android:name=".activity.AccountActivity"
|
||||||
|
android:label="@string/title_activity_account"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar"/>
|
||||||
|
|
||||||
|
|
||||||
<!-- Content provider for search suggestions -->
|
<!-- Content provider for search suggestions -->
|
||||||
<provider
|
<provider
|
||||||
android:name=".provider.SearchSuggestionsProvider"
|
android:name=".provider.SearchSuggestionsProvider"
|
||||||
|
@ -55,7 +64,9 @@
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
<activity android:name=".activity.SelectServerActivity"/>
|
|
||||||
<service android:name=".service.VideoPlayerService" />
|
<service android:name=".service.VideoPlayerService" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 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;
|
||||||
|
|
||||||
|
public class AccountActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
|
private static final String TAG = "AccountActivity";
|
||||||
|
|
||||||
|
@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);
|
||||||
|
finish();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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);
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
getSupportActionBar().setHomeAsUpIndicator(
|
||||||
|
new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
// try to get user data
|
||||||
|
getUserData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getUserData() {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
|
||||||
|
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
|
||||||
|
|
||||||
|
GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class);
|
||||||
|
|
||||||
|
Call<Me> call = service.getMe();
|
||||||
|
|
||||||
|
call.enqueue(new Callback<Me>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<Me> call, @NonNull Response<Me> 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<Me> call, Throwable t) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,16 +18,19 @@
|
||||||
|
|
||||||
package net.schueller.peertube.activity;
|
package net.schueller.peertube.activity;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AutoCompleteTextView;
|
import android.widget.AutoCompleteTextView;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
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.R;
|
||||||
import net.schueller.peertube.helper.APIUrlHelper;
|
import net.schueller.peertube.helper.APIUrlHelper;
|
||||||
|
@ -36,27 +39,23 @@ import net.schueller.peertube.model.Token;
|
||||||
import net.schueller.peertube.network.AuthenticationService;
|
import net.schueller.peertube.network.AuthenticationService;
|
||||||
import net.schueller.peertube.network.RetrofitInstance;
|
import net.schueller.peertube.network.RetrofitInstance;
|
||||||
|
|
||||||
import okhttp3.MediaType;
|
import androidx.annotation.NonNull;
|
||||||
import okhttp3.OkHttpClient;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
|
import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
|
||||||
import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
|
import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
|
||||||
|
|
||||||
public class LoginActivity extends AppCompatActivity {
|
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";
|
private String TAG = "LoginActivity";
|
||||||
|
|
||||||
|
|
||||||
// UI references.
|
// UI references.
|
||||||
private AutoCompleteTextView mEmailView;
|
private AutoCompleteTextView mEmailView;
|
||||||
private EditText mPasswordView;
|
private EditText mPasswordView;
|
||||||
private View mProgressView;
|
|
||||||
private View mLoginFormView;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -79,17 +78,30 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
mEmailView = findViewById(R.id.email);
|
mEmailView = findViewById(R.id.email);
|
||||||
mPasswordView = findViewById(R.id.password);
|
mPasswordView = findViewById(R.id.password);
|
||||||
|
|
||||||
// if (android.os.Build.VERSION.SDK_INT > 9) {
|
|
||||||
// StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
// Attaching the layout to the toolbar object
|
||||||
// StrictMode.setThreadPolicy(policy);
|
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() {
|
private void attemptLogin() {
|
||||||
|
|
||||||
|
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
Context context = this;
|
||||||
|
|
||||||
// Reset errors.
|
// Reset errors.
|
||||||
mEmailView.setError(null);
|
mEmailView.setError(null);
|
||||||
|
@ -106,15 +118,18 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class);
|
AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class);
|
||||||
|
|
||||||
Call<OauthClient> call = service.getOauthClientLocal();
|
Call<OauthClient> call = service.getOauthClientLocal();
|
||||||
|
|
||||||
call.enqueue(new Callback<OauthClient>() {
|
call.enqueue(new Callback<OauthClient>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull Call<OauthClient> call, @NonNull retrofit2.Response<OauthClient> response) {
|
public void onResponse(@NonNull Call<OauthClient> call, @NonNull Response<OauthClient> response) {
|
||||||
|
|
||||||
if (response.body() != null) {
|
if (response.isSuccessful()) {
|
||||||
|
|
||||||
|
OauthClient oauthClient = response.body();
|
||||||
|
|
||||||
Call<Token> call2 = service.getAuthenticationToken(
|
Call<Token> call2 = service.getAuthenticationToken(
|
||||||
response.body().getClientId(),
|
oauthClient.getClientId(),
|
||||||
response.body().getClientSecret(),
|
oauthClient.getClientSecret(),
|
||||||
"code",
|
"code",
|
||||||
"password",
|
"password",
|
||||||
"upload",
|
"upload",
|
||||||
|
@ -125,13 +140,33 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull Call<Token> call2, @NonNull retrofit2.Response<Token> response2) {
|
public void onResponse(@NonNull Call<Token> call2, @NonNull retrofit2.Response<Token> response2) {
|
||||||
|
|
||||||
if (response2.body() != null) {
|
if (response2.isSuccessful()) {
|
||||||
Log.wtf(TAG, response2.body().getAccessToken());
|
|
||||||
Log.wtf(TAG, response2.body().getExpiresIn());
|
Token token = response2.body();
|
||||||
Log.wtf(TAG, response2.body().getRefreshToken());
|
|
||||||
Log.wtf(TAG, response2.body().getTokenType());
|
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();
|
||||||
|
|
||||||
|
Log.wtf(TAG, "Logged in");
|
||||||
|
|
||||||
|
Intent intent = new Intent(context, AccountActivity.class);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
context.startActivity(intent);
|
||||||
|
|
||||||
|
finish(); // close this activity
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.wtf(TAG, response2.toString());
|
Log.wtf(TAG, response2.toString());
|
||||||
|
|
||||||
|
Toast.makeText(LoginActivity.this, "Login Error!", Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,10 @@ import net.schueller.peertube.R;
|
||||||
import net.schueller.peertube.adapter.VideoAdapter;
|
import net.schueller.peertube.adapter.VideoAdapter;
|
||||||
import net.schueller.peertube.helper.APIUrlHelper;
|
import net.schueller.peertube.helper.APIUrlHelper;
|
||||||
import net.schueller.peertube.model.VideoList;
|
import net.schueller.peertube.model.VideoList;
|
||||||
|
import net.schueller.peertube.network.GetUserService;
|
||||||
import net.schueller.peertube.network.GetVideoDataService;
|
import net.schueller.peertube.network.GetVideoDataService;
|
||||||
import net.schueller.peertube.network.RetrofitInstance;
|
import net.schueller.peertube.network.RetrofitInstance;
|
||||||
|
import net.schueller.peertube.network.Session;
|
||||||
import net.schueller.peertube.provider.SearchSuggestionsProvider;
|
import net.schueller.peertube.provider.SearchSuggestionsProvider;
|
||||||
import net.schueller.peertube.service.VideoPlayerService;
|
import net.schueller.peertube.service.VideoPlayerService;
|
||||||
|
|
||||||
|
@ -83,6 +85,7 @@ public class VideoListActivity extends AppCompatActivity {
|
||||||
private String sort = "-createdAt";
|
private String sort = "-createdAt";
|
||||||
private String filter = null;
|
private String filter = null;
|
||||||
private String searchQuery = "";
|
private String searchQuery = "";
|
||||||
|
private Boolean subscriptions = false;
|
||||||
|
|
||||||
private TextView emptyView;
|
private TextView emptyView;
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
|
@ -126,7 +129,7 @@ public class VideoListActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
MenuInflater inflater = getMenuInflater();
|
MenuInflater inflater = getMenuInflater();
|
||||||
inflater.inflate(R.menu.menu_main, menu);
|
inflater.inflate(R.menu.menu_top_videolist, menu);
|
||||||
|
|
||||||
// Set an icon in the ActionBar
|
// Set an icon in the ActionBar
|
||||||
menu.findItem(R.id.action_settings).setIcon(
|
menu.findItem(R.id.action_settings).setIcon(
|
||||||
|
@ -262,6 +265,9 @@ public class VideoListActivity extends AppCompatActivity {
|
||||||
Call<VideoList> call;
|
Call<VideoList> call;
|
||||||
if (!searchQuery.equals("")) {
|
if (!searchQuery.equals("")) {
|
||||||
call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter, languages);
|
call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter, languages);
|
||||||
|
} else if (subscriptions) {
|
||||||
|
GetUserService userService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class);
|
||||||
|
call = userService.getVideosSubscripions(start, count, sort);
|
||||||
} else {
|
} else {
|
||||||
call = service.getVideosData(start, count, sort, nsfw, filter, languages);
|
call = service.getVideosData(start, count, sort, nsfw, filter, languages);
|
||||||
}
|
}
|
||||||
|
@ -381,6 +387,7 @@ public class VideoListActivity extends AppCompatActivity {
|
||||||
sort = "-createdAt";
|
sort = "-createdAt";
|
||||||
currentStart = 0;
|
currentStart = 0;
|
||||||
filter = null;
|
filter = null;
|
||||||
|
subscriptions = false;
|
||||||
loadVideos(currentStart, count, sort, filter);
|
loadVideos(currentStart, count, sort, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,6 +399,7 @@ public class VideoListActivity extends AppCompatActivity {
|
||||||
sort = "-trending";
|
sort = "-trending";
|
||||||
currentStart = 0;
|
currentStart = 0;
|
||||||
filter = null;
|
filter = null;
|
||||||
|
subscriptions = false;
|
||||||
loadVideos(currentStart, count, sort, filter);
|
loadVideos(currentStart, count, sort, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,22 +411,42 @@ public class VideoListActivity extends AppCompatActivity {
|
||||||
sort = "-publishedAt";
|
sort = "-publishedAt";
|
||||||
filter = "local";
|
filter = "local";
|
||||||
currentStart = 0;
|
currentStart = 0;
|
||||||
|
subscriptions = false;
|
||||||
loadVideos(currentStart, count, sort, filter);
|
loadVideos(currentStart, count, sort, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
case R.id.navigation_subscriptions:
|
case R.id.navigation_subscriptions:
|
||||||
//Log.v(TAG, "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);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (!isLoading) {
|
||||||
|
sort = "-publishedAt";
|
||||||
|
filter = null;
|
||||||
|
currentStart = 0;
|
||||||
|
subscriptions = true;
|
||||||
|
loadVideos(currentStart, count, sort, filter);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case R.id.navigation_account:
|
case R.id.navigation_account:
|
||||||
//Log.v(TAG, "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);
|
if (!Session.getInstance().isLoggedIn()) {
|
||||||
// this.startActivity(intent);
|
Intent intent = new Intent(this, LoginActivity.class);
|
||||||
|
this.startActivity(intent);
|
||||||
|
} else {
|
||||||
|
Intent intent = new Intent(this, AccountActivity.class);
|
||||||
|
this.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,14 @@
|
||||||
*/
|
*/
|
||||||
package net.schueller.peertube.model;
|
package net.schueller.peertube.model;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class OauthClient {
|
public class OauthClient {
|
||||||
|
|
||||||
|
@SerializedName("client_id")
|
||||||
private String clientId;
|
private String clientId;
|
||||||
|
|
||||||
|
@SerializedName("client_secret")
|
||||||
private String clientSecret;
|
private String clientSecret;
|
||||||
|
|
||||||
public String getClientId() {
|
public String getClientId() {
|
||||||
|
|
|
@ -17,11 +17,20 @@
|
||||||
*/
|
*/
|
||||||
package net.schueller.peertube.model;
|
package net.schueller.peertube.model;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class Token {
|
public class Token {
|
||||||
|
|
||||||
|
@SerializedName("access_token")
|
||||||
private String accessToken;
|
private String accessToken;
|
||||||
|
|
||||||
|
@SerializedName("expires_in")
|
||||||
private String expiresIn;
|
private String expiresIn;
|
||||||
|
|
||||||
|
@SerializedName("refresh_token")
|
||||||
private String refreshToken;
|
private String refreshToken;
|
||||||
|
|
||||||
|
@SerializedName("token_type")
|
||||||
private String tokenType;
|
private String tokenType;
|
||||||
|
|
||||||
public String getAccessToken() {
|
public String getAccessToken() {
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.schueller.peertube.network;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
Session session = Session.getInstance();
|
||||||
|
|
||||||
|
Response mainResponse = chain.proceed(chain.request());
|
||||||
|
Request mainRequest = chain.request();
|
||||||
|
|
||||||
|
if (session.isLoggedIn()) {
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
|
||||||
|
// logout on auth error
|
||||||
|
if (mainResponse.code() == 401 || mainResponse.code() == 403) {
|
||||||
|
session.invalidate();
|
||||||
|
Log.v("Authorization", "Intercept: Logout forced");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return mainResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package net.schueller.peertube.network;
|
||||||
|
|
||||||
|
import net.schueller.peertube.model.Me;
|
||||||
|
import net.schueller.peertube.model.VideoList;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Header;
|
||||||
|
import retrofit2.http.Query;
|
||||||
|
|
||||||
|
public interface GetUserService {
|
||||||
|
|
||||||
|
@GET("users/me")
|
||||||
|
Call<Me> getMe();
|
||||||
|
|
||||||
|
@GET("users/me/subscriptions/videos")
|
||||||
|
Call<VideoList> getVideosSubscripions(
|
||||||
|
@Query("start") int start,
|
||||||
|
@Query("count") int count,
|
||||||
|
@Query("sort") String sort
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
package net.schueller.peertube.network;
|
package net.schueller.peertube.network;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
import retrofit2.Retrofit;
|
import retrofit2.Retrofit;
|
||||||
import retrofit2.converter.gson.GsonConverterFactory;
|
import retrofit2.converter.gson.GsonConverterFactory;
|
||||||
|
|
||||||
|
@ -28,7 +29,13 @@ public class RetrofitInstance {
|
||||||
public static Retrofit getRetrofitInstance(String newBaseUrl) {
|
public static Retrofit getRetrofitInstance(String newBaseUrl) {
|
||||||
if (retrofit == null || !newBaseUrl.equals(baseUrl)) {
|
if (retrofit == null || !newBaseUrl.equals(baseUrl)) {
|
||||||
baseUrl = newBaseUrl;
|
baseUrl = newBaseUrl;
|
||||||
|
|
||||||
|
OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder();
|
||||||
|
|
||||||
|
okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor());
|
||||||
|
|
||||||
retrofit = new retrofit2.Retrofit.Builder()
|
retrofit = new retrofit2.Retrofit.Builder()
|
||||||
|
.client(okhttpClientBuilder.build())
|
||||||
.baseUrl(baseUrl)
|
.baseUrl(baseUrl)
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
tools:context=".activity.AccountActivity"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar_user"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/tool_bar_user"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_scrollFlags="scroll|enterAlways"
|
||||||
|
android:elevation="4dp" />
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_marginBottom="0dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/account_username"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/account_email"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -3,74 +3,93 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="vertical"
|
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">
|
|
||||||
|
|
||||||
<!-- Login progress -->
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
<ProgressBar
|
android:id="@+id/appbar_login"
|
||||||
android:id="@+id/login_progress"
|
|
||||||
style="?android:attr/progressBarStyleLarge"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:id="@+id/login_form"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/email_login_form"
|
android:id="@+id/tool_bar_login"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:elevation="4dp" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<AutoCompleteTextView
|
<LinearLayout
|
||||||
android:id="@+id/email"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:gravity="center_horizontal"
|
||||||
android:hint="@string/prompt_email"
|
android:orientation="vertical"
|
||||||
android:inputType="textEmailAddress"
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:maxLines="1"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:singleLine="true" />
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
tools:context="net.schueller.peertube.activity.LoginActivity">
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/login_form"
|
||||||
android:layout_height="wrap_content">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="@string/prompt_password"
|
|
||||||
android:imeActionId="6"
|
|
||||||
android:imeActionLabel="@string/action_sign_in_short"
|
|
||||||
android:imeOptions="actionUnspecified"
|
|
||||||
android:inputType="textPassword"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:singleLine="true" />
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
<LinearLayout
|
||||||
|
android:id="@+id/email_login_form"
|
||||||
<Button
|
|
||||||
android:id="@+id/email_sign_in_button"
|
|
||||||
style="?android:textAppearanceSmall"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:orientation="vertical">
|
||||||
android:text="@string/action_sign_in"
|
|
||||||
android:textStyle="bold" />
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
</LinearLayout>
|
android:layout_width="match_parent"
|
||||||
</ScrollView>
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Alpha! Login is still in heavy development and may not work correctly!" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<AutoCompleteTextView
|
||||||
|
android:id="@+id/email"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt_email"
|
||||||
|
android:inputType="textEmailAddress"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt_password"
|
||||||
|
android:imeActionId="6"
|
||||||
|
android:imeActionLabel="@string/action_sign_in_short"
|
||||||
|
android:imeOptions="actionUnspecified"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/email_sign_in_button"
|
||||||
|
style="?android:textAppearanceSmall"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/action_sign_in"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:context="activity.VideoListActivity">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_logout"
|
||||||
|
android:orderInCategory="300"
|
||||||
|
android:title="@string/action_bar_title_logout"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
</menu>
|
|
@ -35,8 +35,8 @@
|
||||||
|
|
||||||
|
|
||||||
<!-- Strings related to Video meta data -->
|
<!-- Strings related to Video meta data -->
|
||||||
<string name="meta_data_seperator">\0020-\0020</string>
|
<string name="meta_data_seperator">\u0020-\u0020</string>
|
||||||
<string name="meta_data_views">\0020مشاهدات</string>
|
<string name="meta_data_views">\u0020 مشاهدات</string>
|
||||||
<string name="meta_data_owner_seperator">\@</string>
|
<string name="meta_data_owner_seperator">\@</string>
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
<string name="pref_title_torrent_player">مشغل فيديو التورنت</string>
|
<string name="pref_title_torrent_player">مشغل فيديو التورنت</string>
|
||||||
<string name="pref_description_torrent_player">تشغيل الفيديو عبر بث التورنت . يتطلب هذا أذونات التخزين. (ألفا ، غير مستقر!)</string>
|
<string name="pref_description_torrent_player">تشغيل الفيديو عبر بث التورنت . يتطلب هذا أذونات التخزين. (ألفا ، غير مستقر!)</string>
|
||||||
<string name="pref_title_license">الرخصة</string>
|
<string name="pref_title_license">الرخصة</string>
|
||||||
<string name="pref_description_license"><b >GNU Affero General Public License v3.0</b>\n
|
<string name="pref_description_license"><b >رخصة جنو العمومية v3.0</b>\n
|
||||||
\n
|
\n
|
||||||
إن أذونات هذا الترخيص الأقوى للحقوق المتروكة مشروطة بإتاحة الشفرة المصدرية الكاملة للأعمال والتعديلات المرخصة ، والتي تشتمل على أعمال أكبر باستخدام عمل مرخص ، تحت نفس الترخيص. يجب الحفاظ على حقوق النشر وإشعارات الترخيص. يقدم المساهمون منحة صريحة لحقوق البراءة. عند استخدام إصدار معدل لتوفير خدمة عبر شبكة ، يجب توفير شفرة المصدر الكاملة للإصدار المعدل.</string>
|
إن أذونات هذا الترخيص الأقوى للحقوق المتروكة مشروطة بإتاحة الشفرة المصدرية الكاملة للأعمال والتعديلات المرخصة ، والتي تشتمل على أعمال أكبر باستخدام عمل مرخص ، تحت نفس الترخيص. يجب الحفاظ على حقوق النشر وإشعارات الترخيص. يقدم المساهمون منحة صريحة لحقوق البراءة. عند استخدام إصدار معدل لتوفير خدمة عبر شبكة ، يجب توفير شفرة المصدر الكاملة للإصدار المعدل.</string>
|
||||||
<string name="pref_title_version">الإصدار</string>
|
<string name="pref_title_version">الإصدار</string>
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
|
|
||||||
|
|
||||||
<string name="pref_title_background_play">التشغيل في الخلفية</string>
|
<string name="pref_title_background_play">التشغيل في الخلفية</string>
|
||||||
<string name="pref_description_background_play">إن تم تنشيطه، ستواصل الفيديو في الإشتغال في الخلفية.</string>
|
<string name="pref_description_background_play">إن تم تنشيطه، سيستمر تشغيل الفيديو في الخلفية.</string>
|
||||||
<string name="bottom_nav_title_local">المحلي</string>
|
<string name="bottom_nav_title_local">المحلي</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<!-- Strings related to login -->
|
<!-- Strings related to login -->
|
||||||
<string name="prompt_server">Serveur</string>
|
<string name="prompt_server">Serveur</string>
|
||||||
<string name="prompt_email">Email</string>
|
<string name="prompt_email">Email</string>
|
||||||
<string name="prompt_password">Mot de passe (optionnel)</string>
|
<string name="prompt_password">Mot de passe</string>
|
||||||
<string name="action_sign_in">Connexion</string>
|
<string name="action_sign_in">Connexion</string>
|
||||||
<string name="action_sign_in_short">Connexion</string>
|
<string name="action_sign_in_short">Connexion</string>
|
||||||
<string name="error_invalid_email">Cette adresse mail n\'est pas valide</string>
|
<string name="error_invalid_email">Cette adresse mail n\'est pas valide</string>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<!-- Strings related to login -->
|
<!-- Strings related to login -->
|
||||||
<string name="prompt_server">Server</string>
|
<string name="prompt_server">Server</string>
|
||||||
<string name="prompt_email">Email</string>
|
<string name="prompt_email">Email</string>
|
||||||
<string name="prompt_password">Password (optional)</string>
|
<string name="prompt_password">Password</string>
|
||||||
<string name="action_sign_in">Sign in</string>
|
<string name="action_sign_in">Sign in</string>
|
||||||
<string name="action_sign_in_short">Sign in</string>
|
<string name="action_sign_in_short">Sign in</string>
|
||||||
<string name="error_invalid_email">This email address is invalid</string>
|
<string name="error_invalid_email">This email address is invalid</string>
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
<!-- Action bar -->
|
<!-- Action bar -->
|
||||||
<string name="action_bar_title_search">Search</string>
|
<string name="action_bar_title_search">Search</string>
|
||||||
<string name="action_bar_title_settings">Settings</string>
|
<string name="action_bar_title_settings">Settings</string>
|
||||||
|
<string name="action_bar_title_logout">Logout</string>
|
||||||
|
|
||||||
<!-- Bottom navigation bar -->
|
<!-- Bottom navigation bar -->
|
||||||
<string name="bottom_nav_title_home">Home</string>
|
<string name="bottom_nav_title_home">Home</string>
|
||||||
|
@ -293,4 +294,14 @@
|
||||||
<string name="pref_description_background_play">If enabled, continues to play video in background.</string>
|
<string name="pref_description_background_play">If enabled, continues to play video in background.</string>
|
||||||
<string name="bottom_nav_title_local">Local</string>
|
<string name="bottom_nav_title_local">Local</string>
|
||||||
|
|
||||||
|
<string name="title_activity_account">Account</string>
|
||||||
|
|
||||||
|
<!-- Constants, Don't translate -->
|
||||||
|
<string name="pref_token_access">pref_token_access</string>
|
||||||
|
<string name="pref_token_refresh">pref_token_refresh</string>
|
||||||
|
<string name="pref_token_expiration">pref_token_expiration</string>
|
||||||
|
<string name="pref_token_type">pref_token_type</string>
|
||||||
|
<string name="pref_auth_username">pref_auth_username</string>
|
||||||
|
<string name="pref_auth_password">pref_auth_password</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue