replaced VideoView with ExoPlayer, removed Twitter linking, removed unused classes and resources, version upgrade, bug fix
This commit is contained in:
parent
8bfd045f0a
commit
1cdf1b7d0a
|
@ -1,6 +1,5 @@
|
|||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'io.michaelrocks.paranoid'
|
||||
id 'ru.cleverpumpkin.proguard-dictionaries-generator'
|
||||
}
|
||||
|
||||
|
@ -13,8 +12,8 @@ android {
|
|||
applicationId 'org.nuclearfog.twidda'
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 33
|
||||
versionCode 79
|
||||
versionName '3.0.11'
|
||||
versionCode 80
|
||||
versionName '3.1'
|
||||
resConfigs 'en', 'de-rDE', 'zh-rCN'
|
||||
}
|
||||
|
||||
|
@ -40,10 +39,6 @@ android {
|
|||
excludes += ['/META-INF/CHANGES', '/META-INF/DEPENDENCIES', '/META-INF/README.md', '/META-INF/androidx.*', '/META-INF/kotlin*', '/META-INF/com.*', '/META-INF/services/**', '/META-INF/com/**', '/kotlin/**', '/Debug*']
|
||||
}
|
||||
}
|
||||
|
||||
paranoid {
|
||||
enabled true
|
||||
}
|
||||
}
|
||||
|
||||
proguardDictionaries {
|
||||
|
@ -54,8 +49,11 @@ proguardDictionaries {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.18.5'
|
||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.18.5'
|
||||
implementation 'com.google.android.exoplayer:extension-okhttp:2.18.5'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
|
|
|
@ -40,24 +40,6 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- DEPRECATED
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="twitter.com" />
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="www.twitter.com" />
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="mobile.twitter.com" />
|
||||
</intent-filter>
|
||||
-->
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
|
@ -102,7 +84,6 @@
|
|||
|
||||
<activity
|
||||
android:name=".ui.activities.VideoViewer"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Transparency" />
|
||||
|
||||
<activity
|
||||
|
|
|
@ -181,29 +181,6 @@
|
|||
limitations under the License.
|
||||
</pre>
|
||||
|
||||
<h3>Notices for libraries:</h3>
|
||||
<ul>
|
||||
<li>paranoid</li>
|
||||
</ul>
|
||||
<pre>
|
||||
Copyright 2021 Michael Rozumyanskiy
|
||||
Licensed under the Apache License,
|
||||
Version 2.0 (the "License");
|
||||
you may not use this file except
|
||||
in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law
|
||||
or agreed to in writing,
|
||||
software distributed under the License
|
||||
is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS
|
||||
OF ANY KIND, either express or implied.
|
||||
See the License for the specific
|
||||
language governing permissions and
|
||||
limitations under the License.
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -5,14 +5,11 @@ import android.content.Context;
|
|||
import org.nuclearfog.twidda.config.GlobalSettings;
|
||||
import org.nuclearfog.twidda.model.Account;
|
||||
|
||||
import io.michaelrocks.paranoid.Obfuscate;
|
||||
|
||||
/**
|
||||
* this class manages Twitter oauth 1.0 keys (consumer token & token secret) for API V1.1 & V2
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
@Obfuscate
|
||||
public class Tokens {
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,6 +40,7 @@ public class MediaV1 implements Media {
|
|||
|
||||
private int type = NONE;
|
||||
private String url = "";
|
||||
private String previewUrl = "";
|
||||
private String key;
|
||||
|
||||
/**
|
||||
|
@ -53,6 +54,7 @@ public class MediaV1 implements Media {
|
|||
String url = json.getString("media_url_https");
|
||||
if (Patterns.WEB_URL.matcher(url).matches()) {
|
||||
this.url = url;
|
||||
previewUrl = url;
|
||||
} else {
|
||||
throw new JSONException("invalid url: \"" + url + "\"");
|
||||
}
|
||||
|
@ -62,6 +64,7 @@ public class MediaV1 implements Media {
|
|||
case TYPE_VIDEO:
|
||||
int maxBitrate = -1;
|
||||
JSONArray videoVariants = json.getJSONObject("video_info").getJSONArray("variants");
|
||||
previewUrl = json.optString("media_url_https", "");
|
||||
for (int i = 0; i < videoVariants.length(); i++) {
|
||||
JSONObject variant = videoVariants.getJSONObject(i);
|
||||
int bitRate = variant.optInt("bitrate", 0);
|
||||
|
@ -80,6 +83,7 @@ public class MediaV1 implements Media {
|
|||
|
||||
case TYPE_GIF:
|
||||
JSONArray gifVariants = json.getJSONObject("video_info").getJSONArray("variants");
|
||||
previewUrl = json.optString("media_url_https", "");
|
||||
for (int i = 0; i < gifVariants.length(); i++) {
|
||||
JSONObject gifVariant = gifVariants.getJSONObject(i);
|
||||
if (MIME_V_MP4.equals(gifVariant.getString("content_type"))) {
|
||||
|
@ -118,7 +122,7 @@ public class MediaV1 implements Media {
|
|||
|
||||
@Override
|
||||
public String getPreviewUrl() {
|
||||
return url;
|
||||
return previewUrl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
package org.nuclearfog.twidda.backend.async;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.nuclearfog.twidda.backend.api.Connection;
|
||||
import org.nuclearfog.twidda.backend.api.ConnectionException;
|
||||
import org.nuclearfog.twidda.backend.api.ConnectionManager;
|
||||
import org.nuclearfog.twidda.model.User;
|
||||
import org.nuclearfog.twidda.model.UserList;
|
||||
import org.nuclearfog.twidda.ui.activities.MainActivity;
|
||||
import org.nuclearfog.twidda.ui.activities.ProfileActivity;
|
||||
import org.nuclearfog.twidda.ui.activities.SearchActivity;
|
||||
import org.nuclearfog.twidda.ui.activities.StatusActivity;
|
||||
import org.nuclearfog.twidda.ui.activities.StatusEditor;
|
||||
import org.nuclearfog.twidda.ui.activities.UserlistActivity;
|
||||
import org.nuclearfog.twidda.ui.activities.UserlistsActivity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class handles deep links and starts activities to show the content
|
||||
* When the user clicks on a link (e.g. "twitter.com/Twitter/status/1480571976414543875")
|
||||
* this class extracts information of the link and open an activity tp show the content
|
||||
* When a link type isn't supported, the {@link MainActivity} will be opened instead
|
||||
*
|
||||
* @author nuclearfog
|
||||
* @see MainActivity
|
||||
*/
|
||||
public class LinkLoader extends AsyncExecutor<Uri, LinkLoader.LinkResult> {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public LinkLoader(Context context) {
|
||||
connection = ConnectionManager.getDefaultConnection(context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected LinkResult doInBackground(@NonNull Uri link) {
|
||||
try {
|
||||
List<String> pathSeg = link.getPathSegments();
|
||||
Bundle data = new Bundle();
|
||||
if (!pathSeg.isEmpty()) {
|
||||
// open home timeline tab
|
||||
// e.g. twitter.com/home
|
||||
if (pathSeg.get(0).equals("home")) {
|
||||
data.putInt(MainActivity.KEY_TAB_PAGE, 0);
|
||||
return new LinkResult(data, MainActivity.class);
|
||||
}
|
||||
// open trend tab
|
||||
// e.g. twitter.com/trends , twitter.com/explore or twitter.com/i/trends
|
||||
else if (pathSeg.get(0).equals("trends") || pathSeg.get(0).equals("explore") ||
|
||||
(pathSeg.size() == 2 && pathSeg.get(0).equals("i") && pathSeg.get(1).equals("trends"))) {
|
||||
data.putInt(MainActivity.KEY_TAB_PAGE, 1);
|
||||
return new LinkResult(data, MainActivity.class);
|
||||
}
|
||||
// open mentions timeline
|
||||
// e.g. twitter.com/notifications
|
||||
else if (pathSeg.get(0).equals("notifications")) {
|
||||
data.putInt(MainActivity.KEY_TAB_PAGE, 2);
|
||||
return new LinkResult(data, MainActivity.class);
|
||||
}
|
||||
// open directmessage page
|
||||
// e.g. twitter.com/messages
|
||||
else if (pathSeg.get(0).equals("messages")) {
|
||||
data.putInt(MainActivity.KEY_TAB_PAGE, 3);
|
||||
return new LinkResult(data, MainActivity.class);
|
||||
}
|
||||
// open twitter search
|
||||
// e.g. twitter.com/search?q={search string}
|
||||
else if (pathSeg.get(0).equals("search")) {
|
||||
if (link.isHierarchical()) {
|
||||
String search = link.getQueryParameter("q");
|
||||
if (search != null) {
|
||||
data.putString(SearchActivity.KEY_SEARCH_QUERY, search);
|
||||
return new LinkResult(data, SearchActivity.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
// open status editor and add text
|
||||
// e.g. twitter.com/share or twitter.com/intent/status
|
||||
else if (pathSeg.get(0).equals("share") ||
|
||||
(pathSeg.size() == 2 && pathSeg.get(0).equals("intent") && pathSeg.get(1).equals("tweet"))) {
|
||||
if (link.isHierarchical()) {
|
||||
String status = "";
|
||||
String text = link.getQueryParameter("text");
|
||||
String url = link.getQueryParameter("url");
|
||||
String via = link.getQueryParameter("via");
|
||||
if (text != null)
|
||||
status = text + " ";
|
||||
if (url != null)
|
||||
status += url + " ";
|
||||
if (via != null)
|
||||
status += "via @" + via;
|
||||
data.putString(StatusEditor.KEY_STATUS_EDITOR_TEXT, status);
|
||||
return new LinkResult(data, StatusEditor.class);
|
||||
}
|
||||
}
|
||||
// open hashtag search
|
||||
// e.g. twitter.com/hashtag/{hashtag name}
|
||||
else if (pathSeg.size() == 2 && pathSeg.get(0).equals("hashtag")) {
|
||||
String search = '#' + pathSeg.get(1);
|
||||
data.putString(SearchActivity.KEY_SEARCH_QUERY, search);
|
||||
return new LinkResult(data, SearchActivity.class);
|
||||
}
|
||||
// open an userlist
|
||||
// e.g. twitter.com/i/lists/{list id}
|
||||
else if (pathSeg.size() == 3 && pathSeg.get(0).equals("i") && pathSeg.get(1).equals("lists") && pathSeg.get(2).matches("\\d+")) {
|
||||
long listId = Long.parseLong(pathSeg.get(2));
|
||||
UserList list = connection.getUserlist(listId);
|
||||
data.putSerializable(UserlistActivity.KEY_LIST_DATA, list);
|
||||
data.putBoolean(UserlistActivity.KEY_LIST_NO_UPDATE, true);
|
||||
return new LinkResult(data, UserlistActivity.class);
|
||||
}
|
||||
// show status
|
||||
// e.g. twitter.com/{screenname}/status/{tweet ID}
|
||||
else if (pathSeg.size() == 3 && pathSeg.get(1).equals("status") && pathSeg.get(2).matches("\\d+")) {
|
||||
String screenname = pathSeg.get(0);
|
||||
long Id = Long.parseLong(pathSeg.get(2));
|
||||
data.putLong(StatusActivity.KEY_STATUS_ID, Id);
|
||||
data.putString(StatusActivity.KEY_STATUS_NAME, screenname);
|
||||
return new LinkResult(data, StatusActivity.class);
|
||||
}
|
||||
// show userlists
|
||||
// e.g. twitter.com/{screenname}/lists
|
||||
else if (pathSeg.size() == 2 && pathSeg.get(1).equals("lists")) {
|
||||
String screenname = pathSeg.get(0);
|
||||
User user = connection.showUser(screenname);
|
||||
data.putLong(UserlistsActivity.KEY_USERLIST_OWNER_ID, user.getId());
|
||||
return new LinkResult(data, UserlistsActivity.class);
|
||||
}
|
||||
// show user profile
|
||||
// e.g. twitter.com/{screenname}
|
||||
else if (pathSeg.size() == 1 || (pathSeg.size() == 2 &&
|
||||
(pathSeg.get(1).equals("with_replies") || pathSeg.get(1).equals("media") || pathSeg.get(1).equals("likes")))) {
|
||||
String screenname = pathSeg.get(0);
|
||||
User user = connection.showUser(screenname);
|
||||
data.putSerializable(ProfileActivity.KEY_PROFILE_USER, user);
|
||||
return new LinkResult(data, ProfileActivity.class);
|
||||
}
|
||||
}
|
||||
} catch (ConnectionException exception) {
|
||||
return new LinkResult(null, null, exception);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new LinkResult(null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holder class for information to start an activity
|
||||
*/
|
||||
public static class LinkResult {
|
||||
|
||||
@Nullable
|
||||
public final Bundle data;
|
||||
@Nullable
|
||||
public final Class<? extends Activity> activity;
|
||||
@Nullable
|
||||
public final ConnectionException exception;
|
||||
|
||||
LinkResult(@NonNull Bundle data, @Nullable Class<? extends Activity> activity) {
|
||||
this(data, activity, null);
|
||||
}
|
||||
|
||||
LinkResult(@Nullable Bundle data, @Nullable Class<? extends Activity> activity, @Nullable ConnectionException exception) {
|
||||
this.data = data;
|
||||
this.activity = activity;
|
||||
this.exception = exception;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package org.nuclearfog.twidda.backend.async;
|
||||
|
||||
import org.nuclearfog.twidda.ui.activities.VideoViewer;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* This class updates {@link VideoViewer}'s Seekbar while playing a video
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class SeekbarUpdater implements Runnable {
|
||||
|
||||
private ScheduledExecutorService updater;
|
||||
private WeakReference<VideoViewer> weakRef;
|
||||
|
||||
private Runnable seekUpdate = new Runnable() {
|
||||
public void run() {
|
||||
VideoViewer mediaViewer = weakRef.get();
|
||||
if (mediaViewer != null) {
|
||||
mediaViewer.updateSeekBar();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public SeekbarUpdater(VideoViewer activity, int milliseconds) {
|
||||
weakRef = new WeakReference<>(activity);
|
||||
updater = Executors.newScheduledThreadPool(1);
|
||||
updater.scheduleWithFixedDelay(this, milliseconds, milliseconds, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
VideoViewer mediaViewer = weakRef.get();
|
||||
if (mediaViewer != null) {
|
||||
mediaViewer.runOnUiThread(seekUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shutdown updater
|
||||
*/
|
||||
public void shutdown() {
|
||||
updater.shutdown();
|
||||
}
|
||||
}
|
|
@ -111,28 +111,6 @@ public class StringTools {
|
|||
return resources.getString(R.string.time_now);
|
||||
}
|
||||
|
||||
/**
|
||||
* format media time to string
|
||||
*
|
||||
* @param time duration/current position in ms
|
||||
* @return time string
|
||||
*/
|
||||
public static String formatMediaTime(int time) {
|
||||
String result = "";
|
||||
int seconds = (time / 1000) % 60;
|
||||
int minutes = (time / 60000) % 60;
|
||||
|
||||
if (minutes < 10)
|
||||
result += "0";
|
||||
result += minutes + ":";
|
||||
|
||||
if (seconds < 10)
|
||||
result += "0";
|
||||
result += seconds;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* un-escape html based text
|
||||
*
|
||||
|
|
|
@ -90,7 +90,6 @@ public class GlobalSettings {
|
|||
private static final String PROXY_PORT = "proxy_port";
|
||||
private static final String PROXY_USER = "proxy_user";
|
||||
private static final String PROXY_PASS = "proxy_pass";
|
||||
private static final String PROXY_IGNORE = "ignore_proxy_set";
|
||||
private static final String TREND_LOC = "location";
|
||||
private static final String TREND_ID = "world_id_long";
|
||||
private static final String ENABLE_LIKE = "like_enable";
|
||||
|
@ -140,7 +139,6 @@ public class GlobalSettings {
|
|||
private boolean loggedIn;
|
||||
private boolean isProxyEnabled;
|
||||
private boolean isProxyAuthSet;
|
||||
private boolean ignoreProxyWarning;
|
||||
private boolean toolbarOverlap;
|
||||
private boolean tweetIndicators;
|
||||
private boolean filterResults;
|
||||
|
@ -860,27 +858,6 @@ public class GlobalSettings {
|
|||
return isProxyAuthSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if proxy warning should be ignored
|
||||
*
|
||||
* @return true if proxy warning should be ignored
|
||||
*/
|
||||
public boolean ignoreProxyWarning() {
|
||||
return ignoreProxyWarning;
|
||||
}
|
||||
|
||||
/**
|
||||
* enable/ignore proxy warning
|
||||
*
|
||||
* @param ignore true to ignore proxy warning
|
||||
*/
|
||||
public void setIgnoreProxyWarning(boolean ignore) {
|
||||
ignoreProxyWarning = ignore;
|
||||
Editor e = settings.edit();
|
||||
e.putBoolean(PROXY_IGNORE, ignore);
|
||||
e.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current user is logged in
|
||||
*
|
||||
|
@ -986,7 +963,6 @@ public class GlobalSettings {
|
|||
listSize = settings.getInt(LIST_SIZE, DEFAULT_LIST_SIZE);
|
||||
isProxyEnabled = settings.getBoolean(PROXY_SET, false);
|
||||
isProxyAuthSet = settings.getBoolean(AUTH_SET, false);
|
||||
ignoreProxyWarning = settings.getBoolean(PROXY_IGNORE, false);
|
||||
loggedIn = settings.getBoolean(LOGGED_IN, false);
|
||||
loadImage = settings.getBoolean(IMAGE_LOAD, true);
|
||||
tweetIndicators = settings.getBoolean(TWEET_INDICATOR, true);
|
||||
|
|
|
@ -30,11 +30,7 @@ import com.google.android.material.tabs.TabLayout.OnTabSelectedListener;
|
|||
import com.google.android.material.tabs.TabLayout.Tab;
|
||||
|
||||
import org.nuclearfog.twidda.R;
|
||||
import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback;
|
||||
import org.nuclearfog.twidda.backend.async.LinkLoader;
|
||||
import org.nuclearfog.twidda.backend.async.LinkLoader.LinkResult;
|
||||
import org.nuclearfog.twidda.backend.utils.AppStyles;
|
||||
import org.nuclearfog.twidda.backend.utils.ErrorHandler;
|
||||
import org.nuclearfog.twidda.config.GlobalSettings;
|
||||
import org.nuclearfog.twidda.ui.adapter.FragmentAdapter;
|
||||
import org.nuclearfog.twidda.ui.dialogs.ProgressDialog;
|
||||
|
@ -44,13 +40,7 @@ import org.nuclearfog.twidda.ui.dialogs.ProgressDialog;
|
|||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class MainActivity extends AppCompatActivity implements ActivityResultCallback<ActivityResult>, OnTabSelectedListener, OnQueryTextListener, AsyncCallback<LinkResult> {
|
||||
|
||||
/**
|
||||
* key used to set the tab page
|
||||
* vale type is Integer
|
||||
*/
|
||||
public static final String KEY_TAB_PAGE = "tab_pos";
|
||||
public class MainActivity extends AppCompatActivity implements ActivityResultCallback<ActivityResult>, OnTabSelectedListener, OnQueryTextListener {
|
||||
|
||||
private ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this);
|
||||
|
||||
|
@ -106,12 +96,6 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal
|
|||
// initialize lists
|
||||
else if (adapter.isEmpty()) {
|
||||
setupAdapter(true);
|
||||
// check if there is a Twitter link
|
||||
if (getIntent().getData() != null) {
|
||||
LinkLoader linkLoader = new LinkLoader(this);
|
||||
linkLoader.execute(getIntent().getData(), this);
|
||||
loadingCircle.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,29 +241,6 @@ public class MainActivity extends AppCompatActivity implements ActivityResultCal
|
|||
adapter.scrollToTop(tab.getPosition());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResult(@NonNull LinkResult linkResult) {
|
||||
loadingCircle.dismiss();
|
||||
if (linkResult.data != null && linkResult.activity != null) {
|
||||
if (linkResult.activity == MainActivity.class) {
|
||||
int page = linkResult.data.getInt(KEY_TAB_PAGE, 0);
|
||||
pager.setCurrentItem(page);
|
||||
} else {
|
||||
Intent intent = new Intent(this, linkResult.activity);
|
||||
intent.putExtras(linkResult.data);
|
||||
startActivity(intent);
|
||||
}
|
||||
} else {
|
||||
if (linkResult.exception != null) {
|
||||
String message = ErrorHandler.getErrorMessage(this, linkResult.exception);
|
||||
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(getApplicationContext(), R.string.error_open_link, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize pager content
|
||||
*/
|
||||
|
|
|
@ -158,7 +158,7 @@ public class MessageEditor extends MediaActivity implements OnClickListener, OnC
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
// retry sending message
|
||||
if (type == ConfirmDialog.MESSAGE_EDITOR_ERROR) {
|
||||
sendMessage();
|
||||
|
|
|
@ -587,7 +587,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
if (user != null) {
|
||||
// confirmed unfollowing user
|
||||
if (type == ConfirmDialog.PROFILE_UNFOLLOW) {
|
||||
|
|
|
@ -239,7 +239,7 @@ public class ProfileEditor extends MediaActivity implements OnClickListener, Asy
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
// leave without settings
|
||||
if (type == ConfirmDialog.PROFILE_EDITOR_LEAVE) {
|
||||
finish();
|
||||
|
|
|
@ -308,7 +308,7 @@ public class SettingsActivity extends AppCompatActivity implements OnClickListen
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
// confirm log out
|
||||
if (type == ConfirmDialog.APP_LOG_OUT) {
|
||||
// remove account from database
|
||||
|
@ -692,7 +692,6 @@ public class SettingsActivity extends AppCompatActivity implements OnClickListen
|
|||
}
|
||||
} else {
|
||||
settings.clearProxyServer();
|
||||
settings.setIgnoreProxyWarning(false);
|
||||
}
|
||||
return checkPassed;
|
||||
}
|
||||
|
|
|
@ -668,35 +668,16 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
switch (type) {
|
||||
case ConfirmDialog.DELETE_STATUS:
|
||||
if (status != null) {
|
||||
long id = status.getId();
|
||||
if (status.getEmbeddedStatus() != null) {
|
||||
id = status.getEmbeddedStatus().getId();
|
||||
}
|
||||
StatusParam param = new StatusParam(StatusParam.DELETE, id);
|
||||
statusLoader.execute(param, statusCallback);
|
||||
public void onConfirm(int type) {
|
||||
if (type == ConfirmDialog.DELETE_STATUS) {
|
||||
if (status != null) {
|
||||
long id = status.getId();
|
||||
if (status.getEmbeddedStatus() != null) {
|
||||
id = status.getEmbeddedStatus().getId();
|
||||
}
|
||||
break;
|
||||
|
||||
case ConfirmDialog.PROXY_CONFIRM:
|
||||
if (status != null) {
|
||||
settings.setIgnoreProxyWarning(rememberChoice);
|
||||
Media[] mediaItems = status.getMedia();
|
||||
if (status.getEmbeddedStatus() != null) {
|
||||
mediaItems = status.getEmbeddedStatus().getMedia();
|
||||
}
|
||||
if (mediaItems.length > 0) {
|
||||
Uri uri = Uri.parse(mediaItems[0].getUrl());
|
||||
Intent intent = new Intent(this, VideoViewer.class);
|
||||
intent.putExtra(VideoViewer.VIDEO_URI, uri);
|
||||
intent.putExtra(VideoViewer.ENABLE_VIDEO_CONTROLS, true);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
break;
|
||||
StatusParam param = new StatusParam(StatusParam.DELETE, id);
|
||||
statusLoader.execute(param, statusCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -730,23 +711,15 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
|||
mediaIntent.putExtra(ImageViewer.IMAGE_URI, uri);
|
||||
startActivity(mediaIntent);
|
||||
} else if (media.getMediaType() == Media.VIDEO) {
|
||||
if (!settings.isProxyEnabled() || settings.ignoreProxyWarning()) {
|
||||
Intent intent = new Intent(this, VideoViewer.class);
|
||||
intent.putExtra(VideoViewer.VIDEO_URI, uri);
|
||||
intent.putExtra(VideoViewer.ENABLE_VIDEO_CONTROLS, true);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
confirmDialog.show(ConfirmDialog.PROXY_CONFIRM);
|
||||
}
|
||||
Intent intent = new Intent(this, VideoViewer.class);
|
||||
intent.putExtra(VideoViewer.VIDEO_URI, uri);
|
||||
intent.putExtra(VideoViewer.ENABLE_VIDEO_CONTROLS, true);
|
||||
startActivity(intent);
|
||||
} else if (media.getMediaType() == Media.GIF) {
|
||||
if (!settings.isProxyEnabled() || settings.ignoreProxyWarning()) {
|
||||
Intent intent = new Intent(this, VideoViewer.class);
|
||||
intent.putExtra(VideoViewer.VIDEO_URI, uri);
|
||||
intent.putExtra(VideoViewer.ENABLE_VIDEO_CONTROLS, false);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
confirmDialog.show(ConfirmDialog.PROXY_CONFIRM);
|
||||
}
|
||||
Intent intent = new Intent(this, VideoViewer.class);
|
||||
intent.putExtra(VideoViewer.VIDEO_URI, uri);
|
||||
intent.putExtra(VideoViewer.ENABLE_VIDEO_CONTROLS, false);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ public class StatusEditor extends MediaActivity implements OnClickListener, OnPr
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
// retry uploading status
|
||||
if (type == ConfirmDialog.STATUS_EDITOR_ERROR) {
|
||||
updateStatus();
|
||||
|
|
|
@ -282,7 +282,7 @@ public class UserlistActivity extends AppCompatActivity implements ActivityResul
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
// delete user list
|
||||
if (type == ConfirmDialog.LIST_DELETE && userList != null) {
|
||||
if (listLoaderAsync.isIdle()) {
|
||||
|
|
|
@ -156,7 +156,7 @@ public class UserlistEditor extends AppCompatActivity implements OnClickListener
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
// retry updating list
|
||||
if (type == ConfirmDialog.LIST_EDITOR_ERROR) {
|
||||
updateList();
|
||||
|
|
|
@ -1,65 +1,42 @@
|
|||
package org.nuclearfog.twidda.ui.activities;
|
||||
|
||||
import static android.media.MediaPlayer.MEDIA_ERROR_UNKNOWN;
|
||||
import static android.media.MediaPlayer.MEDIA_INFO_BUFFERING_END;
|
||||
import static android.media.MediaPlayer.MEDIA_INFO_BUFFERING_START;
|
||||
import static android.media.MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START;
|
||||
import static android.media.MediaPlayer.OnCompletionListener;
|
||||
import static android.media.MediaPlayer.OnErrorListener;
|
||||
import static android.media.MediaPlayer.OnInfoListener;
|
||||
import static android.media.MediaPlayer.OnPreparedListener;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.OnClickListener;
|
||||
import static android.view.View.OnTouchListener;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.location.Location;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
|
||||
import org.nuclearfog.twidda.R;
|
||||
import org.nuclearfog.twidda.backend.async.SeekbarUpdater;
|
||||
import org.nuclearfog.twidda.backend.utils.AppStyles;
|
||||
import org.nuclearfog.twidda.backend.utils.StringTools;
|
||||
import org.nuclearfog.twidda.backend.utils.ConnectionBuilder;
|
||||
import org.nuclearfog.twidda.config.GlobalSettings;
|
||||
import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog;
|
||||
import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener;
|
||||
|
||||
import okhttp3.Call;
|
||||
|
||||
/**
|
||||
* video player activity to show local and online videos/animations
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class VideoViewer extends MediaActivity implements OnSeekBarChangeListener, OnCompletionListener, OnDismissListener,
|
||||
OnPreparedListener, OnInfoListener, OnErrorListener, OnClickListener, OnTouchListener, OnConfirmListener {
|
||||
public class VideoViewer extends AppCompatActivity {
|
||||
|
||||
/**
|
||||
* key for an Uri array with local links
|
||||
|
@ -73,58 +50,10 @@ public class VideoViewer extends MediaActivity implements OnSeekBarChangeListene
|
|||
*/
|
||||
public static final String ENABLE_VIDEO_CONTROLS = "enable_controls";
|
||||
|
||||
/**
|
||||
* playback status used if player is idle
|
||||
*/
|
||||
private static final int IDLE = -1;
|
||||
|
||||
/**
|
||||
* playback status used for "play" mode
|
||||
*/
|
||||
private static final int PLAY = 1;
|
||||
|
||||
/**
|
||||
* playback status used for "pause" mode
|
||||
*/
|
||||
private static final int PAUSE = 2;
|
||||
|
||||
/**
|
||||
* playback status used for "forward" mode
|
||||
*/
|
||||
private static final int FORWARD = 3;
|
||||
|
||||
/**
|
||||
* playback status used for "backward" mode
|
||||
*/
|
||||
private static final int BACKWARD = 4;
|
||||
|
||||
/**
|
||||
* refresh time for video progress update in milliseconds
|
||||
*/
|
||||
private static final int PROGRESS_UPDATE = 1000;
|
||||
|
||||
/**
|
||||
* speed ratio for "backward" and "forward"
|
||||
*/
|
||||
private static final int SPEED_FACTOR = 6;
|
||||
|
||||
@Nullable
|
||||
private SeekbarUpdater seekUpdate;
|
||||
private GlobalSettings settings;
|
||||
private ExoPlayer player;
|
||||
|
||||
private ConfirmDialog confirmDialog;
|
||||
|
||||
private TextView duration, position;
|
||||
private ProgressBar loadingCircle;
|
||||
private SeekBar video_progress;
|
||||
private ImageButton playPause;
|
||||
private VideoView videoView;
|
||||
private ViewGroup controlPanel;
|
||||
|
||||
private Uri link;
|
||||
private boolean enableVideoExtras;
|
||||
private int playStatus = IDLE;
|
||||
|
||||
private Uri data;
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context newBase) {
|
||||
|
@ -136,318 +65,68 @@ public class VideoViewer extends MediaActivity implements OnSeekBarChangeListene
|
|||
protected void onCreate(@Nullable Bundle b) {
|
||||
super.onCreate(b);
|
||||
setContentView(R.layout.page_video);
|
||||
ImageButton forward = findViewById(R.id.controller_forward);
|
||||
ImageButton backward = findViewById(R.id.controller_backward);
|
||||
ImageButton share = findViewById(R.id.controller_share);
|
||||
loadingCircle = findViewById(R.id.media_progress);
|
||||
controlPanel = findViewById(R.id.media_controlpanel);
|
||||
videoView = findViewById(R.id.video_view);
|
||||
video_progress = findViewById(R.id.controller_progress);
|
||||
playPause = findViewById(R.id.controller_play);
|
||||
duration = findViewById(R.id.controller_duration);
|
||||
position = findViewById(R.id.controller_position);
|
||||
|
||||
confirmDialog = new ConfirmDialog(this);
|
||||
ViewGroup root = findViewById(R.id.page_video_root);
|
||||
StyledPlayerView playerView = findViewById(R.id.page_video_player);
|
||||
Toolbar toolbar = findViewById(R.id.page_video_toolbar);
|
||||
|
||||
player = new ExoPlayer.Builder(this).build();
|
||||
settings = GlobalSettings.getInstance(this);
|
||||
AppStyles.setProgressColor(loadingCircle, settings.getHighlightColor());
|
||||
AppStyles.setTheme(controlPanel);
|
||||
videoView.setZOrderMediaOverlay(true); // disable black background
|
||||
videoView.getHolder().setFormat(PixelFormat.TRANSPARENT);
|
||||
|
||||
// get extras
|
||||
enableVideoExtras = getIntent().getBooleanExtra(ENABLE_VIDEO_CONTROLS, false);
|
||||
Parcelable data = getIntent().getParcelableExtra(VIDEO_URI);
|
||||
|
||||
if (data instanceof Uri) {
|
||||
link = (Uri) data;
|
||||
// enable control bar if set
|
||||
if (enableVideoExtras) {
|
||||
controlPanel.setVisibility(VISIBLE);
|
||||
if (link.getScheme().startsWith("http")) {
|
||||
// attach link to share button
|
||||
share.setTag(link);
|
||||
} else {
|
||||
share.setVisibility(GONE);
|
||||
}
|
||||
seekUpdate = new SeekbarUpdater(this, PROGRESS_UPDATE);
|
||||
}
|
||||
videoView.setVideoURI(link);
|
||||
AppStyles.setTheme(root);
|
||||
if (toolbar != null) {
|
||||
setSupportActionBar(toolbar);
|
||||
toolbar.setTitle("");
|
||||
}
|
||||
share.setOnClickListener(this);
|
||||
playPause.setOnClickListener(this);
|
||||
videoView.setOnTouchListener(this);
|
||||
backward.setOnTouchListener(this);
|
||||
forward.setOnTouchListener(this);
|
||||
videoView.setOnPreparedListener(this);
|
||||
videoView.setOnCompletionListener(this);
|
||||
videoView.setOnErrorListener(this);
|
||||
video_progress.setOnSeekBarChangeListener(this);
|
||||
confirmDialog.setConfirmListener(this);
|
||||
confirmDialog.setOnDismissListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (enableVideoExtras) {
|
||||
videoView.pause();
|
||||
setPlayPause(R.drawable.play);
|
||||
playStatus = PAUSE;
|
||||
data = getIntent().getParcelableExtra(VIDEO_URI);
|
||||
boolean enableControls = getIntent().getBooleanExtra(ENABLE_VIDEO_CONTROLS, true);
|
||||
if (!enableControls) {
|
||||
playerView.setUseController(false);
|
||||
player.setRepeatMode(Player.REPEAT_MODE_ONE);
|
||||
}
|
||||
|
||||
MediaItem mediaItem = MediaItem.fromUri(data);
|
||||
DataSource.Factory dataSourceFactory = new OkHttpDataSource.Factory((Call.Factory) ConnectionBuilder.create(this, 128000));
|
||||
MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem);
|
||||
|
||||
player.setMediaSource(mediaSource);
|
||||
playerView.setPlayer(player);
|
||||
|
||||
player.prepare();
|
||||
player.play();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (seekUpdate != null)
|
||||
seekUpdate.shutdown();
|
||||
super.onDestroy();
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
player.pause();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// play/pause video
|
||||
if (v.getId() == R.id.controller_play) {
|
||||
if (playStatus == PAUSE) {
|
||||
playStatus = PLAY;
|
||||
if (!videoView.isPlaying())
|
||||
videoView.start();
|
||||
setPlayPause(R.drawable.pause);
|
||||
} else if (playStatus == PLAY) {
|
||||
playStatus = PAUSE;
|
||||
if (videoView.isPlaying())
|
||||
videoView.pause();
|
||||
setPlayPause(R.drawable.play);
|
||||
}
|
||||
}
|
||||
// open link with another app
|
||||
else if (v.getId() == R.id.controller_share) {
|
||||
if (v.getTag() instanceof Uri) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, (Uri) v.getTag());
|
||||
try {
|
||||
startActivity(intent);
|
||||
} catch (ActivityNotFoundException err) {
|
||||
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.video, menu);
|
||||
AppStyles.setMenuIconColor(menu, settings.getIconColor());
|
||||
menu.findItem(R.id.menu_video_link).setVisible(data.getScheme().startsWith("http"));
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
// fast backward
|
||||
if (v.getId() == R.id.controller_backward) {
|
||||
if (playStatus == PAUSE)
|
||||
return false;
|
||||
if (event.getAction() == ACTION_DOWN) {
|
||||
playStatus = BACKWARD;
|
||||
videoView.pause();
|
||||
return true;
|
||||
}
|
||||
if (event.getAction() == ACTION_UP) {
|
||||
playStatus = PLAY;
|
||||
videoView.start();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// fast forward
|
||||
else if (v.getId() == R.id.controller_forward) {
|
||||
if (playStatus == PAUSE)
|
||||
return false;
|
||||
if (event.getAction() == ACTION_DOWN) {
|
||||
playStatus = FORWARD;
|
||||
videoView.pause();
|
||||
return true;
|
||||
}
|
||||
if (event.getAction() == ACTION_UP) {
|
||||
playStatus = PLAY;
|
||||
videoView.start();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// show/hide control panel
|
||||
else if (v.getId() == R.id.video_view) {
|
||||
if (event.getAction() == ACTION_DOWN) {
|
||||
if (enableVideoExtras) {
|
||||
if (controlPanel.getVisibility() == VISIBLE) {
|
||||
controlPanel.setVisibility(INVISIBLE);
|
||||
} else {
|
||||
controlPanel.setVisibility(VISIBLE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onAttachLocation(@Nullable Location location) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onMediaFetched(int resultType, @NonNull Uri uri) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
// enable controls for video
|
||||
if (enableVideoExtras) {
|
||||
switch (playStatus) {
|
||||
case IDLE:
|
||||
// initialize seekbar
|
||||
playStatus = PLAY;
|
||||
video_progress.setMax(mp.getDuration());
|
||||
duration.setText(StringTools.formatMediaTime(mp.getDuration()));
|
||||
mp.setOnInfoListener(this);
|
||||
// fall through
|
||||
|
||||
case PLAY:
|
||||
// set video pos and start playback
|
||||
mp.seekTo(video_progress.getProgress());
|
||||
mp.start();
|
||||
break;
|
||||
|
||||
case PAUSE:
|
||||
// set only video pos
|
||||
mp.seekTo(video_progress.getProgress());
|
||||
break;
|
||||
}
|
||||
}
|
||||
// setup video looping for gif
|
||||
else {
|
||||
// disable audiofocus for gif
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
|
||||
videoView.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE);
|
||||
}
|
||||
loadingCircle.setVisibility(INVISIBLE);
|
||||
mp.setLooping(true);
|
||||
mp.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInfo(MediaPlayer mp, int what, int extra) {
|
||||
switch (what) {
|
||||
case MEDIA_INFO_BUFFERING_END:
|
||||
case MEDIA_INFO_VIDEO_RENDERING_START:
|
||||
loadingCircle.setVisibility(INVISIBLE);
|
||||
return true;
|
||||
|
||||
case MEDIA_INFO_BUFFERING_START:
|
||||
loadingCircle.setVisibility(VISIBLE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onError(MediaPlayer mp, int what, int extra) {
|
||||
if (what == MEDIA_ERROR_UNKNOWN) {
|
||||
if (link.getScheme().startsWith("http")) {
|
||||
confirmDialog.show(ConfirmDialog.VIDEO_ERROR);
|
||||
} else {
|
||||
Toast.makeText(getApplicationContext(), R.string.error_cant_load_video, LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCompletion(MediaPlayer mp) {
|
||||
setPlayPause(R.drawable.play);
|
||||
video_progress.setProgress(0);
|
||||
playStatus = PAUSE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
videoView.pause();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
position.setText(StringTools.formatMediaTime(progress));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
videoView.seekTo(seekBar.getProgress());
|
||||
if (playStatus == PLAY) {
|
||||
videoView.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
if (type == ConfirmDialog.VIDEO_ERROR) {
|
||||
if (link != null) {
|
||||
// open link in a browser
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == R.id.menu_video_link) {
|
||||
if (data != null) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(link);
|
||||
intent.setData(data);
|
||||
try {
|
||||
startActivity(intent);
|
||||
} catch (ActivityNotFoundException err) {
|
||||
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, LENGTH_SHORT).show();
|
||||
Toast.makeText(getApplicationContext(), R.string.error_connection_failed, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* updates controller panel SeekBar
|
||||
*/
|
||||
public void updateSeekBar() {
|
||||
int videoPos = video_progress.getProgress();
|
||||
switch (playStatus) {
|
||||
case PLAY:
|
||||
video_progress.setProgress(videoView.getCurrentPosition());
|
||||
break;
|
||||
|
||||
case FORWARD:
|
||||
videoPos += 2 * PROGRESS_UPDATE * SPEED_FACTOR;
|
||||
if (videoPos > videoView.getDuration())
|
||||
videoPos = videoView.getDuration();
|
||||
videoView.seekTo(videoPos);
|
||||
video_progress.setProgress(videoPos);
|
||||
break;
|
||||
|
||||
case BACKWARD:
|
||||
videoPos -= 2 * PROGRESS_UPDATE * SPEED_FACTOR;
|
||||
if (videoPos < 0)
|
||||
videoPos = 0;
|
||||
videoView.seekTo(videoPos);
|
||||
video_progress.setProgress(videoPos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setPlayPause(@DrawableRes int icon) {
|
||||
playPause.setImageResource(icon);
|
||||
AppStyles.setDrawableColor(playPause.getDrawable(), settings.getIconColor());
|
||||
AppStyles.setButtonColor(playPause, settings.getFontColor());
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ import android.view.View;
|
|||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -139,8 +138,7 @@ public class ConfirmDialog extends Dialog implements OnClickListener {
|
|||
public static final int NOTIFICATION_DISMISS = 623;
|
||||
|
||||
|
||||
private TextView title, message, confirmDescr;
|
||||
private CompoundButton confirmCheck;
|
||||
private TextView title, message;
|
||||
private Button confirm, cancel;
|
||||
private ViewGroup root;
|
||||
|
||||
|
@ -158,8 +156,6 @@ public class ConfirmDialog extends Dialog implements OnClickListener {
|
|||
cancel = findViewById(R.id.confirm_no);
|
||||
title = findViewById(R.id.confirm_title);
|
||||
message = findViewById(R.id.confirm_message);
|
||||
confirmDescr = findViewById(R.id.confirm_remember_descr);
|
||||
confirmCheck = findViewById(R.id.confirm_remember);
|
||||
|
||||
confirm.setOnClickListener(this);
|
||||
cancel.setOnClickListener(this);
|
||||
|
@ -193,7 +189,6 @@ public class ConfirmDialog extends Dialog implements OnClickListener {
|
|||
confirm.setTag(type);
|
||||
// default visibility values
|
||||
int titleVis = View.GONE;
|
||||
int confirmVis = View.INVISIBLE;
|
||||
int cancelVis = View.VISIBLE;
|
||||
// default resource values
|
||||
int titleRes = R.string.info_error;
|
||||
|
@ -288,7 +283,6 @@ public class ConfirmDialog extends Dialog implements OnClickListener {
|
|||
break;
|
||||
|
||||
case PROXY_CONFIRM:
|
||||
confirmVis = View.VISIBLE;
|
||||
titleVis = View.VISIBLE;
|
||||
titleRes = R.string.dialog_confirm_warning;
|
||||
messageRes = R.string.dialog_warning_videoview;
|
||||
|
@ -304,9 +298,6 @@ public class ConfirmDialog extends Dialog implements OnClickListener {
|
|||
// setup confirm button
|
||||
confirm.setText(confirmRes);
|
||||
confirm.setCompoundDrawablesWithIntrinsicBounds(confirmIconRes, 0, 0, 0);
|
||||
// setup remember choice checkbox
|
||||
confirmCheck.setVisibility(confirmVis);
|
||||
confirmDescr.setVisibility(confirmVis);
|
||||
// setup message
|
||||
if (messageTxt.isEmpty()) {
|
||||
message.setText(messageRes);
|
||||
|
@ -324,8 +315,7 @@ public class ConfirmDialog extends Dialog implements OnClickListener {
|
|||
Object tag = v.getTag();
|
||||
if (listener != null && tag instanceof Integer) {
|
||||
int type = (int) tag;
|
||||
boolean remember = confirmCheck.getVisibility() == View.VISIBLE && confirmCheck.isChecked();
|
||||
listener.onConfirm(type, remember);
|
||||
listener.onConfirm(type);
|
||||
}
|
||||
dismiss();
|
||||
} else if (v.getId() == R.id.confirm_no) {
|
||||
|
@ -348,9 +338,8 @@ public class ConfirmDialog extends Dialog implements OnClickListener {
|
|||
/**
|
||||
* called when the positive button was clicked
|
||||
*
|
||||
* @param type type of dialog
|
||||
* @param rememberChoice true if choice should be remembered
|
||||
* @param type type of dialog
|
||||
*/
|
||||
void onConfirm(int type, boolean rememberChoice);
|
||||
void onConfirm(int type);
|
||||
}
|
||||
}
|
|
@ -105,7 +105,7 @@ public class AccountFragment extends ListFragment implements OnAccountClickListe
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
if (type == ConfirmDialog.REMOVE_ACCOUNT) {
|
||||
load(AccountParameter.DELETE);
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ public class MessageFragment extends ListFragment implements OnMessageClickListe
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
if (type == ConfirmDialog.MESSAGE_DELETE) {
|
||||
MessageLoaderParam param = new MessageLoaderParam(MessageLoaderParam.DELETE, 0, selectedId, "");
|
||||
messageLoader.execute(param, this);
|
||||
|
|
|
@ -152,7 +152,7 @@ public class NotificationFragment extends ListFragment implements OnNotification
|
|||
|
||||
|
||||
@Override
|
||||
public void onConfirm(int type, boolean rememberChoice) {
|
||||
public void onConfirm(int type) {
|
||||
if (type == ConfirmDialog.NOTIFICATION_DISMISS) {
|
||||
if (select != null) {
|
||||
NotificationActionParam param = new NotificationActionParam(NotificationActionParam.DISMISS, select.getId());
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M17.959,4.571L10.756,9.52c0,0 -0.279,0.201 -0.279,0.481s0.279,0.479 0.279,0.479l7.203,4.951C18.531,15.811 19,15.53 19,14.805V5.196C19,4.469 18.531,4.188 17.959,4.571zM8.883,4.571L1.68,9.52c0,0 -0.279,0.201 -0.279,0.481S1.68,10.48 1.68,10.48l7.203,4.951c0.572,0.381 1.041,0.1 1.041,-0.625v-9.61C9.924,4.469 9.455,4.188 8.883,4.571z"
|
||||
android:fillColor="#FFFFFF" />
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M9.244,9.52L2.041,4.571C1.469,4.188 1,4.469 1,5.196v9.609c0,0.725 0.469,1.006 1.041,0.625l7.203,-4.951c0,0 0.279,-0.199 0.279,-0.478C9.523,9.721 9.244,9.52 9.244,9.52zM18.6,10.001c0,0.279 -0.279,0.478 -0.279,0.478l-7.203,4.951c-0.572,0.381 -1.041,0.1 -1.041,-0.625V5.196c0,-0.727 0.469,-1.008 1.041,-0.625L18.32,9.52C18.32,9.52 18.6,9.721 18.6,10.001z"
|
||||
android:fillColor="#FFFFFF" />
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M15,3h-2c-0.553,0 -1,0.048 -1,0.6v12.8c0,0.552 0.447,0.6 1,0.6h2c0.553,0 1,-0.048 1,-0.6V3.6C16,3.048 15.553,3 15,3zM7,3H5C4.447,3 4,3.048 4,3.6v12.8C4,16.952 4.447,17 5,17h2c0.553,0 1,-0.048 1,-0.6V3.6C8,3.048 7.553,3 7,3z"
|
||||
android:fillColor="#FFFFFF" />
|
||||
</vector>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/page_video_root"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/page_video_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/page_status_toolbar_height"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.google.android.exoplayer2.ui.StyledPlayerView
|
||||
android:id="@+id/page_video_player"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -39,30 +39,8 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="confirm_no,confirm_yes,confirm_remember,confirm_remember_descr" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/confirm_remember"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/confirm_button_margin"
|
||||
android:lines="1"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/confirm_remember_descr"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/confirm_remember_descr"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/confirm_checkbox_text_margin"
|
||||
android:text="@string/dialog_confirm_remember"
|
||||
android:textSize="@dimen/confirm_checkbox_text_size"
|
||||
app:layout_constraintBottom_toBottomOf="@id/confirm_remember"
|
||||
app:layout_constraintEnd_toStartOf="@id/confirm_no"
|
||||
app:layout_constraintStart_toEndOf="@id/confirm_remember"
|
||||
app:layout_constraintTop_toTopOf="@id/confirm_remember" />
|
||||
app:constraint_referenced_ids="confirm_no,confirm_yes"
|
||||
tools:layout_editor_absoluteY="96dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/confirm_no"
|
||||
|
|
|
@ -1,135 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/page_video_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".ui.activities.VideoViewer">
|
||||
|
||||
<VideoView
|
||||
android:id="@+id/video_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/page_video_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/page_status_toolbar_height" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/media_progress"
|
||||
android:layout_width="@dimen/mediapage_circle_size"
|
||||
android:layout_height="@dimen/mediapage_circle_size"
|
||||
android:layout_marginTop="@dimen/mediapage_preview_margin"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
<com.google.android.exoplayer2.ui.StyledPlayerView
|
||||
android:id="@+id/page_video_player"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/media_controlpanel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"
|
||||
android:layout_marginStart="@dimen/mediapage_controller_layout_margin"
|
||||
android:layout_marginBottom="@dimen/mediapage_controller_layout_margin"
|
||||
android:layout_marginEnd="@dimen/mediapage_controller_layout_margin"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/controller_backward"
|
||||
android:layout_width="@dimen/controller_button_width"
|
||||
android:layout_height="@dimen/controller_button_height"
|
||||
android:layout_marginTop="@dimen/controller_seekbar_margin"
|
||||
android:contentDescription="@string/button_backward"
|
||||
android:src="@drawable/backward"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/controller_play"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/controller_play"
|
||||
android:layout_width="@dimen/controller_button_width"
|
||||
android:layout_height="@dimen/controller_button_height"
|
||||
android:layout_marginTop="@dimen/controller_seekbar_margin"
|
||||
android:contentDescription="@string/button_play_pause"
|
||||
android:src="@drawable/pause"
|
||||
app:layout_constraintStart_toEndOf="@id/controller_backward"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/controller_forward"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/controller_forward"
|
||||
android:layout_width="@dimen/controller_button_width"
|
||||
android:layout_height="@dimen/controller_button_height"
|
||||
android:layout_marginTop="@dimen/controller_seekbar_margin"
|
||||
android:contentDescription="@string/button_forward"
|
||||
android:src="@drawable/forward"
|
||||
app:layout_constraintStart_toEndOf="@id/controller_play"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/controller_share"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/controller_share"
|
||||
android:layout_width="@dimen/controller_button_width"
|
||||
android:layout_height="@dimen/controller_button_height"
|
||||
android:layout_marginTop="@dimen/controller_seekbar_margin"
|
||||
android:contentDescription="@string/button_share"
|
||||
android:src="@drawable/share"
|
||||
app:layout_constraintStart_toEndOf="@id/controller_forward"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
style="@style/RoundButton" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/controller_barrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="controller_backward,controller_forward,controller_play" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/controller_position"
|
||||
android:layout_width="@dimen/controller_text_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/controller_text_margin"
|
||||
android:lines="1"
|
||||
android:textSize="@dimen/controller_text_size"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/controller_progress"
|
||||
app:layout_constraintBottom_toBottomOf="@id/controller_progress"
|
||||
app:layout_constraintEnd_toStartOf="@id/controller_progress" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/controller_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/controller_seekbar_margin"
|
||||
android:layout_marginBottom="@dimen/controller_seekbar_margin"
|
||||
android:contentDescription="@string/button_backward"
|
||||
app:layout_constraintStart_toEndOf="@id/controller_position"
|
||||
app:layout_constraintTop_toBottomOf="@id/controller_barrier"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/controller_duration" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/controller_duration"
|
||||
android:layout_width="@dimen/controller_text_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/controller_text_margin"
|
||||
android:lines="1"
|
||||
android:textSize="@dimen/controller_text_size"
|
||||
app:layout_constraintStart_toEndOf="@id/controller_progress"
|
||||
app:layout_constraintTop_toTopOf="@id/controller_progress"
|
||||
app:layout_constraintBottom_toBottomOf="@id/controller_progress"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_video_link"
|
||||
android:icon="@drawable/share"
|
||||
android:title="@string/button_share"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
|
@ -183,9 +183,6 @@
|
|||
<string name="error_api_key_expired">Fehler, API Schlüssel veraltet, bitte App aktualisieren!</string>
|
||||
<string name="info_location_pending">Ortung läuft, bitte warten.</string>
|
||||
<string name="error_twitter_search">Suchbegriff ist entweder zu lang oder enthält nicht erlaubte Zeichen!</string>
|
||||
<string name="button_backward">Zurückspulen</string>
|
||||
<string name="button_forward">Vorspulen</string>
|
||||
<string name="button_play_pause">Pause/Abspielen</string>
|
||||
<string name="button_share">Videolink teilen</string>
|
||||
<string name="settings_look">Aussehen</string>
|
||||
<string name="dialog_link_image_preview">Linkvorschau Bild</string>
|
||||
|
@ -237,7 +234,6 @@
|
|||
<string name="dialog_confirm_warning">Warnung</string>
|
||||
<string name="dialog_warning_videoview">Videoplayer unterstützt keine Proxy Verbindung! Fortsetzen ohne Proxy?</string>
|
||||
<string name="confirm_unknown_error">Unbekannter Fehler!</string>
|
||||
<string name="dialog_confirm_remember">merken</string>
|
||||
<string name="error_invalid_media">Ungültige Mediendatei!</string>
|
||||
<string name="menu_follow_requests">Anfragen</string>
|
||||
<string name="menu_toolbar_excluded_users">Blocklisten</string>
|
||||
|
|
|
@ -83,9 +83,6 @@
|
|||
<string name="info_list_followed">已关注列表</string>
|
||||
<string name="info_list_unfollowed">已取消关注列表</string>
|
||||
<string name="descr_add_profile_image">更换头像</string>
|
||||
<string name="button_backward">后退</string>
|
||||
<string name="button_forward">快进</string>
|
||||
<string name="button_play_pause">暂停/播放</string>
|
||||
<string name="button_share">分享链接</string>
|
||||
|
||||
<!-- toast messages to inform user -->
|
||||
|
|
|
@ -187,7 +187,6 @@
|
|||
<dimen name="mediapage_toolbar_height">@dimen/toolbar_height</dimen>
|
||||
<dimen name="mediapage_preview_margin">10dp</dimen>
|
||||
<dimen name="mediapage_circle_size">64dp</dimen>
|
||||
<dimen name="mediapage_controller_layout_margin">10dp</dimen>
|
||||
|
||||
<!--dimens of item_placeholder.xml-->
|
||||
<dimen name="item_placeholder_margin">8dp</dimen>
|
||||
|
@ -227,8 +226,6 @@
|
|||
<dimen name="confirm_message_fontsize">18sp</dimen>
|
||||
<dimen name="confirm_title_fontsize">22sp</dimen>
|
||||
<dimen name="confirm_button_height">30sp</dimen>
|
||||
<dimen name="confirm_checkbox_text_margin">5dp</dimen>
|
||||
<dimen name="confirm_checkbox_text_size">10sp</dimen>
|
||||
<integer name="confirm_message_max_ines">8</integer>
|
||||
|
||||
<!--dimens of dialog_userlist.xml-->
|
||||
|
@ -258,14 +255,6 @@
|
|||
<dimen name="tabitem_icon_size">22sp</dimen>
|
||||
<dimen name="tabitem_textsize">11sp</dimen>
|
||||
|
||||
<!--dimens of controlpanel-->
|
||||
<dimen name="controller_seekbar_margin">10dp</dimen>
|
||||
<dimen name="controller_text_margin">5dp</dimen>
|
||||
<dimen name="controller_text_size">11sp</dimen>
|
||||
<dimen name="controller_button_width">64dp</dimen>
|
||||
<dimen name="controller_button_height">32dp</dimen>
|
||||
<dimen name="controller_text_width">36sp</dimen>
|
||||
|
||||
<!--dimens of item_card.xml-->
|
||||
<dimen name="item_card_textsize">11sp</dimen>
|
||||
<dimen name="item_card_layout_padding">5dp</dimen>
|
||||
|
|
|
@ -283,13 +283,9 @@
|
|||
<string name="update_list">update list</string>
|
||||
<string name="confirm_remove_user_from_list">remove user from list?</string>
|
||||
<string name="descr_remove_user">remove user from list</string>
|
||||
<string name="dialog_confirm_remember">remember</string>
|
||||
<string name="confirm_unknown_error">unknown error!</string>
|
||||
<string name="list_following_indicator">following list</string>
|
||||
<string name="descr_add_profile_image">change profile image</string>
|
||||
<string name="button_backward">Rewind</string>
|
||||
<string name="button_forward">Fast forward</string>
|
||||
<string name="button_play_pause">Pause/Play</string>
|
||||
<string name="button_share">share link</string>
|
||||
<string name="settings_rt_icon_color">Reposts</string>
|
||||
<string name="settings_follow_req_color">Follow request</string>
|
||||
|
|
|
@ -10,7 +10,6 @@ buildscript {
|
|||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath 'io.michaelrocks:paranoid-gradle-plugin:0.3.7' // fixme Find replacement
|
||||
classpath 'gradle.plugin.ru.cleverpumpkin.proguard-dictionaries-generator:plugin:1.0.8'
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue