Embedded webview + manages fullscreen videos + javascript can be disabled & third party cookies
This commit is contained in:
parent
711490d351
commit
1a96f4a3c7
|
@ -64,10 +64,16 @@
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
/>
|
/>
|
||||||
|
<activity android:name="fr.gouv.etalab.mastodon.activities.WebviewConnectActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
/>
|
||||||
<activity android:name="fr.gouv.etalab.mastodon.activities.WebviewActivity"
|
<activity android:name="fr.gouv.etalab.mastodon.activities.WebviewActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
|
android:noHistory="true"
|
||||||
/>
|
/>
|
||||||
<activity android:name="fr.gouv.etalab.mastodon.activities.SearchResultActivity"
|
<activity android:name="fr.gouv.etalab.mastodon.activities.SearchResultActivity"
|
||||||
android:windowSoftInputMode="stateAlwaysHidden"
|
android:windowSoftInputMode="stateAlwaysHidden"
|
||||||
|
|
|
@ -173,7 +173,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||||
connectionButton.setEnabled(true);
|
connectionButton.setEnabled(true);
|
||||||
login_two_step.setVisibility(View.VISIBLE);
|
login_two_step.setVisibility(View.VISIBLE);
|
||||||
if( client_id_for_webview){
|
if( client_id_for_webview){
|
||||||
Intent i = new Intent(LoginActivity.this, WebviewActivity.class);
|
Intent i = new Intent(LoginActivity.this, WebviewConnectActivity.class);
|
||||||
i.putExtra("instance", instance);
|
i.putExtra("instance", instance);
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,178 +12,351 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
* You should have received a copy of the GNU General Public License along with Thomas Schneider; if not,
|
||||||
* see <http://www.gnu.org/licenses>. */
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
package fr.gouv.etalab.mastodon.activities;
|
package fr.gouv.etalab.mastodon.activities;
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.Uri;
|
import android.graphics.Bitmap;
|
||||||
import android.os.AsyncTask;
|
|
||||||
|
import android.media.MediaPlayer;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.CookieSyncManager;
|
|
||||||
import android.webkit.WebChromeClient;
|
import android.webkit.WebChromeClient;
|
||||||
|
import android.webkit.WebSettings;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.loopj.android.http.AsyncHttpResponseHandler;
|
|
||||||
import com.loopj.android.http.RequestParams;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import cz.msebera.android.httpclient.Header;
|
|
||||||
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
|
||||||
import fr.gouv.etalab.mastodon.client.OauthClient;
|
|
||||||
import fr.gouv.etalab.mastodon.helper.Helper;
|
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||||
import mastodon.etalab.gouv.fr.mastodon.R;
|
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Thomas on 24/04/2017.
|
* Created by Thomas on 24/06/2017.
|
||||||
* Webview to connect accounts
|
* Webview activity
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class WebviewActivity extends AppCompatActivity {
|
public class WebviewActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
private ProgressBar pbar;
|
||||||
|
|
||||||
private WebView webView;
|
@Override
|
||||||
private AlertDialog alert;
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
private String clientId, clientSecret;
|
|
||||||
private String instance;
|
|
||||||
|
|
||||||
public void onCreate(Bundle savedInstanceState)
|
|
||||||
{
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_webview);
|
setContentView(R.layout.activity_webview);
|
||||||
Bundle b = getIntent().getExtras();
|
Bundle b = getIntent().getExtras();
|
||||||
if(b != null)
|
if(b != null)
|
||||||
instance = b.getString("instance");
|
url = b.getString("url", null);
|
||||||
if( instance == null)
|
if( url == null)
|
||||||
finish();
|
finish();
|
||||||
|
if( getSupportActionBar() != null)
|
||||||
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
boolean javascript = sharedpreferences.getBoolean(Helper.SET_JAVASCRIPT, true);
|
||||||
|
|
||||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
|
||||||
clientId = sharedpreferences.getString(Helper.CLIENT_ID, null);
|
|
||||||
clientSecret = sharedpreferences.getString(Helper.CLIENT_SECRET, null);
|
|
||||||
|
|
||||||
webView = (WebView) findViewById(R.id.webviewConnect);
|
|
||||||
clearCookies(getApplicationContext());
|
pbar = (ProgressBar) findViewById(R.id.progress_bar);
|
||||||
final ProgressBar pbar = (ProgressBar) findViewById(R.id.progress_bar);
|
WebView webView = (WebView) findViewById(R.id.webview);
|
||||||
webView.setWebChromeClient(new WebChromeClient() {
|
webView.getSettings().setJavaScriptEnabled(javascript);
|
||||||
|
webView.getSettings().setUseWideViewPort(true);
|
||||||
|
webView.getSettings().setLoadWithOverviewMode(true);
|
||||||
|
webView.getSettings().setSupportZoom(true);
|
||||||
|
webView.getSettings().setDisplayZoomControls(false);
|
||||||
|
webView.getSettings().setBuiltInZoomControls(true);
|
||||||
|
webView.getSettings().setAllowContentAccess(true);
|
||||||
|
webView.getSettings().setLoadsImagesAutomatically(true);
|
||||||
|
webView.getSettings().setSupportMultipleWindows(false);
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||||
|
//noinspection deprecation
|
||||||
|
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
webView.getSettings().setMediaPlaybackRequiresUserGesture(true);
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||||
|
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
boolean cookies = sharedpreferences.getBoolean(Helper.SET_COOKIES, false);
|
||||||
|
CookieManager cookieManager = CookieManager.getInstance();
|
||||||
|
cookieManager.setAcceptThirdPartyCookies(webView, cookies);
|
||||||
|
}
|
||||||
|
webView.getSettings().setAppCacheEnabled(true);
|
||||||
|
webView.getSettings().setDatabaseEnabled(true);
|
||||||
|
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
|
||||||
|
|
||||||
|
|
||||||
|
setTitle("");
|
||||||
|
FrameLayout webview_container = (FrameLayout) findViewById(R.id.webview_container);
|
||||||
|
final ViewGroup videoLayout = (ViewGroup) findViewById(R.id.videoLayout); // Your own view, read class comments
|
||||||
|
|
||||||
|
|
||||||
|
MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient(webView, webview_container, videoLayout);
|
||||||
|
mastalabWebChromeClient.setOnToggledFullscreen(new ToggledFullscreenCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onProgressChanged(WebView view, int progress) {
|
public void toggledFullscreen(boolean fullscreen) {
|
||||||
if (progress < 100 && pbar.getVisibility() == ProgressBar.GONE) {
|
|
||||||
pbar.setVisibility(ProgressBar.VISIBLE);
|
if (fullscreen) {
|
||||||
}
|
videoLayout.setVisibility(View.VISIBLE);
|
||||||
pbar.setProgress(progress);
|
WindowManager.LayoutParams attrs = getWindow().getAttributes();
|
||||||
if (progress == 100) {
|
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||||
pbar.setVisibility(ProgressBar.GONE);
|
attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||||
|
getWindow().setAttributes(attrs);
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
|
||||||
|
} else {
|
||||||
|
WindowManager.LayoutParams attrs = getWindow().getAttributes();
|
||||||
|
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
|
||||||
|
attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
|
||||||
|
getWindow().setAttributes(attrs);
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||||
|
videoLayout.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
webView.setWebChromeClient(mastalabWebChromeClient);
|
||||||
|
webView.setWebViewClient(new MastalabWebViewClient());
|
||||||
webView.setWebViewClient(new WebViewClient() {
|
webView.loadUrl(url);
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public boolean shouldOverrideUrlLoading(WebView view, String url){
|
|
||||||
super.shouldOverrideUrlLoading(view,url);
|
|
||||||
if( url.contains(Helper.REDIRECT_CONTENT_WEB)){
|
|
||||||
String val[] = url.split("code=");
|
|
||||||
String code = val[1];
|
|
||||||
|
|
||||||
String action = "/oauth/token";
|
|
||||||
RequestParams parameters = new RequestParams();
|
|
||||||
parameters.add(Helper.CLIENT_ID, clientId);
|
|
||||||
parameters.add(Helper.CLIENT_SECRET, clientSecret);
|
|
||||||
parameters.add(Helper.REDIRECT_URI,Helper.REDIRECT_CONTENT_WEB);
|
|
||||||
parameters.add("grant_type", "authorization_code");
|
|
||||||
parameters.add("code",code);
|
|
||||||
new OauthClient(instance).post(action, parameters, new AsyncHttpResponseHandler() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
|
|
||||||
String response = new String(responseBody);
|
|
||||||
JSONObject resobj;
|
|
||||||
try {
|
|
||||||
resobj = new JSONObject(response);
|
|
||||||
String token = resobj.get("access_token").toString();
|
|
||||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
|
||||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
||||||
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
|
|
||||||
editor.apply();
|
|
||||||
//Update the account with the token;
|
|
||||||
new UpdateAccountInfoAsyncTask(WebviewActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
|
|
||||||
error.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
webView.loadUrl(redirectUserToAuthorizeAndLogin());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
if (webView != null && webView.canGoBack()) {
|
switch (item.getItemId()) {
|
||||||
webView.goBack();
|
case android.R.id.home:
|
||||||
} else {
|
finish();
|
||||||
super.onBackPressed();
|
return true;
|
||||||
|
default:
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String redirectUserToAuthorizeAndLogin() {
|
|
||||||
|
|
||||||
String queryString = Helper.CLIENT_ID + "="+ clientId;
|
|
||||||
queryString += "&" + Helper.REDIRECT_URI + "="+ Uri.encode(Helper.REDIRECT_CONTENT_WEB);
|
|
||||||
queryString += "&" + Helper.RESPONSE_TYPE +"=code";
|
|
||||||
queryString += "&" + Helper.SCOPE +"=" + Helper.OAUTH_SCOPES;
|
|
||||||
return "https://" + instance + Helper.EP_AUTHORIZE + "?" + queryString;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy(){
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (alert != null) {
|
|
||||||
alert.dismiss();
|
}
|
||||||
alert = null;
|
|
||||||
|
private class MastalabWebViewClient extends WebViewClient{
|
||||||
|
@Override
|
||||||
|
public void onPageFinished(WebView view, String url) {
|
||||||
|
super.onPageFinished(view, url);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onPageStarted (WebView view, String url, Bitmap favicon) {
|
||||||
|
super.onPageStarted(view, url, favicon);
|
||||||
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
LayoutInflater mInflater = LayoutInflater.from(WebviewActivity.this);
|
||||||
|
if( actionBar != null){
|
||||||
|
View webview_actionbar = mInflater.inflate(R.layout.webview_actionbar, null);
|
||||||
|
TextView webview_title = (TextView) webview_actionbar.findViewById(R.id.webview_title);
|
||||||
|
webview_title.setText(url);
|
||||||
|
actionBar.setCustomView(webview_actionbar);
|
||||||
|
actionBar.setDisplayShowCustomEnabled(true);
|
||||||
|
}else {
|
||||||
|
setTitle(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
interface ToggledFullscreenCallback {
|
||||||
public static void clearCookies(Context context)
|
void toggledFullscreen(boolean fullscreen);
|
||||||
{
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
CookieManager.getInstance().removeAllCookies(null);
|
|
||||||
CookieManager.getInstance().flush();
|
|
||||||
} else {
|
|
||||||
CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(context);
|
|
||||||
cookieSyncMngr.startSync();
|
|
||||||
CookieManager cookieManager=CookieManager.getInstance();
|
|
||||||
cookieManager.removeAllCookie();
|
|
||||||
cookieManager.removeSessionCookie();
|
|
||||||
cookieSyncMngr.stopSync();
|
|
||||||
cookieSyncMngr.sync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
private class MastalabWebChromeClient extends WebChromeClient implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
|
||||||
|
|
||||||
|
private FrameLayout videoViewContainer;
|
||||||
|
private CustomViewCallback videoViewCallback;
|
||||||
|
|
||||||
|
private ToggledFullscreenCallback toggledFullscreenCallback;
|
||||||
|
private boolean isVideoFullscreen;
|
||||||
|
private WebView webView;
|
||||||
|
private View activityNonVideoView;
|
||||||
|
private ViewGroup activityVideoView;
|
||||||
|
private View loadingView;
|
||||||
|
|
||||||
|
MastalabWebChromeClient(WebView webView, FrameLayout webviewContainer, ViewGroup videoLayout){
|
||||||
|
this.isVideoFullscreen = false;
|
||||||
|
this.webView = webView;
|
||||||
|
this.activityNonVideoView = webviewContainer;
|
||||||
|
this.activityVideoView = videoLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(WebView view, int progress) {
|
||||||
|
if (progress < 100 && pbar.getVisibility() == ProgressBar.GONE) {
|
||||||
|
pbar.setVisibility(ProgressBar.VISIBLE);
|
||||||
|
}
|
||||||
|
pbar.setProgress(progress);
|
||||||
|
if (progress == 100) {
|
||||||
|
pbar.setVisibility(ProgressBar.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onReceivedIcon(WebView view, Bitmap icon) {
|
||||||
|
super.onReceivedIcon(view, icon);
|
||||||
|
LayoutInflater mInflater = LayoutInflater.from(WebviewActivity.this);
|
||||||
|
ActionBar actionBar = getSupportActionBar();
|
||||||
|
if( actionBar != null){
|
||||||
|
View webview_actionbar = mInflater.inflate(R.layout.webview_actionbar, null);
|
||||||
|
TextView webview_title = (TextView) webview_actionbar.findViewById(R.id.webview_title);
|
||||||
|
webview_title.setText(view.getTitle());
|
||||||
|
ImageView webview_favicon = (ImageView) webview_actionbar.findViewById(R.id.webview_favicon);
|
||||||
|
if( icon != null)
|
||||||
|
webview_favicon.setImageBitmap(icon);
|
||||||
|
actionBar.setCustomView(webview_actionbar);
|
||||||
|
actionBar.setDisplayShowCustomEnabled(true);
|
||||||
|
}else {
|
||||||
|
setTitle(view.getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//FULLSCREEN VIDEO
|
||||||
|
//Code from https://stackoverflow.com/a/16179544/3197259
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a callback that will be fired when the video starts or finishes displaying using a custom view (typically full-screen)
|
||||||
|
* @param callback A VideoEnabledWebChromeClient.ToggledFullscreenCallback callback
|
||||||
|
*/
|
||||||
|
void setOnToggledFullscreen(ToggledFullscreenCallback callback) {
|
||||||
|
this.toggledFullscreenCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onShowCustomView(View view, CustomViewCallback callback) {
|
||||||
|
if (view instanceof FrameLayout) {
|
||||||
|
if( getSupportActionBar() != null)
|
||||||
|
getSupportActionBar().hide();
|
||||||
|
// A video wants to be shown
|
||||||
|
FrameLayout frameLayout = (FrameLayout) view;
|
||||||
|
View focusedChild = frameLayout.getFocusedChild();
|
||||||
|
|
||||||
|
// Save video related variables
|
||||||
|
isVideoFullscreen = true;
|
||||||
|
this.videoViewContainer = frameLayout;
|
||||||
|
this.videoViewCallback = callback;
|
||||||
|
|
||||||
|
// Hide the non-video view, add the video view, and show it
|
||||||
|
activityNonVideoView.setVisibility(View.INVISIBLE);
|
||||||
|
activityVideoView.addView(videoViewContainer, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||||
|
activityVideoView.setVisibility(View.VISIBLE);
|
||||||
|
if (focusedChild instanceof android.widget.VideoView) {
|
||||||
|
// android.widget.VideoView (typically API level <11)
|
||||||
|
android.widget.VideoView videoView = (android.widget.VideoView) focusedChild;
|
||||||
|
// Handle all the required events
|
||||||
|
videoView.setOnPreparedListener(this);
|
||||||
|
videoView.setOnCompletionListener(this);
|
||||||
|
videoView.setOnErrorListener(this);
|
||||||
|
} else {
|
||||||
|
// Other classes, including:
|
||||||
|
// - android.webkit.HTML5VideoFullScreen$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 11-18)
|
||||||
|
// - android.webkit.HTML5VideoFullScreen$VideoTextureView, which inherits from android.view.TextureView (typically API level 11-18)
|
||||||
|
// - com.android.org.chromium.content.browser.ContentVideoView$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 19+)
|
||||||
|
|
||||||
|
// Handle HTML5 video ended event only if the class is a SurfaceView
|
||||||
|
// Test case: TextureView of Sony Xperia T API level 16 doesn't work fullscreen when loading the javascript below
|
||||||
|
if (webView != null && webView.getSettings().getJavaScriptEnabled() && focusedChild instanceof SurfaceView) {
|
||||||
|
// Run javascript code that detects the video end and notifies the Javascript interface
|
||||||
|
String js = "javascript:";
|
||||||
|
js += "var _ytrp_html5_video_last;";
|
||||||
|
js += "var _ytrp_html5_video = document.getElementsByTagName('video')[0];";
|
||||||
|
js += "if (_ytrp_html5_video != undefined && _ytrp_html5_video != _ytrp_html5_video_last) {";
|
||||||
|
{
|
||||||
|
js += "_ytrp_html5_video_last = _ytrp_html5_video;";
|
||||||
|
js += "function _ytrp_html5_video_ended() {";
|
||||||
|
{
|
||||||
|
js += "_VideoEnabledWebView.notifyVideoEnd();"; // Must match Javascript interface name and method of VideoEnableWebView
|
||||||
|
}
|
||||||
|
js += "}";
|
||||||
|
js += "_ytrp_html5_video.addEventListener('ended', _ytrp_html5_video_ended);";
|
||||||
|
}
|
||||||
|
js += "}";
|
||||||
|
webView.loadUrl(js);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Notify full-screen change
|
||||||
|
if (toggledFullscreenCallback != null) {
|
||||||
|
toggledFullscreenCallback.toggledFullscreen(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Available in API level 14+, deprecated in API level 18+
|
||||||
|
@Override @SuppressWarnings("deprecation")
|
||||||
|
public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
|
||||||
|
onShowCustomView(view, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onHideCustomView() {
|
||||||
|
if( getSupportActionBar() != null)
|
||||||
|
getSupportActionBar().show();
|
||||||
|
// This method should be manually called on video end in all cases because it's not always called automatically.
|
||||||
|
// This method must be manually called on back key press (from this class' onBackPressed() method).
|
||||||
|
if (isVideoFullscreen) {
|
||||||
|
// Hide the video view, remove it, and show the non-video view
|
||||||
|
activityVideoView.setVisibility(View.INVISIBLE);
|
||||||
|
activityVideoView.removeView(videoViewContainer);
|
||||||
|
activityNonVideoView.setVisibility(View.VISIBLE);
|
||||||
|
// Call back (only in API level <19, because in API level 19+ with chromium webview it crashes)
|
||||||
|
if (videoViewCallback != null && !videoViewCallback.getClass().getName().contains(".chromium.")) {
|
||||||
|
videoViewCallback.onCustomViewHidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset video related variables
|
||||||
|
isVideoFullscreen = false;
|
||||||
|
videoViewContainer = null;
|
||||||
|
videoViewCallback = null;
|
||||||
|
|
||||||
|
// Notify full-screen change
|
||||||
|
if (toggledFullscreenCallback != null) {
|
||||||
|
toggledFullscreenCallback.toggledFullscreen(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Video will start loading
|
||||||
|
@Override
|
||||||
|
public View getVideoLoadingProgressView() {
|
||||||
|
return super.getVideoLoadingProgressView();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Video will start playing, only called in the case of android.widget.VideoView (typically API level <11)
|
||||||
|
@Override
|
||||||
|
public void onPrepared(MediaPlayer mp) {
|
||||||
|
if (loadingView != null) {
|
||||||
|
loadingView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Video finished playing, only called in the case of android.widget.VideoView (typically API level <11)
|
||||||
|
@Override
|
||||||
|
public void onCompletion(MediaPlayer mp) {
|
||||||
|
onHideCustomView();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error while playing video, only called in the case of android.widget.VideoView (typically API level <11)
|
||||||
|
@Override
|
||||||
|
public boolean onError(MediaPlayer mp, int what, int extra) {
|
||||||
|
return false; // By returning false, onCompletion() will be called
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/* Copyright 2017 Thomas Schneider
|
||||||
|
*
|
||||||
|
* This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Mastodon Etalab 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 Thomas Schneider; if not,
|
||||||
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
|
||||||
|
package fr.gouv.etalab.mastodon.activities;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.webkit.CookieManager;
|
||||||
|
import android.webkit.CookieSyncManager;
|
||||||
|
import android.webkit.WebChromeClient;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import com.loopj.android.http.AsyncHttpResponseHandler;
|
||||||
|
import com.loopj.android.http.RequestParams;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import cz.msebera.android.httpclient.Header;
|
||||||
|
import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask;
|
||||||
|
import fr.gouv.etalab.mastodon.client.OauthClient;
|
||||||
|
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||||
|
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Thomas on 24/04/2017.
|
||||||
|
* Webview to connect accounts
|
||||||
|
*/
|
||||||
|
public class WebviewConnectActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
|
private WebView webView;
|
||||||
|
private AlertDialog alert;
|
||||||
|
private String clientId, clientSecret;
|
||||||
|
private String instance;
|
||||||
|
|
||||||
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_webview);
|
||||||
|
Bundle b = getIntent().getExtras();
|
||||||
|
if(b != null)
|
||||||
|
instance = b.getString("instance");
|
||||||
|
if( instance == null)
|
||||||
|
finish();
|
||||||
|
|
||||||
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
clientId = sharedpreferences.getString(Helper.CLIENT_ID, null);
|
||||||
|
clientSecret = sharedpreferences.getString(Helper.CLIENT_SECRET, null);
|
||||||
|
|
||||||
|
webView = (WebView) findViewById(R.id.webviewConnect);
|
||||||
|
clearCookies(getApplicationContext());
|
||||||
|
final ProgressBar pbar = (ProgressBar) findViewById(R.id.progress_bar);
|
||||||
|
webView.setWebChromeClient(new WebChromeClient() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(WebView view, int progress) {
|
||||||
|
if (progress < 100 && pbar.getVisibility() == ProgressBar.GONE) {
|
||||||
|
pbar.setVisibility(ProgressBar.VISIBLE);
|
||||||
|
}
|
||||||
|
pbar.setProgress(progress);
|
||||||
|
if (progress == 100) {
|
||||||
|
pbar.setVisibility(ProgressBar.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
webView.setWebViewClient(new WebViewClient() {
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public boolean shouldOverrideUrlLoading(WebView view, String url){
|
||||||
|
super.shouldOverrideUrlLoading(view,url);
|
||||||
|
if( url.contains(Helper.REDIRECT_CONTENT_WEB)){
|
||||||
|
String val[] = url.split("code=");
|
||||||
|
String code = val[1];
|
||||||
|
|
||||||
|
String action = "/oauth/token";
|
||||||
|
RequestParams parameters = new RequestParams();
|
||||||
|
parameters.add(Helper.CLIENT_ID, clientId);
|
||||||
|
parameters.add(Helper.CLIENT_SECRET, clientSecret);
|
||||||
|
parameters.add(Helper.REDIRECT_URI,Helper.REDIRECT_CONTENT_WEB);
|
||||||
|
parameters.add("grant_type", "authorization_code");
|
||||||
|
parameters.add("code",code);
|
||||||
|
new OauthClient(instance).post(action, parameters, new AsyncHttpResponseHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
|
||||||
|
String response = new String(responseBody);
|
||||||
|
JSONObject resobj;
|
||||||
|
try {
|
||||||
|
resobj = new JSONObject(response);
|
||||||
|
String token = resobj.get("access_token").toString();
|
||||||
|
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
|
||||||
|
editor.apply();
|
||||||
|
//Update the account with the token;
|
||||||
|
new UpdateAccountInfoAsyncTask(WebviewConnectActivity.this, token, instance).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
|
||||||
|
error.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
webView.loadUrl(redirectUserToAuthorizeAndLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (webView != null && webView.canGoBack()) {
|
||||||
|
webView.goBack();
|
||||||
|
} else {
|
||||||
|
super.onBackPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String redirectUserToAuthorizeAndLogin() {
|
||||||
|
|
||||||
|
String queryString = Helper.CLIENT_ID + "="+ clientId;
|
||||||
|
queryString += "&" + Helper.REDIRECT_URI + "="+ Uri.encode(Helper.REDIRECT_CONTENT_WEB);
|
||||||
|
queryString += "&" + Helper.RESPONSE_TYPE +"=code";
|
||||||
|
queryString += "&" + Helper.SCOPE +"=" + Helper.OAUTH_SCOPES;
|
||||||
|
return "https://" + instance + Helper.EP_AUTHORIZE + "?" + queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (alert != null) {
|
||||||
|
alert.dismiss();
|
||||||
|
alert = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public static void clearCookies(Context context)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||||
|
CookieManager.getInstance().removeAllCookies(null);
|
||||||
|
CookieManager.getInstance().flush();
|
||||||
|
} else {
|
||||||
|
CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(context);
|
||||||
|
cookieSyncMngr.startSync();
|
||||||
|
CookieManager cookieManager=CookieManager.getInstance();
|
||||||
|
cookieManager.removeAllCookie();
|
||||||
|
cookieManager.removeSessionCookie();
|
||||||
|
cookieSyncMngr.stopSync();
|
||||||
|
cookieSyncMngr.sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
package fr.gouv.etalab.mastodon.fragments;
|
||||||
|
/* Copyright 2017 Thomas Schneider
|
||||||
|
*
|
||||||
|
* This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Mastodon Etalab 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 Thomas Schneider; if not,
|
||||||
|
* see <http://www.gnu.org/licenses>. */
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.widget.SwitchCompat;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import fr.gouv.etalab.mastodon.helper.Helper;
|
||||||
|
import mastodon.etalab.gouv.fr.mastodon.R;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Thomas on 24/06/2017.
|
||||||
|
* Fragment for settings, yes I didn't use PreferenceFragment :)
|
||||||
|
*/
|
||||||
|
public class SettingsFragment extends Fragment {
|
||||||
|
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
View rootView = inflater.inflate(R.layout.fragment_settings, container, false);
|
||||||
|
context = getContext();
|
||||||
|
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
|
||||||
|
|
||||||
|
boolean show_reply = sharedpreferences.getBoolean(Helper.SET_SHOW_REPLY, false);
|
||||||
|
final CheckBox set_show_reply = (CheckBox) rootView.findViewById(R.id.set_show_reply);
|
||||||
|
set_show_reply.setChecked(show_reply);
|
||||||
|
|
||||||
|
set_show_reply.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putBoolean(Helper.SET_SHOW_REPLY, set_show_reply.isChecked());
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
|
||||||
|
final CheckBox set_show_error_messages = (CheckBox) rootView.findViewById(R.id.set_show_error_messages);
|
||||||
|
set_show_error_messages.setChecked(show_error_messages);
|
||||||
|
|
||||||
|
set_show_error_messages.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putBoolean(Helper.SET_SHOW_ERROR_MESSAGES, set_show_error_messages.isChecked());
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
boolean notif_validation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true);
|
||||||
|
final CheckBox set_share_validation = (CheckBox) rootView.findViewById(R.id.set_share_validation);
|
||||||
|
set_share_validation.setChecked(notif_validation);
|
||||||
|
|
||||||
|
set_share_validation.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putBoolean(Helper.SET_NOTIF_VALIDATION, set_share_validation.isChecked());
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
final CheckBox set_embedded_browser = (CheckBox) rootView.findViewById(R.id.set_embedded_browser);
|
||||||
|
final LinearLayout set_javascript_container = (LinearLayout) rootView.findViewById(R.id.set_javascript_container);
|
||||||
|
final SwitchCompat set_javascript = (SwitchCompat) rootView.findViewById(R.id.set_javascript);
|
||||||
|
boolean javascript = sharedpreferences.getBoolean(Helper.SET_JAVASCRIPT, true);
|
||||||
|
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
|
||||||
|
if( !embedded_browser){
|
||||||
|
set_javascript_container.setVisibility(View.GONE);
|
||||||
|
}else{
|
||||||
|
set_javascript_container.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
set_embedded_browser.setChecked(embedded_browser);
|
||||||
|
set_embedded_browser.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putBoolean(Helper.SET_EMBEDDED_BROWSER, set_embedded_browser.isChecked());
|
||||||
|
editor.apply();
|
||||||
|
if( !set_embedded_browser.isChecked()){
|
||||||
|
set_javascript_container.setVisibility(View.GONE);
|
||||||
|
}else{
|
||||||
|
set_javascript_container.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
set_javascript.setChecked(javascript);
|
||||||
|
set_javascript.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putBoolean(Helper.SET_JAVASCRIPT, isChecked);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final LinearLayout set_cookies_container = (LinearLayout) rootView.findViewById(R.id.set_cookies_container);
|
||||||
|
final SwitchCompat set_cookies = (SwitchCompat) rootView.findViewById(R.id.set_cookies);
|
||||||
|
boolean cookies = sharedpreferences.getBoolean(Helper.SET_COOKIES, false);
|
||||||
|
|
||||||
|
set_cookies.setChecked(cookies);
|
||||||
|
set_cookies.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putBoolean(Helper.SET_COOKIES, isChecked);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
set_cookies_container.setVisibility(View.VISIBLE);
|
||||||
|
}else {
|
||||||
|
set_cookies_container.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle saveInstance) {
|
||||||
|
super.onCreate(saveInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -49,10 +49,10 @@ public class SettingsNotificationsFragment extends Fragment {
|
||||||
boolean notif_ask = sharedpreferences.getBoolean(Helper.SET_NOTIF_ASK, true);
|
boolean notif_ask = sharedpreferences.getBoolean(Helper.SET_NOTIF_ASK, true);
|
||||||
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
|
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
|
||||||
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
|
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
|
||||||
boolean notif_validation = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION, true);
|
|
||||||
boolean notif_wifi = sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false);
|
boolean notif_wifi = sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false);
|
||||||
boolean notif_silent = sharedpreferences.getBoolean(Helper.SET_NOTIF_SILENT, false);
|
boolean notif_silent = sharedpreferences.getBoolean(Helper.SET_NOTIF_SILENT, false);
|
||||||
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
|
|
||||||
boolean notif_hometimeline = sharedpreferences.getBoolean(Helper.SET_NOTIF_HOMETIMELINE, true);
|
boolean notif_hometimeline = sharedpreferences.getBoolean(Helper.SET_NOTIF_HOMETIMELINE, true);
|
||||||
|
|
||||||
final CheckBox set_notif_follow = (CheckBox) rootView.findViewById(R.id.set_notif_follow);
|
final CheckBox set_notif_follow = (CheckBox) rootView.findViewById(R.id.set_notif_follow);
|
||||||
|
@ -60,9 +60,9 @@ public class SettingsNotificationsFragment extends Fragment {
|
||||||
final CheckBox set_notif_follow_ask = (CheckBox) rootView.findViewById(R.id.set_notif_follow_ask);
|
final CheckBox set_notif_follow_ask = (CheckBox) rootView.findViewById(R.id.set_notif_follow_ask);
|
||||||
final CheckBox set_notif_follow_mention = (CheckBox) rootView.findViewById(R.id.set_notif_follow_mention);
|
final CheckBox set_notif_follow_mention = (CheckBox) rootView.findViewById(R.id.set_notif_follow_mention);
|
||||||
final CheckBox set_notif_follow_share = (CheckBox) rootView.findViewById(R.id.set_notif_follow_share);
|
final CheckBox set_notif_follow_share = (CheckBox) rootView.findViewById(R.id.set_notif_follow_share);
|
||||||
final CheckBox set_share_validation = (CheckBox) rootView.findViewById(R.id.set_share_validation);
|
|
||||||
final CheckBox set_notif_hometimeline = (CheckBox) rootView.findViewById(R.id.set_notif_hometimeline);
|
final CheckBox set_notif_hometimeline = (CheckBox) rootView.findViewById(R.id.set_notif_hometimeline);
|
||||||
final CheckBox set_show_error_messages = (CheckBox) rootView.findViewById(R.id.set_show_error_messages);
|
|
||||||
final SwitchCompat switchCompatWIFI = (SwitchCompat) rootView.findViewById(R.id.set_wifi_only);
|
final SwitchCompat switchCompatWIFI = (SwitchCompat) rootView.findViewById(R.id.set_wifi_only);
|
||||||
final SwitchCompat switchCompatSilent = (SwitchCompat) rootView.findViewById(R.id.set_silence);
|
final SwitchCompat switchCompatSilent = (SwitchCompat) rootView.findViewById(R.id.set_silence);
|
||||||
|
|
||||||
|
@ -71,9 +71,8 @@ public class SettingsNotificationsFragment extends Fragment {
|
||||||
set_notif_follow_ask.setChecked(notif_ask);
|
set_notif_follow_ask.setChecked(notif_ask);
|
||||||
set_notif_follow_mention.setChecked(notif_mention);
|
set_notif_follow_mention.setChecked(notif_mention);
|
||||||
set_notif_follow_share.setChecked(notif_share);
|
set_notif_follow_share.setChecked(notif_share);
|
||||||
set_share_validation.setChecked(notif_validation);
|
|
||||||
set_notif_hometimeline.setChecked(notif_hometimeline);
|
set_notif_hometimeline.setChecked(notif_hometimeline);
|
||||||
set_show_error_messages.setChecked(show_error_messages);
|
|
||||||
switchCompatWIFI.setChecked(notif_wifi);
|
switchCompatWIFI.setChecked(notif_wifi);
|
||||||
switchCompatSilent.setChecked(notif_silent);
|
switchCompatSilent.setChecked(notif_silent);
|
||||||
|
|
||||||
|
@ -125,22 +124,7 @@ public class SettingsNotificationsFragment extends Fragment {
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
set_share_validation.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
||||||
editor.putBoolean(Helper.SET_NOTIF_VALIDATION, set_share_validation.isChecked());
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
set_show_error_messages.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
||||||
editor.putBoolean(Helper.SET_SHOW_ERROR_MESSAGES, set_show_error_messages.isChecked());
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
switchCompatWIFI.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
switchCompatWIFI.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,7 +20,6 @@ import android.support.v4.app.Fragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.RadioGroup;
|
import android.widget.RadioGroup;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -46,18 +45,6 @@ public class SettingsOptimizationFragment extends Fragment {
|
||||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
|
||||||
|
|
||||||
boolean show_reply = sharedpreferences.getBoolean(Helper.SET_SHOW_REPLY, false);
|
|
||||||
final CheckBox set_show_reply = (CheckBox) rootView.findViewById(R.id.set_show_reply);
|
|
||||||
set_show_reply.setChecked(show_reply);
|
|
||||||
|
|
||||||
set_show_reply.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
|
||||||
editor.putBoolean(Helper.SET_SHOW_REPLY, set_show_reply.isChecked());
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//Status per page
|
//Status per page
|
||||||
SeekBar statusSeekBar = (SeekBar) rootView.findViewById(R.id.set_toots_per_page);
|
SeekBar statusSeekBar = (SeekBar) rootView.findViewById(R.id.set_toots_per_page);
|
||||||
|
|
|
@ -40,6 +40,7 @@ public class TabLayoutSettingsFragment extends Fragment {
|
||||||
View inflatedView = inflater.inflate(R.layout.tablayout_settings, container, false);
|
View inflatedView = inflater.inflate(R.layout.tablayout_settings, container, false);
|
||||||
|
|
||||||
TabLayout tabLayout = (TabLayout) inflatedView.findViewById(R.id.tabLayout);
|
TabLayout tabLayout = (TabLayout) inflatedView.findViewById(R.id.tabLayout);
|
||||||
|
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.settings)));
|
||||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.notifications)));
|
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.notifications)));
|
||||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.optimization)));
|
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.optimization)));
|
||||||
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.profile)));
|
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.profile)));
|
||||||
|
@ -84,10 +85,12 @@ public class TabLayoutSettingsFragment extends Fragment {
|
||||||
public Fragment getItem(int position) {
|
public Fragment getItem(int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
return new SettingsNotificationsFragment();
|
return new SettingsFragment();
|
||||||
case 1:
|
case 1:
|
||||||
return new SettingsOptimizationFragment();
|
return new SettingsNotificationsFragment();
|
||||||
case 2:
|
case 2:
|
||||||
|
return new SettingsOptimizationFragment();
|
||||||
|
case 3:
|
||||||
return new SettingsProfileFragment();
|
return new SettingsProfileFragment();
|
||||||
default:
|
default:
|
||||||
return new SettingsNotificationsFragment();
|
return new SettingsNotificationsFragment();
|
||||||
|
|
|
@ -51,6 +51,7 @@ import android.util.Log;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.webkit.WebView;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
@ -81,6 +82,7 @@ import java.util.regex.Pattern;
|
||||||
import fr.gouv.etalab.mastodon.activities.HashTagActivity;
|
import fr.gouv.etalab.mastodon.activities.HashTagActivity;
|
||||||
import fr.gouv.etalab.mastodon.activities.LoginActivity;
|
import fr.gouv.etalab.mastodon.activities.LoginActivity;
|
||||||
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
import fr.gouv.etalab.mastodon.activities.ShowAccountActivity;
|
||||||
|
import fr.gouv.etalab.mastodon.activities.WebviewActivity;
|
||||||
import fr.gouv.etalab.mastodon.asynctasks.RemoveAccountAsyncTask;
|
import fr.gouv.etalab.mastodon.asynctasks.RemoveAccountAsyncTask;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
import fr.gouv.etalab.mastodon.client.Entities.Account;
|
||||||
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
import fr.gouv.etalab.mastodon.client.Entities.Mention;
|
||||||
|
@ -155,6 +157,10 @@ public class Helper {
|
||||||
public static final String SET_NOTIF_SILENT = "set_notif_silent";
|
public static final String SET_NOTIF_SILENT = "set_notif_silent";
|
||||||
public static final String SET_SHOW_REPLY = "set_show_reply";
|
public static final String SET_SHOW_REPLY = "set_show_reply";
|
||||||
public static final String SET_SHOW_ERROR_MESSAGES = "set_show_error_messages";
|
public static final String SET_SHOW_ERROR_MESSAGES = "set_show_error_messages";
|
||||||
|
public static final String SET_EMBEDDED_BROWSER = "set_embedded_browser";
|
||||||
|
public static final String SET_JAVASCRIPT = "set_javascript";
|
||||||
|
public static final String SET_COOKIES = "set_cookies";
|
||||||
|
|
||||||
//End points
|
//End points
|
||||||
public static final String EP_AUTHORIZE = "/oauth/authorize";
|
public static final String EP_AUTHORIZE = "/oauth/authorize";
|
||||||
|
|
||||||
|
@ -179,6 +185,12 @@ public class Helper {
|
||||||
|
|
||||||
private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":([-+\\w]+):");
|
private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":([-+\\w]+):");
|
||||||
|
|
||||||
|
private static final Pattern urlPattern = Pattern.compile(
|
||||||
|
"(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)"
|
||||||
|
+ "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*"
|
||||||
|
+ "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)",
|
||||||
|
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts emojis in input to unicode
|
* Converts emojis in input to unicode
|
||||||
* @param input String
|
* @param input String
|
||||||
|
@ -793,19 +805,40 @@ public class Helper {
|
||||||
* @return TextView
|
* @return TextView
|
||||||
*/
|
*/
|
||||||
public static TextView clickableElements(final Context context, TextView statusTV, String fullContent, List<Mention> mentions, List<Tag> tags) {
|
public static TextView clickableElements(final Context context, TextView statusTV, String fullContent, List<Mention> mentions, List<Tag> tags) {
|
||||||
//Retrieves accounts name
|
|
||||||
Pattern sPattern = Pattern.compile("@<span>([a-zA-Z0-9_]{1,})<\\/span>");
|
|
||||||
Matcher m = sPattern.matcher(fullContent);
|
|
||||||
while (m.find()) {
|
|
||||||
fullContent = fullContent.replaceAll(m.group(0), "<font color='#000'>" + m.group(0) + "</font>");
|
|
||||||
}
|
|
||||||
SpannableString spannableString;
|
SpannableString spannableString;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
spannableString = new SpannableString(Html.fromHtml(fullContent, Html.FROM_HTML_MODE_COMPACT));
|
spannableString = new SpannableString(Html.fromHtml(fullContent, Html.FROM_HTML_MODE_COMPACT));
|
||||||
else
|
else
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
spannableString = new SpannableString(Html.fromHtml(fullContent));
|
spannableString = new SpannableString(Html.fromHtml(fullContent));
|
||||||
|
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
|
||||||
|
if( embedded_browser){
|
||||||
|
Matcher matcher = urlPattern.matcher(spannableString);
|
||||||
|
while (matcher.find()){
|
||||||
|
int matchStart = matcher.start(1);
|
||||||
|
int matchEnd = matcher.end();
|
||||||
|
final String url = spannableString.toString().substring(matchStart, matchEnd);
|
||||||
|
spannableString.setSpan(new ClickableSpan() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View textView) {
|
||||||
|
Intent intent = new Intent(context, WebviewActivity.class);
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.putString("url", url);
|
||||||
|
intent.putExtras(b);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void updateDrawState(TextPaint ds) {
|
||||||
|
super.updateDrawState(ds);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchStart, matchEnd,
|
||||||
|
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
//Deals with mention to make them clickable
|
//Deals with mention to make them clickable
|
||||||
if( mentions != null && mentions.size() > 0 ) {
|
if( mentions != null && mentions.size() > 0 ) {
|
||||||
//Looping through accounts which are mentioned
|
//Looping through accounts which are mentioned
|
||||||
|
|
|
@ -32,11 +32,23 @@
|
||||||
android:layout_height="10dp"
|
android:layout_height="10dp"
|
||||||
android:padding="2dp">
|
android:padding="2dp">
|
||||||
</ProgressBar>
|
</ProgressBar>
|
||||||
<WebView
|
<FrameLayout
|
||||||
android:id="@+id/webviewConnect"
|
android:id="@+id/webview_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1">
|
||||||
/>
|
<WebView
|
||||||
|
android:id="@+id/webview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
</FrameLayout>
|
||||||
|
<!-- View where the video will be shown when video goes fullscreen -->
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/videoLayout"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:background="@color/black"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</android.support.v4.widget.DrawerLayout>
|
</android.support.v4.widget.DrawerLayout>
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2017 Thomas Schneider
|
||||||
|
|
||||||
|
This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Mastodon Etalab 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 Thomas Schneider; if not,
|
||||||
|
see <http://www.gnu.org/licenses>
|
||||||
|
-->
|
||||||
|
<android.support.v4.widget.DrawerLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/drawer_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/layout_login"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<ProgressBar android:id="@+id/progress_bar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:padding="2dp">
|
||||||
|
</ProgressBar>
|
||||||
|
<WebView
|
||||||
|
android:id="@+id/webviewConnect"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</android.support.v4.widget.DrawerLayout>
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2017 Thomas Schneider
|
||||||
|
|
||||||
|
This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Mastodon Etalab 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 Thomas Schneider; if not,
|
||||||
|
see <http://www.gnu.org/licenses>.
|
||||||
|
-->
|
||||||
|
<ScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/swipeContainer"
|
||||||
|
android:paddingLeft="@dimen/drawer_padding"
|
||||||
|
android:paddingRight="@dimen/drawer_padding"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="@dimen/fab_margin"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:ignore="UselessParent">
|
||||||
|
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/set_share_validation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="@string/set_share_validation"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/set_show_error_messages"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="@string/set_show_error_messages"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:id="@+id/set_show_reply"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="@string/set_display_reply"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:id="@+id/set_embedded_browser"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:text="@string/embedded_browser"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/set_javascript_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/use_javascript"/>
|
||||||
|
<android.support.v7.widget.SwitchCompat
|
||||||
|
android:id="@+id/set_javascript"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/set_cookies_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/use_cookies"/>
|
||||||
|
<android.support.v7.widget.SwitchCompat
|
||||||
|
android:id="@+id/set_cookies"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
|
@ -93,17 +93,6 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/set_share_validation"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:text="@string/set_share_validation"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/set_show_error_messages"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:text="@string/set_show_error_messages"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -152,12 +152,6 @@
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<!-- MORE OPTIONS SETTINGS -->
|
<!-- MORE OPTIONS SETTINGS -->
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:id="@+id/set_show_reply"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:text="@string/set_display_reply"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
<!-- END OPTIMIZATION SETTINGS -->
|
<!-- END OPTIMIZATION SETTINGS -->
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -25,8 +25,9 @@
|
||||||
android:id="@+id/tabLayout"
|
android:id="@+id/tabLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
app:tabMaxWidth="0dp"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
app:tabMode="fixed"
|
app:tabMode="scrollable"
|
||||||
app:tabGravity="fill"
|
app:tabGravity="fill"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2017 Thomas Schneider
|
||||||
|
|
||||||
|
This file is a part of Mastodon Etalab for mastodon.etalab.gouv.fr
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Mastodon Etalab 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 Thomas Schneider; if not,
|
||||||
|
see <http://www.gnu.org/licenses>.
|
||||||
|
-->
|
||||||
|
<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="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
tools:ignore="UseCompoundDrawables">
|
||||||
|
<ImageView
|
||||||
|
android:background="@color/white"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:id="@+id/webview_favicon"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
<TextView
|
||||||
|
android:layout_marginLeft="5dp"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:id="@+id/webview_title"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
</LinearLayout>
|
|
@ -23,4 +23,6 @@
|
||||||
<color name="background_image">#282c37</color>
|
<color name="background_image">#282c37</color>
|
||||||
<color name="green_1">#009688</color>
|
<color name="green_1">#009688</color>
|
||||||
<color name="red_1">#F44336</color>
|
<color name="red_1">#F44336</color>
|
||||||
|
|
||||||
|
<color name="black">#000</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
<string name="notifications">Notifications</string>
|
<string name="notifications">Notifications</string>
|
||||||
<string name="follow_request">Demandes d\'abonnements</string>
|
<string name="follow_request">Demandes d\'abonnements</string>
|
||||||
<string name="optimization">Optimisation</string>
|
<string name="optimization">Optimisation</string>
|
||||||
|
<string name="settings">Paramètres</string>
|
||||||
<string name="profile">Profil</string>
|
<string name="profile">Profil</string>
|
||||||
<string name="make_a_choice">Que souhaitez-vous faire ?</string>
|
<string name="make_a_choice">Que souhaitez-vous faire ?</string>
|
||||||
<string name="delete_account_title">Supprimer un compte</string>
|
<string name="delete_account_title">Supprimer un compte</string>
|
||||||
|
@ -242,6 +243,10 @@
|
||||||
<string name="note_no_space">Vous avez atteint les 160 caractères autorisés !</string>
|
<string name="note_no_space">Vous avez atteint les 160 caractères autorisés !</string>
|
||||||
<string name="username_no_space">Vous avez atteint les 30 caractères autorisés !</string>
|
<string name="username_no_space">Vous avez atteint les 30 caractères autorisés !</string>
|
||||||
|
|
||||||
|
<string name="embedded_browser">Utiliser le navigateur intégré</string>
|
||||||
|
<string name="use_javascript">Activer Javascript</string>
|
||||||
|
<string name="use_cookies">Autoriser les cookies tiers</string>
|
||||||
|
|
||||||
<string name="set_title_news">Actualités</string>
|
<string name="set_title_news">Actualités</string>
|
||||||
<string name="set_notification_news">Notifier lors de nouveaux pouets sur la page d\'accueil</string>
|
<string name="set_notification_news">Notifier lors de nouveaux pouets sur la page d\'accueil</string>
|
||||||
<string name="set_show_error_messages">Afficher les messages d\'erreur</string>
|
<string name="set_show_error_messages">Afficher les messages d\'erreur</string>
|
||||||
|
|
Loading…
Reference in New Issue