migrating to kotlin
This commit is contained in:
parent
f63282f039
commit
8047612281
|
@ -62,7 +62,7 @@ public class NyanDaydreamService extends DreamService implements NyanConstants,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) {
|
||||
updateView();
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class NyanWallpaperService extends WallpaperService implements NyanConsta
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) {
|
||||
updateSurface();
|
||||
}
|
||||
|
|
|
@ -65,12 +65,10 @@ android {
|
|||
resValue("bool", "debug", "false")
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
res.srcDirs += project.files("src/$name/res-localized")
|
||||
res.srcDirs += project.files("src/$name/res-svg2png")
|
||||
java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
sourceSets.each {
|
||||
it.res.srcDirs += project.files("src/${it.name}/res-localized")
|
||||
it.res.srcDirs += project.files("src/${it.name}/res-svg2png")
|
||||
it.java.srcDirs += "src/${it.name}/kotlin"
|
||||
}
|
||||
testOptions {
|
||||
unitTests.returnDefaultValues = true
|
||||
|
|
|
@ -17,30 +17,27 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.Fragment
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity;
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/1.
|
||||
*/
|
||||
public final class TwitterCardFragmentFactoryImpl extends TwitterCardFragmentFactory {
|
||||
class TwitterCardFragmentFactoryImpl : TwitterCardFragmentFactory() {
|
||||
|
||||
@Override
|
||||
public Fragment createAnimatedGifFragment(ParcelableCardEntity card) {
|
||||
return null;
|
||||
override fun createAnimatedGifFragment(card: ParcelableCardEntity): Fragment? {
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment createAudioFragment(ParcelableCardEntity card) {
|
||||
return null;
|
||||
override fun createAudioFragment(card: ParcelableCardEntity): Fragment? {
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment createPlayerFragment(ParcelableCardEntity card) {
|
||||
return null;
|
||||
override fun createPlayerFragment(card: ParcelableCardEntity): Fragment? {
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.auth.api.Auth;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/5/14.
|
||||
*/
|
||||
public class PlusServiceGoogleSignInActivity extends BasePlusServiceSignInActivity implements
|
||||
GoogleApiClient.OnConnectionFailedListener {
|
||||
|
||||
private static final int REQUEST_GOOGLE_SIGN_IN = 101;
|
||||
|
||||
private GoogleApiClient mGoogleApiClient;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
// Configure sign-in to request the user's ID, email address, and basic
|
||||
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
|
||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestEmail()
|
||||
.requestIdToken(GOOGLE_APIS_SERVER_CLIENT_ID)
|
||||
.build();
|
||||
// Build a GoogleApiClient with access to the Google Sign-In API and the
|
||||
// options specified by gso.
|
||||
mGoogleApiClient = new GoogleApiClient.Builder(this)
|
||||
.enableAutoManage(this, this)
|
||||
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
|
||||
.build();
|
||||
signInWithGoogle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
|
||||
if (requestCode == REQUEST_GOOGLE_SIGN_IN) {
|
||||
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
|
||||
handleSignInResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
|
||||
|
||||
}
|
||||
|
||||
private void signInWithGoogle() {
|
||||
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
|
||||
startActivityForResult(signInIntent, REQUEST_GOOGLE_SIGN_IN);
|
||||
}
|
||||
|
||||
private void handleSignInResult(GoogleSignInResult result) {
|
||||
Log.d(LOGTAG, "handleSignInResult:" + result.isSuccess());
|
||||
if (result.isSuccess()) {
|
||||
// TODO Signed in successfully, show authenticated UI.
|
||||
GoogleSignInAccount acct = result.getSignInAccount();
|
||||
acct.getIdToken();
|
||||
Log.d(LOGTAG, "sign in name:" + acct.getDisplayName());
|
||||
} else {
|
||||
// TODO Signed out, show unauthenticated UI.
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.gms.maps.CameraUpdate;
|
||||
import com.google.android.gms.maps.CameraUpdateFactory;
|
||||
import com.google.android.gms.maps.GoogleMap;
|
||||
import com.google.android.gms.maps.OnMapReadyCallback;
|
||||
import com.google.android.gms.maps.SupportMapFragment;
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
import com.google.android.gms.maps.model.MarkerOptions;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment;
|
||||
import org.mariotaku.twidere.fragment.iface.IMapFragment;
|
||||
|
||||
public class GoogleMapFragment extends SupportMapFragment implements Constants, IMapFragment, IBaseFragment {
|
||||
|
||||
private GoogleMap mMapView;
|
||||
private ActionHelper mActionHelper = new ActionHelper(this);
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
final Bundle args = getArguments();
|
||||
if (args == null || !args.containsKey(EXTRA_LATITUDE) || !args.containsKey(EXTRA_LONGITUDE))
|
||||
return;
|
||||
final double lat = args.getDouble(EXTRA_LATITUDE, 0.0), lng = args.getDouble(EXTRA_LONGITUDE, 0.0);
|
||||
getMapAsync(new OnMapReadyCallback() {
|
||||
@Override
|
||||
public void onMapReady(GoogleMap googleMap) {
|
||||
mMapView = googleMap;
|
||||
final MarkerOptions marker = new MarkerOptions();
|
||||
marker.position(new LatLng(lat, lng));
|
||||
mMapView.addMarker(marker);
|
||||
center(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mActionHelper.dispatchOnPause();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mActionHelper.dispatchOnResumeFragments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_google_maps_viewer, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
requestFitSystemWindows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.center: {
|
||||
center();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void center() {
|
||||
center(true);
|
||||
}
|
||||
|
||||
public void center(final boolean animate) {
|
||||
final Bundle args = getArguments();
|
||||
if (mMapView == null || args == null || !args.containsKey(EXTRA_LATITUDE) || !args.containsKey(EXTRA_LONGITUDE))
|
||||
return;
|
||||
final double lat = args.getDouble(EXTRA_LATITUDE, 0.0), lng = args.getDouble(EXTRA_LONGITUDE, 0.0);
|
||||
final CameraUpdate c = CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 12);
|
||||
if (animate) {
|
||||
mMapView.animateCamera(c);
|
||||
} else {
|
||||
mMapView.moveCamera(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Bundle getExtraConfiguration() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTabPosition() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFitSystemWindows() {
|
||||
final Activity activity = getActivity();
|
||||
final Fragment parentFragment = getParentFragment();
|
||||
final IBaseFragment.SystemWindowsInsetsCallback callback;
|
||||
if (parentFragment instanceof IBaseFragment.SystemWindowsInsetsCallback) {
|
||||
callback = (IBaseFragment.SystemWindowsInsetsCallback) parentFragment;
|
||||
} else if (activity instanceof IBaseFragment.SystemWindowsInsetsCallback) {
|
||||
callback = (IBaseFragment.SystemWindowsInsetsCallback) activity;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
final Rect insets = new Rect();
|
||||
if (callback.getSystemWindowsInsets(insets)) {
|
||||
fitSystemWindows(insets);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAfterFragmentResumed(Action action) {
|
||||
mActionHelper.executeAfterFragmentResumed(action);
|
||||
}
|
||||
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
final View view = getView();
|
||||
if (view != null) {
|
||||
view.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.iface.IMapFragment;
|
||||
import org.mariotaku.twidere.util.webkit.DefaultWebViewClient;
|
||||
|
||||
public class WebMapFragment extends BaseSupportWebViewFragment implements IMapFragment {
|
||||
|
||||
private static final String MAPVIEW_URI = "file:///android_asset/mapview.html";
|
||||
|
||||
private double latitude, longitude;
|
||||
|
||||
@Override
|
||||
public void center() {
|
||||
final WebView webview = getWebView();
|
||||
webview.loadUrl("javascript:center();");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.center: {
|
||||
center();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_google_maps_viewer, menu);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
getLocation();
|
||||
setupWebView();
|
||||
}
|
||||
|
||||
/**
|
||||
* The Location Manager manages location providers. This code searches for
|
||||
* the best provider of data (GPS, WiFi/cell phone tower lookup, some other
|
||||
* mechanism) and finds the last known location.
|
||||
*/
|
||||
private void getLocation() {
|
||||
final Bundle bundle = getArguments();
|
||||
if (bundle != null) {
|
||||
latitude = bundle.getDouble(EXTRA_LATITUDE, 0.0);
|
||||
longitude = bundle.getDouble(EXTRA_LONGITUDE, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the WebView object and loads the URL of the page *
|
||||
*/
|
||||
private void setupWebView() {
|
||||
|
||||
final WebView webview = getWebView();
|
||||
webview.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
|
||||
webview.setWebViewClient(new MapWebViewClient(getActivity()));
|
||||
webview.loadUrl(MAPVIEW_URI);
|
||||
|
||||
final WebSettings settings = webview.getSettings();
|
||||
settings.setBuiltInZoomControls(false);
|
||||
|
||||
/** Allows JavaScript calls to access application resources **/
|
||||
webview.addJavascriptInterface(new MapJavaScriptInterface(), "android");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the interface for getting access to Latitude and Longitude data
|
||||
* from device
|
||||
*/
|
||||
class MapJavaScriptInterface {
|
||||
|
||||
@JavascriptInterface
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MapWebViewClient extends DefaultWebViewClient {
|
||||
|
||||
public MapWebViewClient(final Activity activity) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(final WebView view, final String url) {
|
||||
final Uri uri = Uri.parse(url);
|
||||
if (uri.getScheme().equals(Uri.parse(MAPVIEW_URI).getScheme())) return false;
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/7/8.
|
||||
*/
|
||||
public class TwidereBugReporter extends BugReporter implements Constants {
|
||||
|
||||
@Override
|
||||
protected void logImpl(int priority, String tag, String msg) {
|
||||
Crashlytics.log(priority, tag, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void logExceptionImpl(@NonNull final Throwable throwable) {
|
||||
Crashlytics.logException(throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initImpl(final Application application) {
|
||||
Fabric.with(application, new Crashlytics());
|
||||
Crashlytics.setBool("debug", BuildConfig.DEBUG);
|
||||
Crashlytics.setString("build.brand", Build.BRAND);
|
||||
Crashlytics.setString("build.device", Build.DEVICE);
|
||||
Crashlytics.setString("build.display", Build.DISPLAY);
|
||||
Crashlytics.setString("build.hardware", Build.HARDWARE);
|
||||
Crashlytics.setString("build.manufacturer", Build.MANUFACTURER);
|
||||
Crashlytics.setString("build.model", Build.MODEL);
|
||||
Crashlytics.setString("build.product", Build.PRODUCT);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import com.google.android.youtube.player.YouTubeInitializationResult;
|
||||
import com.google.android.youtube.player.YouTubePlayer;
|
||||
import com.google.android.youtube.player.YouTubePlayerSupportFragment;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/1.
|
||||
*/
|
||||
public final class TwitterCardFragmentFactoryImpl extends TwitterCardFragmentFactory {
|
||||
|
||||
private static final String YOUTUBE_DATA_API_KEY = "AIzaSyCVdCIMFFxdNqHnCPrJ9yKUzoTfs8jhYGc";
|
||||
|
||||
@Override
|
||||
public Fragment createAnimatedGifFragment(ParcelableCardEntity card) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment createAudioFragment(ParcelableCardEntity card) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment createPlayerFragment(ParcelableCardEntity card) {
|
||||
if (Boolean.parseBoolean("true")) return null;
|
||||
final String appUrlResolved = ParcelableCardEntityUtils.getString(card, "app_url_resolved");
|
||||
final String domain = ParcelableCardEntityUtils.getString(card, "domain");
|
||||
if (domain != null && appUrlResolved != null) {
|
||||
final Uri uri = Uri.parse(appUrlResolved);
|
||||
final String paramV = uri.getQueryParameter("v");
|
||||
if ("www.youtube.com".equals(domain) && paramV != null) {
|
||||
final YouTubePlayerSupportFragment fragment = YouTubePlayerSupportFragment.newInstance();
|
||||
fragment.initialize(YOUTUBE_DATA_API_KEY, new YouTubePlayer.OnInitializedListener() {
|
||||
@Override
|
||||
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
|
||||
if (!wasRestored) {
|
||||
player.cueVideo(paramV);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
|
||||
final FragmentActivity activity = fragment.getActivity();
|
||||
if (activity == null) return;
|
||||
// if (errorReason.isUserRecoverableError()) {
|
||||
// errorReason.getErrorDialog(activity, RECOVERY_DIALOG_REQUEST).show();
|
||||
// } else {
|
||||
// Toast.makeText(activity, errorReason.toString(), Toast.LENGTH_LONG).show();
|
||||
// }
|
||||
}
|
||||
});
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package org.mariotaku.twidere.activity
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.google.android.gms.auth.api.Auth
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInResult
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.api.GoogleApiClient
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/5/14.
|
||||
*/
|
||||
class PlusServiceGoogleSignInActivity : BasePlusServiceSignInActivity(), GoogleApiClient.OnConnectionFailedListener {
|
||||
|
||||
private var mGoogleApiClient: GoogleApiClient? = null
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// Configure sign-in to request the user's ID, email address, and basic
|
||||
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
|
||||
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().requestIdToken(GOOGLE_APIS_SERVER_CLIENT_ID).build()
|
||||
// Build a GoogleApiClient with access to the Google Sign-In API and the
|
||||
// options specified by gso.
|
||||
mGoogleApiClient = GoogleApiClient.Builder(this).enableAutoManage(this, this).addApi(Auth.GOOGLE_SIGN_IN_API, gso).build()
|
||||
signInWithGoogle()
|
||||
}
|
||||
|
||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
|
||||
if (requestCode == REQUEST_GOOGLE_SIGN_IN) {
|
||||
val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
|
||||
handleSignInResult(result)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConnectionFailed(connectionResult: ConnectionResult) {
|
||||
|
||||
}
|
||||
|
||||
private fun signInWithGoogle() {
|
||||
val signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient)
|
||||
startActivityForResult(signInIntent, REQUEST_GOOGLE_SIGN_IN)
|
||||
}
|
||||
|
||||
private fun handleSignInResult(result: GoogleSignInResult) {
|
||||
Log.d(LOGTAG, "handleSignInResult:" + result.isSuccess)
|
||||
if (result.isSuccess) {
|
||||
// TODO Signed in successfully, show authenticated UI.
|
||||
val acct = result.signInAccount
|
||||
acct!!.idToken
|
||||
Log.d(LOGTAG, "sign in name:" + acct.displayName!!)
|
||||
} else {
|
||||
// TODO Signed out, show unauthenticated UI.
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val REQUEST_GOOGLE_SIGN_IN = 101
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.webkit.JavascriptInterface
|
||||
import android.webkit.WebView
|
||||
import org.mariotaku.twidere.Constants.EXTRA_LATITUDE
|
||||
import org.mariotaku.twidere.Constants.EXTRA_LONGITUDE
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.fragment.iface.IMapFragment
|
||||
import org.mariotaku.twidere.util.webkit.DefaultWebViewClient
|
||||
|
||||
class WebMapFragment : BaseSupportWebViewFragment(), IMapFragment {
|
||||
|
||||
private var latitude: Double = 0.toDouble()
|
||||
private var longitude: Double = 0.toDouble()
|
||||
|
||||
override fun center() {
|
||||
webView?.loadUrl("javascript:center();")
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item!!.itemId) {
|
||||
R.id.center -> {
|
||||
center()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
inflater!!.inflate(R.menu.menu_google_maps_viewer, menu)
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
getLocation()
|
||||
setupWebView()
|
||||
}
|
||||
|
||||
/**
|
||||
* The Location Manager manages location providers. This code searches for
|
||||
* the best provider of data (GPS, WiFi/cell phone tower lookup, some other
|
||||
* mechanism) and finds the last known location.
|
||||
*/
|
||||
private fun getLocation() {
|
||||
val bundle = arguments
|
||||
if (bundle != null) {
|
||||
latitude = bundle.getDouble(EXTRA_LATITUDE, 0.0)
|
||||
longitude = bundle.getDouble(EXTRA_LONGITUDE, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the WebView object and loads the URL of the page *
|
||||
*/
|
||||
private fun setupWebView() {
|
||||
|
||||
val webView = webView!!
|
||||
webView.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
|
||||
webView.setWebViewClient(MapWebViewClient(activity))
|
||||
webView.loadUrl(MAPVIEW_URI)
|
||||
|
||||
val settings = webView.settings
|
||||
settings.builtInZoomControls = false
|
||||
|
||||
/** Allows JavaScript calls to access application resources */
|
||||
webView.addJavascriptInterface(MapJavaScriptInterface(this), "android")
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the interface for getting access to Latitude and Longitude data
|
||||
* from device
|
||||
*/
|
||||
internal class MapJavaScriptInterface(val fragment: WebMapFragment) {
|
||||
|
||||
@JavascriptInterface
|
||||
fun getLatitude(): Double {
|
||||
return fragment.latitude
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun getLongitude(): Double {
|
||||
return fragment.longitude
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal inner class MapWebViewClient(activity: Activity) : DefaultWebViewClient(activity) {
|
||||
|
||||
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
|
||||
val uri = Uri.parse(url)
|
||||
if (uri.scheme == Uri.parse(MAPVIEW_URI).scheme) return false
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
startActivity(intent)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val MAPVIEW_URI = "file:///android_asset/mapview.html"
|
||||
}
|
||||
|
||||
}
|
|
@ -17,26 +17,25 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.content.Context
|
||||
import android.support.v4.app.Fragment
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GoogleApiAvailability;
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
|
||||
import org.mariotaku.twidere.fragment.GoogleMapFragment;
|
||||
import org.mariotaku.twidere.fragment.WebMapFragment;
|
||||
import org.mariotaku.twidere.fragment.GoogleMapFragment
|
||||
import org.mariotaku.twidere.fragment.WebMapFragment
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/4/27.
|
||||
*/
|
||||
public class MapFragmentFactoryImpl extends MapFragmentFactory {
|
||||
@Override
|
||||
public Fragment createMapFragment(Context context) {
|
||||
class MapFragmentFactoryImpl : MapFragmentFactory() {
|
||||
override fun createMapFragment(context: Context): Fragment? {
|
||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS) {
|
||||
return new GoogleMapFragment();
|
||||
return GoogleMapFragment()
|
||||
}
|
||||
return new WebMapFragment();
|
||||
return WebMapFragment()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.app.Application
|
||||
import android.os.Build
|
||||
import com.crashlytics.android.Crashlytics
|
||||
import io.fabric.sdk.android.Fabric
|
||||
import org.mariotaku.twidere.BuildConfig
|
||||
import org.mariotaku.twidere.Constants
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/7/8.
|
||||
*/
|
||||
class TwidereBugReporter : BugReporter(), Constants {
|
||||
|
||||
override fun logImpl(priority: Int, tag: String, msg: String) {
|
||||
Crashlytics.log(priority, tag, msg)
|
||||
}
|
||||
|
||||
override fun logExceptionImpl(throwable: Throwable) {
|
||||
Crashlytics.logException(throwable)
|
||||
}
|
||||
|
||||
override fun initImpl(application: Application) {
|
||||
Fabric.with(application, Crashlytics())
|
||||
Crashlytics.setBool("debug", BuildConfig.DEBUG)
|
||||
Crashlytics.setString("build.brand", Build.BRAND)
|
||||
Crashlytics.setString("build.device", Build.DEVICE)
|
||||
Crashlytics.setString("build.display", Build.DISPLAY)
|
||||
Crashlytics.setString("build.hardware", Build.HARDWARE)
|
||||
Crashlytics.setString("build.manufacturer", Build.MANUFACTURER)
|
||||
Crashlytics.setString("build.model", Build.MODEL)
|
||||
Crashlytics.setString("build.product", Build.PRODUCT)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.net.Uri
|
||||
import android.support.v4.app.Fragment
|
||||
import com.google.android.youtube.player.YouTubeInitializationResult
|
||||
import com.google.android.youtube.player.YouTubePlayer
|
||||
import com.google.android.youtube.player.YouTubePlayerSupportFragment
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity
|
||||
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/1.
|
||||
*/
|
||||
class TwitterCardFragmentFactoryImpl : TwitterCardFragmentFactory() {
|
||||
|
||||
override fun createAnimatedGifFragment(card: ParcelableCardEntity): Fragment? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun createAudioFragment(card: ParcelableCardEntity): Fragment? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun createPlayerFragment(card: ParcelableCardEntity): Fragment? {
|
||||
if (java.lang.Boolean.parseBoolean("true")) return null
|
||||
val appUrlResolved = ParcelableCardEntityUtils.getString(card, "app_url_resolved")
|
||||
val domain = ParcelableCardEntityUtils.getString(card, "domain")
|
||||
if (domain != null && appUrlResolved != null) {
|
||||
val uri = Uri.parse(appUrlResolved)
|
||||
val paramV = uri.getQueryParameter("v")
|
||||
if ("www.youtube.com" == domain && paramV != null) {
|
||||
val fragment = YouTubePlayerSupportFragment.newInstance()
|
||||
fragment.initialize(YOUTUBE_DATA_API_KEY, object : YouTubePlayer.OnInitializedListener {
|
||||
override fun onInitializationSuccess(provider: YouTubePlayer.Provider, player: YouTubePlayer, wasRestored: Boolean) {
|
||||
if (!wasRestored) {
|
||||
player.cueVideo(paramV)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInitializationFailure(provider: YouTubePlayer.Provider, errorReason: YouTubeInitializationResult) {
|
||||
val activity = fragment.activity ?: return
|
||||
// if (errorReason.isUserRecoverableError()) {
|
||||
// errorReason.getErrorDialog(activity, RECOVERY_DIALOG_REQUEST).show();
|
||||
// } else {
|
||||
// Toast.makeText(activity, errorReason.toString(), Toast.LENGTH_LONG).show();
|
||||
// }
|
||||
}
|
||||
})
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val YOUTUBE_DATA_API_KEY = "AIzaSyCVdCIMFFxdNqHnCPrJ9yKUzoTfs8jhYGc"
|
||||
}
|
||||
|
||||
}
|
|
@ -60,7 +60,7 @@ public class NyanActivity extends Activity implements OnLongClickListener, OnSha
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
if (KEY_LIVE_WALLPAPER_SCALE.equals(key)) {
|
||||
updateSurface();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.adapter;
|
|||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
|
@ -178,7 +179,8 @@ public class AccountsAdapter extends SimpleDragSortCursorAdapter implements IBas
|
|||
}
|
||||
|
||||
@Override
|
||||
public Cursor swapCursor(final Cursor cursor) {
|
||||
@Nullable
|
||||
public Cursor swapCursor(@Nullable final Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
mIndices = new ParcelableAccountCursorIndices(cursor);
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ public class ComposeAutoCompleteAdapter extends SimpleCursorAdapter implements C
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public Cursor swapCursor(final Cursor cursor) {
|
||||
public Cursor swapCursor(@Nullable final Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
mTypeIdx = cursor.getColumnIndex(Suggestions.AutoComplete.TYPE);
|
||||
mTitleIdx = cursor.getColumnIndex(Suggestions.AutoComplete.TITLE);
|
||||
|
|
|
@ -78,7 +78,7 @@ public class SourceAutoCompleteAdapter extends SimpleCursorAdapter {
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public Cursor swapCursor(final Cursor cursor) {
|
||||
public Cursor swapCursor(@Nullable final Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
mSourceIdx = cursor.getColumnIndex(CachedStatuses.SOURCE);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class TrendsAdapter extends SimpleCursorAdapter {
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public Cursor swapCursor(Cursor c) {
|
||||
public Cursor swapCursor(@Nullable Cursor c) {
|
||||
if (c != null) {
|
||||
mNameIdx = c.getColumnIndex(TwidereDataStore.CachedTrends.NAME);
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ public class UserAutoCompleteAdapter extends SimpleCursorAdapter {
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public Cursor swapCursor(final Cursor cursor) {
|
||||
public Cursor swapCursor(@Nullable final Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
mIdIdx = cursor.getColumnIndex(CachedUsers.USER_KEY);
|
||||
mNameIdx = cursor.getColumnIndex(CachedUsers.NAME);
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
|
||||
public class AccountNotificationSettingsFragment extends BaseAccountPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final Preference preference = findPreference(KEY_NOTIFICATION_LIGHT_COLOR);
|
||||
final ParcelableAccount account = getAccount();
|
||||
if (preference != null && account != null) {
|
||||
preference.setDefaultValue(account.color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferencesResource() {
|
||||
return R.xml.preferences_account_notifications;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getSwitchPreferenceDefault() {
|
||||
return DEFAULT_NOTIFICATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSwitchPreferenceKey() {
|
||||
return KEY_NOTIFICATION;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
public class AccountRefreshSettingsFragment extends BaseAccountPreferenceFragment {
|
||||
|
||||
@Override
|
||||
protected int getPreferencesResource() {
|
||||
return R.xml.preferences_account_refresh;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getSwitchPreferenceDefault() {
|
||||
return DEFAULT_AUTO_REFRESH;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String getSwitchPreferenceKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
if (KEY_AUTO_REFRESH.equals(key)) {
|
||||
Utils.startRefreshServiceIfNeeded(activity);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,14 @@ import org.mariotaku.twidere.util.collection.CompactHashSet;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_ALPHA_SLIDER;
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_COLOR;
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_ID;
|
||||
import static org.mariotaku.twidere.Constants.INTENT_ACTION_TWITTER_LOGIN;
|
||||
import static org.mariotaku.twidere.Constants.KEY_DEFAULT_ACCOUNT_KEY;
|
||||
import static org.mariotaku.twidere.Constants.KEY_NEW_DOCUMENT_API;
|
||||
import static org.mariotaku.twidere.Constants.REQUEST_SET_COLOR;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/10/26.
|
||||
*/
|
||||
|
@ -295,7 +303,7 @@ public class AccountsManagerFragment extends BaseSupportFragment implements Load
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (KEY_DEFAULT_ACCOUNT_KEY.equals(key)) {
|
||||
updateDefaultAccount();
|
||||
}
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
|
||||
public abstract class BaseAccountPreferenceFragment extends BasePreferenceFragment implements
|
||||
OnCheckedChangeListener, OnSharedPreferenceChangeListener {
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle bundle, String s) {
|
||||
final PreferenceManager pm = getPreferenceManager();
|
||||
final ParcelableAccount account = getArguments().getParcelable(EXTRA_ACCOUNT);
|
||||
final String preferenceName = ACCOUNT_PREFERENCES_NAME_PREFIX
|
||||
+ (account != null ? account.account_key : "unknown");
|
||||
pm.setSharedPreferencesName(preferenceName);
|
||||
addPreferencesFromResource(getPreferencesResource());
|
||||
final SharedPreferences prefs = pm.getSharedPreferences();
|
||||
prefs.registerOnSharedPreferenceChangeListener(this);
|
||||
final Activity activity = getActivity();
|
||||
final Intent intent = activity.getIntent();
|
||||
if (account != null && intent.hasExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT)) {
|
||||
final boolean nameFirst = prefs.getBoolean(KEY_NAME_FIRST, true);
|
||||
final String name = mUserColorNameManager.getDisplayName(account.account_key,
|
||||
account.name, account.screen_name, nameFirst);
|
||||
activity.setTitle(name);
|
||||
}
|
||||
updatePreferenceScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
final PreferenceManager pm = getPreferenceManager();
|
||||
final SharedPreferences prefs = pm.getSharedPreferences();
|
||||
prefs.unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
|
||||
final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
|
||||
final SharedPreferences.Editor editor = prefs.edit();
|
||||
if (prefs.getBoolean(getSwitchPreferenceKey(), getSwitchPreferenceDefault()) != isChecked) {
|
||||
editor.putBoolean(getSwitchPreferenceKey(), isChecked);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
|
||||
final String switchKey = getSwitchPreferenceKey();
|
||||
if (!TextUtils.isEmpty(switchKey)) {
|
||||
inflater.inflate(R.menu.menu_switch_preference, menu);
|
||||
final View actionView = menu.findItem(R.id.toggle).getActionView();
|
||||
final CompoundButton toggle = (CompoundButton) actionView.findViewById(android.R.id.toggle);
|
||||
final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
|
||||
toggle.setOnCheckedChangeListener(this);
|
||||
toggle.setChecked(prefs.getBoolean(switchKey, getSwitchPreferenceDefault()));
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
if (key.equals(getSwitchPreferenceKey())) {
|
||||
updatePreferenceScreen();
|
||||
}
|
||||
}
|
||||
|
||||
protected ParcelableAccount getAccount() {
|
||||
final Bundle args = getArguments();
|
||||
if (args == null) return null;
|
||||
return args.getParcelable(EXTRA_ACCOUNT);
|
||||
}
|
||||
|
||||
protected abstract int getPreferencesResource();
|
||||
|
||||
protected abstract boolean getSwitchPreferenceDefault();
|
||||
|
||||
@Nullable
|
||||
protected abstract String getSwitchPreferenceKey();
|
||||
|
||||
private void updatePreferenceScreen() {
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
final SharedPreferences sharedPreferences = getPreferenceManager().getSharedPreferences();
|
||||
if (screen == null || sharedPreferences == null) return;
|
||||
screen.setEnabled(sharedPreferences.getBoolean(getSwitchPreferenceKey(), getSwitchPreferenceDefault()));
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.preference.RingtonePreference;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public abstract class BasePreferenceFragment extends PreferenceFragmentCompat implements Constants {
|
||||
|
||||
private static final int REQUEST_PICK_RINGTONE = 301;
|
||||
private static final String EXTRA_RINGTONE_PREFERENCE_KEY = "internal:ringtone_preference_key";
|
||||
private String mRingtonePreferenceKey;
|
||||
|
||||
@Inject
|
||||
protected KeyboardShortcutsHandler mKeyboardShortcutHandler;
|
||||
@Inject
|
||||
protected UserColorNameManager mUserColorNameManager;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
GeneralComponentHelper.build(context).inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
if (savedInstanceState != null) {
|
||||
mRingtonePreferenceKey = savedInstanceState.getString(EXTRA_RINGTONE_PREFERENCE_KEY);
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putString(EXTRA_RINGTONE_PREFERENCE_KEY, mRingtonePreferenceKey);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_PICK_RINGTONE: {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
Uri ringtone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
if (mRingtonePreferenceKey != null) {
|
||||
RingtonePreference ringtonePreference = (RingtonePreference)
|
||||
findPreference(mRingtonePreferenceKey);
|
||||
if (ringtonePreference != null) {
|
||||
ringtonePreference.setValue(ringtone != null ? ringtone.toString() : null);
|
||||
}
|
||||
}
|
||||
mRingtonePreferenceKey = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(Preference preference) {
|
||||
if (preference instanceof RingtonePreference) {
|
||||
RingtonePreference ringtonePreference = (RingtonePreference) preference;
|
||||
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, ringtonePreference.getRingtoneType());
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, ringtonePreference.isShowDefault());
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, ringtonePreference.isShowSilent());
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, Settings.System.DEFAULT_NOTIFICATION_URI);
|
||||
|
||||
String existingValue = ringtonePreference.getValue(); // TODO
|
||||
if (existingValue != null) {
|
||||
if (existingValue.length() == 0) {
|
||||
// Select "Silent"
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri) null);
|
||||
} else {
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Uri.parse(existingValue));
|
||||
}
|
||||
} else {
|
||||
// No ringtone has been selected, set to the default
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Settings.System.DEFAULT_NOTIFICATION_URI);
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_PICK_RINGTONE);
|
||||
mRingtonePreferenceKey = ringtonePreference.getKey();
|
||||
return true;
|
||||
}
|
||||
return super.onPreferenceTreeClick(preference);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
import org.mariotaku.twidere.util.support.WebSettingsSupport;
|
||||
import org.mariotaku.twidere.util.webkit.DefaultWebViewClient;
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
public class BaseSupportWebViewFragment extends BaseSupportFragment {
|
||||
|
||||
private WebView mWebView;
|
||||
private boolean mIsWebViewAvailable;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final WebView view = getWebView();
|
||||
view.setWebViewClient(createWebViewClient());
|
||||
final WebSettings settings = view.getSettings();
|
||||
settings.setBuiltInZoomControls(true);
|
||||
settings.setJavaScriptEnabled(true);
|
||||
WebSettingsSupport.setAllowUniversalAccessFromFileURLs(settings, true);
|
||||
}
|
||||
|
||||
|
||||
protected WebViewClient createWebViewClient() {
|
||||
return new DefaultWebViewClient(getActivity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to instantiate the view. Creates and returns the WebView.
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
if (mWebView != null) {
|
||||
mWebView.destroy();
|
||||
}
|
||||
mWebView = new WebView(getActivity());
|
||||
mIsWebViewAvailable = true;
|
||||
return mWebView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is visible to the user and actively running. Resumes the WebView.
|
||||
*/
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mWebView.onPause();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is no longer resumed. Pauses the WebView.
|
||||
*/
|
||||
@Override
|
||||
public void onResume() {
|
||||
mWebView.onResume();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the WebView has been detached from the fragment.
|
||||
* The WebView is no longer available after this time.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mIsWebViewAvailable = false;
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is no longer in use. Destroys the internal state of the WebView.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (mWebView != null) {
|
||||
mWebView.destroy();
|
||||
mWebView = null;
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the WebView.
|
||||
*/
|
||||
public WebView getWebView() {
|
||||
return mIsWebViewAvailable ? mWebView : null;
|
||||
}
|
||||
}
|
|
@ -79,6 +79,17 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_ARGUMENTS;
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_EXTRAS;
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_ICON;
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_ID;
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_NAME;
|
||||
import static org.mariotaku.twidere.Constants.EXTRA_TYPE;
|
||||
import static org.mariotaku.twidere.Constants.INTENT_ACTION_ADD_TAB;
|
||||
import static org.mariotaku.twidere.Constants.INTENT_ACTION_EDIT_TAB;
|
||||
import static org.mariotaku.twidere.Constants.REQUEST_ADD_TAB;
|
||||
import static org.mariotaku.twidere.Constants.REQUEST_EDIT_TAB;
|
||||
|
||||
public class CustomTabsFragment extends BaseSupportFragment implements LoaderCallbacks<Cursor>,
|
||||
MultiChoiceModeListener, OnItemClickListener {
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public class DestroySavedSearchDialogFragment extends BaseDialogFragment impleme
|
|||
final UserKey accountKey = getAccountKey();
|
||||
final long searchId = getSearchId();
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
if (searchId <= 0 || twitter == null) return;
|
||||
if (searchId <= 0) return;
|
||||
twitter.destroySavedSearchAsync(accountKey, searchId);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -41,7 +41,7 @@ public class DestroyStatusDialogFragment extends BaseDialogFragment implements D
|
|||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final ParcelableStatus status = getStatus();
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
if (status == null || twitter == null) return;
|
||||
if (status == null) return;
|
||||
twitter.destroyStatusAsync(status.account_key, status.id);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1,164 +0,0 @@
|
|||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.nfc.NdefMessage;
|
||||
import android.nfc.NdefRecord;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.NfcEvent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.microblog.library.MicroBlog;
|
||||
import org.mariotaku.microblog.library.MicroBlogException;
|
||||
import org.mariotaku.microblog.library.statusnet.model.Group;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter;
|
||||
import org.mariotaku.twidere.model.ParcelableGroup;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.util.ParcelableGroupUtils;
|
||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/23.
|
||||
*/
|
||||
public class GroupFragment extends AbsToolbarTabPagesFragment implements
|
||||
LoaderCallbacks<SingleResponse<ParcelableGroup>> {
|
||||
private ParcelableGroup mGroup;
|
||||
private boolean mGroupLoaderInitialized;
|
||||
|
||||
@Override
|
||||
protected void addTabs(SupportTabsAdapter adapter) {
|
||||
final Bundle args = getArguments();
|
||||
adapter.addTab(GroupTimelineFragment.class, args, getString(R.string.statuses), 0, 0, "statuses");
|
||||
adapter.addTab(GroupMembersFragment.class, args, getString(R.string.members), 0, 1, "members");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
Utils.setNdefPushMessageCallback(getActivity(), new NfcAdapter.CreateNdefMessageCallback() {
|
||||
|
||||
@Override
|
||||
public NdefMessage createNdefMessage(NfcEvent event) {
|
||||
final ParcelableGroup group = getGroup();
|
||||
if (group == null || group.url == null) return null;
|
||||
return new NdefMessage(new NdefRecord[]{
|
||||
NdefRecord.createUri(group.url),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
getGroupInfo(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<SingleResponse<ParcelableGroup>> onCreateLoader(int id, Bundle args) {
|
||||
final UserKey accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
final String groupId = args.getString(EXTRA_GROUP_ID);
|
||||
final String groupName = args.getString(EXTRA_GROUP_NAME);
|
||||
final boolean omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true);
|
||||
return new ParcelableGroupLoader(getContext(), omitIntentExtra, getArguments(), accountKey,
|
||||
groupId, groupName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<SingleResponse<ParcelableGroup>> loader, SingleResponse<ParcelableGroup> data) {
|
||||
if (data.hasData()) {
|
||||
displayGroup(data.getData());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<SingleResponse<ParcelableGroup>> loader) {
|
||||
|
||||
}
|
||||
|
||||
public void displayGroup(final ParcelableGroup group) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
getLoaderManager().destroyLoader(0);
|
||||
mGroup = group;
|
||||
|
||||
if (group != null) {
|
||||
activity.setTitle(group.fullname);
|
||||
} else {
|
||||
activity.setTitle(R.string.user_list);
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
|
||||
public void getGroupInfo(final boolean omitIntentExtra) {
|
||||
final LoaderManager lm = getLoaderManager();
|
||||
lm.destroyLoader(0);
|
||||
final Bundle args = new Bundle(getArguments());
|
||||
args.putBoolean(EXTRA_OMIT_INTENT_EXTRA, omitIntentExtra);
|
||||
if (!mGroupLoaderInitialized) {
|
||||
lm.initLoader(0, args, this);
|
||||
mGroupLoaderInitialized = true;
|
||||
} else {
|
||||
lm.restartLoader(0, args, this);
|
||||
}
|
||||
}
|
||||
|
||||
public ParcelableGroup getGroup() {
|
||||
return mGroup;
|
||||
}
|
||||
|
||||
static class ParcelableGroupLoader extends AsyncTaskLoader<SingleResponse<ParcelableGroup>> {
|
||||
|
||||
private final boolean mOmitIntentExtra;
|
||||
private final Bundle mExtras;
|
||||
private final UserKey mAccountKey;
|
||||
private final String mGroupId;
|
||||
private final String mGroupName;
|
||||
|
||||
private ParcelableGroupLoader(final Context context, final boolean omitIntentExtra,
|
||||
final Bundle extras, final UserKey accountKey,
|
||||
final String groupId, final String groupName) {
|
||||
super(context);
|
||||
mOmitIntentExtra = omitIntentExtra;
|
||||
mExtras = extras;
|
||||
mAccountKey = accountKey;
|
||||
mGroupId = groupId;
|
||||
mGroupName = groupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<ParcelableGroup> loadInBackground() {
|
||||
if (!mOmitIntentExtra && mExtras != null) {
|
||||
final ParcelableGroup cache = mExtras.getParcelable(EXTRA_GROUP);
|
||||
if (cache != null) return SingleResponse.Companion.getInstance(cache);
|
||||
}
|
||||
final MicroBlog twitter = MicroBlogAPIFactory.getInstance(getContext(), mAccountKey,
|
||||
true);
|
||||
if (twitter == null) return SingleResponse.Companion.getInstance();
|
||||
try {
|
||||
final Group group;
|
||||
if (mGroupId != null) {
|
||||
group = twitter.showGroup(mGroupId);
|
||||
} else if (mGroupName != null) {
|
||||
group = twitter.showGroupByName(mGroupName);
|
||||
} else {
|
||||
return SingleResponse.Companion.getInstance();
|
||||
}
|
||||
return SingleResponse.Companion.getInstance(ParcelableGroupUtils.from(group, mAccountKey, 0,
|
||||
group.isMember()));
|
||||
} catch (final MicroBlogException e) {
|
||||
return SingleResponse.Companion.getInstance(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartLoading() {
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
public class InvalidTabFragment extends BaseSupportFragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_invalid_tab, container, false);
|
||||
}
|
||||
|
||||
}
|
|
@ -91,7 +91,7 @@ public class KeyboardShortcutsFragment extends BasePreferenceFragment implements
|
|||
setTitle(KeyboardShortcutsHandler.getActionLabel(context, action));
|
||||
mPreferencesChangeListener = new OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
updateSummary();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -52,6 +52,10 @@ import java.net.UnknownHostException;
|
|||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.mariotaku.twidere.Constants.DEFAULT_TWITTER_API_URL_FORMAT;
|
||||
import static org.mariotaku.twidere.Constants.KEY_BUILTIN_DNS_RESOLVER;
|
||||
import static org.mariotaku.twidere.Constants.KEY_DNS_SERVER;
|
||||
import static org.mariotaku.twidere.Constants.KEY_TCP_DNS_QUERY;
|
||||
|
||||
/**
|
||||
* Network diagnostics
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchRecentSuggestions;
|
||||
import android.support.v4.view.ViewPager.OnPageChangeListener;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.ComposeActivity;
|
||||
import org.mariotaku.twidere.activity.LinkHandlerActivity;
|
||||
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener;
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter;
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback;
|
||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
|
||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.provider.RecentSearchProvider;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.SearchHistory;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
public class SearchFragment extends AbsToolbarTabPagesFragment implements RefreshScrollTopInterface,
|
||||
SupportFragmentCallback, SystemWindowsInsetsCallback, ControlBarOffsetListener,
|
||||
OnPageChangeListener, LinkHandlerActivity.HideUiOnScroll {
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
final String query = getQuery();
|
||||
if (savedInstanceState == null && !TextUtils.isEmpty(query)) {
|
||||
final SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getActivity(),
|
||||
RecentSearchProvider.AUTHORITY, RecentSearchProvider.MODE);
|
||||
suggestions.saveRecentQuery(query, null);
|
||||
final ContentResolver cr = getContentResolver();
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(SearchHistory.QUERY, query);
|
||||
cr.insert(SearchHistory.CONTENT_URI, values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_search, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
if (isDetached() || getActivity() == null) return;
|
||||
final MenuItem item = menu.findItem(R.id.compose);
|
||||
item.setTitle(getString(R.string.tweet_hashtag, getQuery()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
final String query = getQuery();
|
||||
switch (item.getItemId()) {
|
||||
case R.id.save: {
|
||||
final AsyncTwitterWrapper twitter = twitterWrapper;
|
||||
final Bundle args = getArguments();
|
||||
if (twitter != null && args != null) {
|
||||
twitter.createSavedSearchAsync(getAccountKey(), query);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case R.id.compose: {
|
||||
final Intent intent = new Intent(getActivity(), ComposeActivity.class);
|
||||
intent.setAction(INTENT_ACTION_COMPOSE);
|
||||
if (query.startsWith("@") || query.startsWith("\uff20")) {
|
||||
intent.putExtra(Intent.EXTRA_TEXT, query);
|
||||
} else {
|
||||
intent.putExtra(Intent.EXTRA_TEXT, String.format("#%s ", query));
|
||||
}
|
||||
intent.putExtra(EXTRA_ACCOUNT_KEY, getAccountKey());
|
||||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean triggerRefresh(final int position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public UserKey getAccountKey() {
|
||||
return getArguments().getParcelable(EXTRA_ACCOUNT_KEY);
|
||||
}
|
||||
|
||||
public String getQuery() {
|
||||
return getArguments().getString(EXTRA_QUERY);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void addTabs(SupportTabsAdapter adapter) {
|
||||
final Bundle args = getArguments();
|
||||
adapter.addTab(StatusesSearchFragment.class, args, getString(R.string.statuses), R.drawable.ic_action_twitter, 0, null);
|
||||
adapter.addTab(SearchUsersFragment.class, args, getString(R.string.users), R.drawable.ic_action_user, 1, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import org.mariotaku.twidere.activity.SettingsActivity;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
public class SettingsDetailsFragment extends BasePreferenceFragment implements
|
||||
OnSharedPreferenceChangeListener {
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
final PreferenceManager preferenceManager = getPreferenceManager();
|
||||
preferenceManager.setSharedPreferencesName(SHARED_PREFERENCES_NAME);
|
||||
final PreferenceScreen defaultScreen = getPreferenceScreen();
|
||||
final PreferenceScreen preferenceScreen;
|
||||
if (defaultScreen != null) {
|
||||
defaultScreen.removeAll();
|
||||
preferenceScreen = defaultScreen;
|
||||
} else {
|
||||
preferenceScreen = preferenceManager.createPreferenceScreen(getActivity());
|
||||
}
|
||||
setPreferenceScreen(preferenceScreen);
|
||||
|
||||
final Bundle args = getArguments();
|
||||
final Object rawResId = args.get(EXTRA_RESID);
|
||||
final int resId;
|
||||
if (rawResId instanceof Integer) {
|
||||
resId = (Integer) rawResId;
|
||||
} else if (rawResId instanceof String) {
|
||||
resId = Utils.getResId(getActivity(), (String) rawResId);
|
||||
} else {
|
||||
resId = 0;
|
||||
}
|
||||
if (resId != 0) {
|
||||
addPreferencesFromResource(resId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final SharedPreferences preferences = getPreferenceManager().getSharedPreferences();
|
||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
final SharedPreferences preferences = getPreferenceManager().getSharedPreferences();
|
||||
preferences.unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
final Preference preference = findPreference(key);
|
||||
if (preference == null) return;
|
||||
final Bundle extras = preference.getExtras();
|
||||
if (extras != null) {
|
||||
final Activity activity = getActivity();
|
||||
if (extras.containsKey(EXTRA_NOTIFY_CHANGE)) {
|
||||
SettingsActivity.setShouldNotifyChange(activity);
|
||||
}
|
||||
if (extras.containsKey(EXTRA_RESTART_ACTIVITY)) {
|
||||
activity.recreate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
|
||||
import static org.mariotaku.twidere.constant.IntentConstants.EXTRA_TAB_POSITION;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/7/4.
|
||||
*/
|
||||
public class StubFragment extends Fragment {
|
||||
private TextView mTextView;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mTextView.setText(String.valueOf(getArguments().get(EXTRA_TAB_POSITION)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mTextView = (TextView) view.findViewById(R.id.text);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_stub, container, false);
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.card;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import org.mariotaku.twidere.fragment.SupportBrowserFragment;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/6.
|
||||
*/
|
||||
public class CardBrowserFragment extends SupportBrowserFragment {
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final WebView view = getWebView();
|
||||
final WebSettings settings = view.getSettings();
|
||||
settings.setBuiltInZoomControls(false);
|
||||
}
|
||||
|
||||
public static CardBrowserFragment show(@NonNull String uri, @Nullable Bundle extraArgs) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putString(EXTRA_URI, uri);
|
||||
if (extraArgs != null) {
|
||||
args.putAll(extraArgs);
|
||||
}
|
||||
final CardBrowserFragment fragment = new CardBrowserFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
}
|
|
@ -1,373 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.card;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.mariotaku.abstask.library.AbstractTask;
|
||||
import org.mariotaku.abstask.library.TaskStarter;
|
||||
import org.mariotaku.microblog.library.MicroBlogException;
|
||||
import org.mariotaku.microblog.library.twitter.TwitterCaps;
|
||||
import org.mariotaku.microblog.library.twitter.model.CardDataMap;
|
||||
import org.mariotaku.microblog.library.twitter.model.CardEntity;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.fragment.BaseSupportFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils;
|
||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
|
||||
import org.mariotaku.twidere.util.support.ViewSupport;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/12/20.
|
||||
*/
|
||||
public class CardPollFragment extends BaseSupportFragment implements
|
||||
LoaderManager.LoaderCallbacks<ParcelableCardEntity>, View.OnClickListener {
|
||||
|
||||
public static final Pattern PATTERN_POLL_TEXT_ONLY = Pattern.compile("poll([\\d]+)choice_text_only");
|
||||
private TableLayout mPollContainer;
|
||||
private TextView mPollSummary;
|
||||
private ParcelableCardEntity mCard;
|
||||
|
||||
|
||||
public static CardPollFragment show(ParcelableStatus status) {
|
||||
final CardPollFragment fragment = new CardPollFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(EXTRA_STATUS, status);
|
||||
args.putParcelable(EXTRA_CARD, status.card);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static boolean isPoll(@NonNull ParcelableCardEntity card) {
|
||||
return PATTERN_POLL_TEXT_ONLY.matcher(card.name).matches() && !TextUtils.isEmpty(card.url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
initChoiceView(savedInstanceState);
|
||||
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mPollContainer = (TableLayout) view.findViewById(R.id.poll_container);
|
||||
mPollSummary = (TextView) view.findViewById(R.id.poll_summary);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_card_poll, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fitSystemWindows(Rect insets) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
|
||||
private void initChoiceView(@Nullable Bundle savedInstanceState) {
|
||||
final ParcelableCardEntity card = getCard();
|
||||
final ParcelableStatus status = getStatus();
|
||||
final int choicesCount = getChoicesCount(card);
|
||||
final LayoutInflater inflater = getLayoutInflater(savedInstanceState);
|
||||
|
||||
for (int i = 0; i < choicesCount; i++) {
|
||||
inflater.inflate(R.layout.layout_poll_item, mPollContainer, true);
|
||||
}
|
||||
|
||||
displayPoll(card, status);
|
||||
}
|
||||
|
||||
private void displayPoll(final ParcelableCardEntity card, final ParcelableStatus status) {
|
||||
final Context context = getContext();
|
||||
if (card == null || status == null || context == null) return;
|
||||
mCard = card;
|
||||
final int choicesCount = getChoicesCount(card);
|
||||
int votesSum = 0;
|
||||
final boolean countsAreFinal = ParcelableCardEntityUtils.getAsBoolean(card, "counts_are_final", false);
|
||||
final int selectedChoice = ParcelableCardEntityUtils.getAsInteger(card, "selected_choice", -1);
|
||||
final Date endDatetimeUtc = ParcelableCardEntityUtils.getAsDate(card, "end_datetime_utc", new Date());
|
||||
final boolean hasChoice = selectedChoice != -1;
|
||||
final boolean isMyPoll = status.account_key.equals(status.user_key);
|
||||
final boolean showResult = countsAreFinal || isMyPoll || hasChoice;
|
||||
for (int i = 0; i < choicesCount; i++) {
|
||||
final int choiceIndex = i + 1;
|
||||
votesSum += ParcelableCardEntityUtils.getAsInteger(card, "choice" + choiceIndex + "_count", 0);
|
||||
}
|
||||
|
||||
final View.OnClickListener clickListener = new View.OnClickListener() {
|
||||
private boolean clickedChoice;
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (hasChoice || clickedChoice) return;
|
||||
for (int i = 0, j = mPollContainer.getChildCount(); i < j; i++) {
|
||||
final View pollItem = mPollContainer.getChildAt(i);
|
||||
pollItem.setClickable(false);
|
||||
clickedChoice = true;
|
||||
final RadioButton choiceRadioButton = (RadioButton) pollItem.findViewById(R.id.choice_button);
|
||||
final boolean checked = v == pollItem;
|
||||
choiceRadioButton.setChecked(checked);
|
||||
if (checked) {
|
||||
final CardDataMap cardData = new CardDataMap();
|
||||
cardData.putLong("original_tweet_id", NumberUtils.toLong(status.id));
|
||||
cardData.putString("card_uri", card.url);
|
||||
cardData.putString("cards_platform", MicroBlogAPIFactory.CARDS_PLATFORM_ANDROID_12);
|
||||
cardData.putString("response_card_name", card.name);
|
||||
cardData.putString("selected_choice", String.valueOf(i + 1));
|
||||
AbstractTask<CardDataMap, ParcelableCardEntity, CardPollFragment> task
|
||||
= new AbstractTask<CardDataMap, ParcelableCardEntity, CardPollFragment>() {
|
||||
|
||||
@Override
|
||||
public void afterExecute(CardPollFragment handler, ParcelableCardEntity result) {
|
||||
handler.displayAndReloadPoll(result, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableCardEntity doLongOperation(CardDataMap cardDataMap) {
|
||||
final Context context = getContext();
|
||||
if (context == null) return null;
|
||||
final TwitterCaps caps = MicroBlogAPIFactory.getInstance(context,
|
||||
card.account_key, true, true, TwitterCaps.class);
|
||||
if (caps == null) return null;
|
||||
try {
|
||||
final CardEntity cardEntity = caps.sendPassThrough(cardDataMap).getCard();
|
||||
return ParcelableCardEntityUtils.fromCardEntity(cardEntity,
|
||||
card.account_key);
|
||||
} catch (MicroBlogException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
task.setCallback(CardPollFragment.this);
|
||||
task.setParams(cardData);
|
||||
TaskStarter.execute(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final int color = ContextCompat.getColor(context, R.color.material_light_blue_a200);
|
||||
final float radius = getResources().getDimension(R.dimen.element_spacing_small);
|
||||
for (int i = 0; i < choicesCount; i++) {
|
||||
final View pollItem = mPollContainer.getChildAt(i);
|
||||
|
||||
final TextView choicePercentView = (TextView) pollItem.findViewById(R.id.choice_percent);
|
||||
final TextView choiceLabelView = (TextView) pollItem.findViewById(R.id.choice_label);
|
||||
final RadioButton choiceRadioButton = (RadioButton) pollItem.findViewById(R.id.choice_button);
|
||||
|
||||
final int choiceIndex = i + 1;
|
||||
final String label = ParcelableCardEntityUtils.getAsString(card, "choice" + choiceIndex + "_label", null);
|
||||
final int value = ParcelableCardEntityUtils.getAsInteger(card, "choice" + choiceIndex + "_count", 0);
|
||||
if (label == null) throw new NullPointerException();
|
||||
final float choicePercent = votesSum == 0 ? 0 : value / (float) votesSum;
|
||||
choiceLabelView.setText(label);
|
||||
choicePercentView.setText(String.format(Locale.US, "%d%%", Math.round(choicePercent * 100)));
|
||||
|
||||
pollItem.setOnClickListener(clickListener);
|
||||
|
||||
final boolean isSelected = selectedChoice == choiceIndex;
|
||||
|
||||
if (showResult) {
|
||||
choicePercentView.setVisibility(View.VISIBLE);
|
||||
choiceRadioButton.setVisibility(hasChoice && isSelected ? View.VISIBLE : View.INVISIBLE);
|
||||
ViewSupport.setBackground(choiceLabelView, new PercentDrawable(choicePercent, radius, color));
|
||||
} else {
|
||||
choicePercentView.setVisibility(View.GONE);
|
||||
choiceRadioButton.setVisibility(View.VISIBLE);
|
||||
ViewSupport.setBackground(choiceLabelView, null);
|
||||
}
|
||||
|
||||
choiceRadioButton.setChecked(isSelected);
|
||||
pollItem.setClickable(selectedChoice == -1);
|
||||
|
||||
}
|
||||
|
||||
final String nVotes = getResources().getQuantityString(R.plurals.N_votes, votesSum, votesSum);
|
||||
|
||||
final CharSequence timeLeft = DateUtils.getRelativeTimeSpanString(context,
|
||||
endDatetimeUtc.getTime(), true);
|
||||
mPollSummary.setText(getString(R.string.poll_summary_format, nVotes, timeLeft));
|
||||
}
|
||||
|
||||
private void displayAndReloadPoll(ParcelableCardEntity result, ParcelableStatus status) {
|
||||
if (getHost() == null) return;
|
||||
displayPoll(result, status);
|
||||
getLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
private int getChoicesCount(ParcelableCardEntity card) {
|
||||
final Matcher matcher = PATTERN_POLL_TEXT_ONLY.matcher(card.name);
|
||||
if (!matcher.matches()) throw new IllegalStateException();
|
||||
return NumberUtils.toInt(matcher.group(1));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ParcelableCardEntity getCard() {
|
||||
if (mCard != null) return mCard;
|
||||
final ParcelableCardEntity card = getArguments().getParcelable(EXTRA_CARD);
|
||||
assert card != null && card.name != null;
|
||||
return card;
|
||||
}
|
||||
|
||||
private ParcelableStatus getStatus() {
|
||||
return getArguments().getParcelable(EXTRA_STATUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<ParcelableCardEntity> onCreateLoader(int id, Bundle args) {
|
||||
final ParcelableCardEntity card = getCard();
|
||||
return new ParcelableCardEntityLoader(getContext(), card.account_key, card.url, card.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<ParcelableCardEntity> loader, ParcelableCardEntity data) {
|
||||
if (data == null) return;
|
||||
displayPoll(data, getStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<ParcelableCardEntity> loader) {
|
||||
|
||||
}
|
||||
|
||||
private static class PercentDrawable extends Drawable {
|
||||
|
||||
private final Paint mPaint;
|
||||
private final RectF mBounds;
|
||||
private final float mPercent;
|
||||
private final float mRadius;
|
||||
|
||||
PercentDrawable(float percent, float radius, int color) {
|
||||
mPercent = percent;
|
||||
mRadius = radius;
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaint.setColor(color);
|
||||
mBounds = new RectF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
canvas.drawRoundRect(mBounds, mRadius, mRadius, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
mBounds.set(bounds);
|
||||
mBounds.right = mBounds.left + mBounds.width() * mPercent;
|
||||
super.onBoundsChange(bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter colorFilter) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ParcelableCardEntityLoader extends AsyncTaskLoader<ParcelableCardEntity> {
|
||||
private final UserKey mAccountKey;
|
||||
private final String mCardUri;
|
||||
private final String mCardName;
|
||||
|
||||
public ParcelableCardEntityLoader(Context context, UserKey accountKey,
|
||||
String cardUri, String cardName) {
|
||||
super(context);
|
||||
mAccountKey = accountKey;
|
||||
mCardUri = cardUri;
|
||||
mCardName = cardName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableCardEntity loadInBackground() {
|
||||
final TwitterCaps caps = MicroBlogAPIFactory.getInstance(getContext(), mAccountKey,
|
||||
true, true, TwitterCaps.class);
|
||||
if (caps == null) return null;
|
||||
try {
|
||||
final CardDataMap params = new CardDataMap();
|
||||
params.putString("card_uri", mCardUri);
|
||||
params.putString("cards_platform", MicroBlogAPIFactory.CARDS_PLATFORM_ANDROID_12);
|
||||
params.putString("response_card_name", mCardName);
|
||||
final CardEntity card = caps.getPassThrough(params).getCard();
|
||||
if (card == null || card.getName() == null) {
|
||||
return null;
|
||||
}
|
||||
return ParcelableCardEntityUtils.fromCardEntity(card, mAccountKey);
|
||||
} catch (MicroBlogException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
forceLoad();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public interface IBaseFragment {
|
||||
Bundle getExtraConfiguration();
|
||||
|
||||
int getTabPosition();
|
||||
|
||||
void requestFitSystemWindows();
|
||||
|
||||
interface SystemWindowsInsetsCallback {
|
||||
boolean getSystemWindowsInsets(Rect insets);
|
||||
}
|
||||
|
||||
void executeAfterFragmentResumed(Action action);
|
||||
|
||||
interface Action {
|
||||
void execute(IBaseFragment fragment);
|
||||
}
|
||||
|
||||
class ActionHelper {
|
||||
|
||||
private final IBaseFragment mFragment;
|
||||
|
||||
private boolean mFragmentResumed;
|
||||
private Queue<Action> mActionQueue = new LinkedList<>();
|
||||
|
||||
public ActionHelper(IBaseFragment fragment) {
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
public void dispatchOnPause() {
|
||||
mFragmentResumed = false;
|
||||
}
|
||||
|
||||
public void dispatchOnResumeFragments() {
|
||||
mFragmentResumed = true;
|
||||
executePending();
|
||||
}
|
||||
|
||||
|
||||
private void executePending() {
|
||||
if (!mFragmentResumed) return;
|
||||
Action action;
|
||||
while ((action = mActionQueue.poll()) != null) {
|
||||
action.execute(mFragment);
|
||||
}
|
||||
}
|
||||
|
||||
public void executeAfterFragmentResumed(Action action) {
|
||||
mActionQueue.add(action);
|
||||
executePending();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import java.util.*
|
||||
|
||||
interface IBaseFragment {
|
||||
val extraConfiguration: Bundle?
|
||||
|
||||
val tabPosition: Int
|
||||
|
||||
fun requestFitSystemWindows()
|
||||
|
||||
interface SystemWindowsInsetsCallback {
|
||||
fun getSystemWindowsInsets(insets: Rect): Boolean
|
||||
}
|
||||
|
||||
fun executeAfterFragmentResumed(action: (IBaseFragment) -> Unit)
|
||||
|
||||
class ActionHelper(private val fragment: IBaseFragment) {
|
||||
|
||||
private var fragmentResumed: Boolean = false
|
||||
private val actionQueue = LinkedList<(IBaseFragment) -> Unit>()
|
||||
|
||||
fun dispatchOnPause() {
|
||||
fragmentResumed = false
|
||||
}
|
||||
|
||||
fun dispatchOnResumeFragments() {
|
||||
fragmentResumed = true
|
||||
executePending()
|
||||
}
|
||||
|
||||
|
||||
private fun executePending() {
|
||||
if (!fragmentResumed) return
|
||||
var action: ((IBaseFragment) -> Unit)?
|
||||
do {
|
||||
action = actionQueue.poll()
|
||||
action?.invoke(fragment)
|
||||
} while (action != null)
|
||||
}
|
||||
|
||||
fun executeAfterFragmentResumed(action: (IBaseFragment) -> Unit) {
|
||||
actionQueue.add(action)
|
||||
executePending()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,12 +17,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface;
|
||||
package org.mariotaku.twidere.fragment.iface
|
||||
|
||||
public interface IDialogFragmentCallback {
|
||||
interface IDialogFragmentCallback {
|
||||
|
||||
void onCancelled();
|
||||
fun onCancelled()
|
||||
|
||||
void onDismissed();
|
||||
fun onDismissed()
|
||||
|
||||
}
|
|
@ -17,10 +17,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface;
|
||||
package org.mariotaku.twidere.fragment.iface
|
||||
|
||||
public interface IMapFragment {
|
||||
interface IMapFragment {
|
||||
|
||||
void center();
|
||||
fun center()
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface;
|
||||
|
||||
import android.support.v4.app.DialogFragment;
|
||||
|
||||
public interface ISupportDialogFragmentCallback {
|
||||
|
||||
void onCancelled(DialogFragment df);
|
||||
|
||||
void onDismissed(DialogFragment df);
|
||||
|
||||
}
|
|
@ -17,13 +17,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface;
|
||||
package org.mariotaku.twidere.fragment.iface
|
||||
|
||||
public interface IBasePullToRefreshFragment {
|
||||
import android.support.v4.app.DialogFragment
|
||||
|
||||
void onRefresh();
|
||||
interface ISupportDialogFragmentCallback {
|
||||
|
||||
boolean isRefreshing();
|
||||
fun onCancelled(df: DialogFragment)
|
||||
|
||||
fun onDismissed(df: DialogFragment)
|
||||
|
||||
void setRefreshing(boolean refresh);
|
||||
}
|
|
@ -17,12 +17,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface;
|
||||
package org.mariotaku.twidere.fragment.iface
|
||||
|
||||
public interface RefreshScrollTopInterface {
|
||||
interface RefreshScrollTopInterface {
|
||||
|
||||
boolean scrollToStart();
|
||||
fun scrollToStart(): Boolean
|
||||
|
||||
boolean triggerRefresh();
|
||||
fun triggerRefresh(): Boolean
|
||||
|
||||
}
|
|
@ -17,14 +17,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment.iface;
|
||||
package org.mariotaku.twidere.fragment.iface
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.Fragment
|
||||
|
||||
public interface SupportFragmentCallback {
|
||||
interface SupportFragmentCallback {
|
||||
|
||||
Fragment getCurrentVisibleFragment();
|
||||
val currentVisibleFragment: Fragment?
|
||||
|
||||
boolean triggerRefresh(int position);
|
||||
fun triggerRefresh(position: Int): Boolean
|
||||
|
||||
}
|
|
@ -143,7 +143,7 @@ public abstract class AccountsListPreference extends PreferenceCategory implemen
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class KeyboardShortcutPreference extends DialogPreference implements IDia
|
|||
setTitle(KeyboardShortcutsHandler.getActionLabel(context, mAction));
|
||||
mPreferencesChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
updateSummary();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -610,7 +610,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
updatePreferences();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,18 +17,21 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.content.Context
|
||||
import android.support.v4.app.Fragment
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/4/27.
|
||||
*/
|
||||
public abstract class MapFragmentFactory {
|
||||
abstract class MapFragmentFactory {
|
||||
|
||||
public static final MapFragmentFactory SINGLETON = new MapFragmentFactoryImpl();
|
||||
abstract fun createMapFragment(context: Context): Fragment?
|
||||
|
||||
public abstract Fragment createMapFragment(Context context);
|
||||
companion object {
|
||||
|
||||
fun getInstance(): MapFragmentFactory = MapFragmentFactoryImpl()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import org.mariotaku.twidere.fragment.card.CardBrowserFragment;
|
||||
import org.mariotaku.twidere.fragment.card.CardPollFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/1.
|
||||
*/
|
||||
public abstract class TwitterCardFragmentFactory {
|
||||
|
||||
public abstract Fragment createAnimatedGifFragment(ParcelableCardEntity card);
|
||||
|
||||
public abstract Fragment createAudioFragment(ParcelableCardEntity card);
|
||||
|
||||
public abstract Fragment createPlayerFragment(ParcelableCardEntity card);
|
||||
|
||||
public static TwitterCardFragmentFactory getInstance() {
|
||||
return new TwitterCardFragmentFactoryImpl();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Fragment createGenericPlayerFragment(@Nullable ParcelableCardEntity card, Bundle args) {
|
||||
if (card == null) return null;
|
||||
final String playerUrl = ParcelableCardEntityUtils.getString(card, "player_url");
|
||||
if (playerUrl == null) return null;
|
||||
return CardBrowserFragment.show(playerUrl, args);
|
||||
}
|
||||
|
||||
public static Fragment createCardPollFragment(ParcelableStatus status) {
|
||||
return CardPollFragment.show(status);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
|
||||
import org.mariotaku.twidere.fragment.card.CardBrowserFragment
|
||||
import org.mariotaku.twidere.fragment.card.CardPollFragment
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/1.
|
||||
*/
|
||||
abstract class TwitterCardFragmentFactory {
|
||||
|
||||
abstract fun createAnimatedGifFragment(card: ParcelableCardEntity): Fragment?
|
||||
|
||||
abstract fun createAudioFragment(card: ParcelableCardEntity): Fragment?
|
||||
|
||||
abstract fun createPlayerFragment(card: ParcelableCardEntity): Fragment?
|
||||
|
||||
companion object {
|
||||
|
||||
val instance: TwitterCardFragmentFactory
|
||||
get() = TwitterCardFragmentFactoryImpl()
|
||||
|
||||
fun createGenericPlayerFragment(card: ParcelableCardEntity?, args: Bundle?): Fragment? {
|
||||
if (card == null) return null
|
||||
val playerUrl = ParcelableCardEntityUtils.getString(card, "player_url") ?: return null
|
||||
return CardBrowserFragment.show(playerUrl, args)
|
||||
}
|
||||
|
||||
fun createCardPollFragment(status: ParcelableStatus): Fragment {
|
||||
return CardPollFragment.show(status)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.twidere.fragment.card.CardPollFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/1.
|
||||
*/
|
||||
public class TwitterCardUtils {
|
||||
|
||||
private static final TwitterCardFragmentFactory sFactory = TwitterCardFragmentFactory.getInstance();
|
||||
|
||||
public static final String CARD_NAME_PLAYER = "player";
|
||||
public static final String CARD_NAME_AUDIO = "audio";
|
||||
public static final String CARD_NAME_ANIMATED_GIF = "animated_gif";
|
||||
|
||||
private TwitterCardUtils() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Fragment createCardFragment(ParcelableStatus status) {
|
||||
final ParcelableCardEntity card = status.card;
|
||||
if (card == null || card.name == null) return null;
|
||||
if (CARD_NAME_PLAYER.equals(card.name)) {
|
||||
final Fragment playerFragment = sFactory.createPlayerFragment(card);
|
||||
if (playerFragment != null) return playerFragment;
|
||||
return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null);
|
||||
} else if (CARD_NAME_AUDIO.equals(card.name)) {
|
||||
final Fragment playerFragment = sFactory.createAudioFragment(card);
|
||||
if (playerFragment != null) return playerFragment;
|
||||
return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null);
|
||||
} else if (CARD_NAME_ANIMATED_GIF.equals(card.name)) {
|
||||
final Fragment playerFragment = sFactory.createAnimatedGifFragment(card);
|
||||
if (playerFragment != null) return playerFragment;
|
||||
return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null);
|
||||
} else if (CardPollFragment.isPoll(card)) {
|
||||
return TwitterCardFragmentFactory.createCardPollFragment(status);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Point getCardSize(ParcelableCardEntity card) {
|
||||
final int playerWidth = ParcelableCardEntityUtils.getAsInteger(card, "player_width", -1);
|
||||
final int playerHeight = ParcelableCardEntityUtils.getAsInteger(card, "player_height", -1);
|
||||
if (playerWidth > 0 && playerHeight > 0) {
|
||||
return new Point(playerWidth, playerHeight);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isCardSupported(ParcelableStatus status) {
|
||||
if (status.card == null || status.card_name == null) return false;
|
||||
switch (status.card_name) {
|
||||
case CARD_NAME_PLAYER: {
|
||||
if (!ArrayUtils.isEmpty(status.media)) {
|
||||
String appUrlResolved = ParcelableCardEntityUtils.getString(status.card, "app_url_resolved");
|
||||
String cardUrl = status.card.url;
|
||||
for (ParcelableMedia media : status.media) {
|
||||
if (media.url.equals(appUrlResolved) || media.url.equals(cardUrl)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TextUtils.isEmpty(ParcelableCardEntityUtils.getString(status.card, "player_stream_url"));
|
||||
}
|
||||
case CARD_NAME_AUDIO: {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (CardPollFragment.isPoll(status.card)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isPoll(ParcelableStatus status) {
|
||||
if (status.card_name == null || status.card == null) return false;
|
||||
return CardPollFragment.isPoll(status.card);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.graphics.Point
|
||||
import android.support.v4.app.Fragment
|
||||
import android.text.TextUtils
|
||||
import org.apache.commons.lang3.ArrayUtils
|
||||
import org.mariotaku.twidere.fragment.card.CardPollFragment
|
||||
import org.mariotaku.twidere.model.ParcelableCardEntity
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/1.
|
||||
*/
|
||||
object TwitterCardUtils {
|
||||
|
||||
private val sFactory = TwitterCardFragmentFactory.instance
|
||||
|
||||
val CARD_NAME_PLAYER = "player"
|
||||
val CARD_NAME_AUDIO = "audio"
|
||||
val CARD_NAME_ANIMATED_GIF = "animated_gif"
|
||||
|
||||
fun createCardFragment(status: ParcelableStatus): Fragment? {
|
||||
val card = status.card
|
||||
if (card == null || card.name == null) return null
|
||||
if (CARD_NAME_PLAYER == card.name) {
|
||||
val playerFragment = sFactory.createPlayerFragment(card)
|
||||
if (playerFragment != null) return playerFragment
|
||||
return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null)
|
||||
} else if (CARD_NAME_AUDIO == card.name) {
|
||||
val playerFragment = sFactory.createAudioFragment(card)
|
||||
if (playerFragment != null) return playerFragment
|
||||
return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null)
|
||||
} else if (CARD_NAME_ANIMATED_GIF == card.name) {
|
||||
val playerFragment = sFactory.createAnimatedGifFragment(card)
|
||||
if (playerFragment != null) return playerFragment
|
||||
return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null)
|
||||
} else if (CardPollFragment.isPoll(card)) {
|
||||
return TwitterCardFragmentFactory.createCardPollFragment(status)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
fun getCardSize(card: ParcelableCardEntity): Point? {
|
||||
val playerWidth = ParcelableCardEntityUtils.getAsInteger(card, "player_width", -1)
|
||||
val playerHeight = ParcelableCardEntityUtils.getAsInteger(card, "player_height", -1)
|
||||
if (playerWidth > 0 && playerHeight > 0) {
|
||||
return Point(playerWidth, playerHeight)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun isCardSupported(status: ParcelableStatus): Boolean {
|
||||
val card = status.card ?: return false
|
||||
when (status.card_name) {
|
||||
CARD_NAME_PLAYER -> {
|
||||
if (!ArrayUtils.isEmpty(status.media)) {
|
||||
val appUrlResolved = ParcelableCardEntityUtils.getString(card, "app_url_resolved")
|
||||
val cardUrl = card.url
|
||||
for (media in status.media) {
|
||||
if (media.url == appUrlResolved || media.url == cardUrl) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return TextUtils.isEmpty(ParcelableCardEntityUtils.getString(card, "player_stream_url"))
|
||||
}
|
||||
CARD_NAME_AUDIO -> {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (CardPollFragment.isPoll(card)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isPoll(status: ParcelableStatus): Boolean {
|
||||
val card = status.card ?: return false
|
||||
return CardPollFragment.isPoll(card)
|
||||
}
|
||||
}
|
|
@ -256,10 +256,10 @@ public class UserColorNameManager implements TwidereConstants {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
final UserKey userId = UserKey.valueOf(key);
|
||||
if (mListener != null && userId != null) {
|
||||
mListener.onUserColorChanged(userId, sharedPreferences.getInt(key, 0));
|
||||
mListener.onUserColorChanged(userId, preferences.getInt(key, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,10 +274,10 @@ public class UserColorNameManager implements TwidereConstants {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
|
||||
final UserKey userId = UserKey.valueOf(key);
|
||||
if (mListener != null && userId != null) {
|
||||
mListener.onUserNicknameChanged(userId, sharedPreferences.getString(key, null));
|
||||
mListener.onUserNicknameChanged(userId, preferences.getString(key, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -480,7 +480,7 @@ public final class Utils implements Constants {
|
|||
args.putDouble(EXTRA_LATITUDE, lat);
|
||||
args.putDouble(EXTRA_LONGITUDE, lng);
|
||||
}
|
||||
fragment = MapFragmentFactory.SINGLETON.createMapFragment(context);
|
||||
fragment = MapFragmentFactory.Companion.getInstance().createMapFragment(context);
|
||||
break;
|
||||
}
|
||||
case LINK_ID_STATUS: {
|
||||
|
|
|
@ -437,6 +437,9 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
|||
replyButton.setOnClickListener(eventListener)
|
||||
retweetButton.setOnClickListener(eventListener)
|
||||
favoriteButton.setOnClickListener(eventListener)
|
||||
|
||||
mediaLabel.setOnClickListener(eventListener)
|
||||
quotedMediaLabel.setOnClickListener(eventListener)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -140,11 +140,12 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
|||
return DataStoreUtils.getActivatedAccountKeys(this)
|
||||
}
|
||||
|
||||
override fun getCurrentVisibleFragment(): Fragment? {
|
||||
val currentItem = mainPager!!.currentItem
|
||||
if (currentItem < 0 || currentItem >= pagerAdapter!!.count) return null
|
||||
return pagerAdapter!!.instantiateItem(mainPager, currentItem) as Fragment
|
||||
}
|
||||
override val currentVisibleFragment: Fragment?
|
||||
get() {
|
||||
val currentItem = mainPager!!.currentItem
|
||||
if (currentItem < 0 || currentItem >= pagerAdapter!!.count) return null
|
||||
return pagerAdapter!!.instantiateItem(mainPager, currentItem) as Fragment
|
||||
}
|
||||
|
||||
override fun triggerRefresh(position: Int): Boolean {
|
||||
val f = pagerAdapter!!.instantiateItem(mainPager, position) as Fragment
|
||||
|
|
|
@ -61,9 +61,10 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
|
|||
private var mHideOffsetNotSupported: Boolean = false
|
||||
|
||||
|
||||
override fun getCurrentVisibleFragment(): Fragment {
|
||||
return supportFragmentManager.findFragmentById(android.R.id.content)
|
||||
}
|
||||
override val currentVisibleFragment: Fragment?
|
||||
get() {
|
||||
return supportFragmentManager.findFragmentById(android.R.id.content)
|
||||
}
|
||||
|
||||
override fun triggerRefresh(position: Int): Boolean {
|
||||
return false
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.os.Bundle
|
|||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.content.CursorLoader
|
||||
import android.support.v4.content.Loader
|
||||
import android.support.v4.widget.CursorAdapter
|
||||
import android.text.Editable
|
||||
import android.text.TextUtils
|
||||
import android.text.TextWatcher
|
||||
|
@ -58,32 +59,32 @@ import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener
|
|||
/**
|
||||
* Created by mariotaku on 15/1/6.
|
||||
*/
|
||||
class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<Cursor>,
|
||||
class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<Cursor?>,
|
||||
OnItemSelectedListener, OnItemClickListener, OnFitSystemWindowsListener,
|
||||
SwipeDismissListViewTouchListener.DismissCallbacks {
|
||||
|
||||
private var usersSearchAdapter: SuggestionsAdapter? = null
|
||||
private val mSystemWindowsInsets = Rect()
|
||||
private var textChanged: Boolean = false
|
||||
|
||||
override fun canDismiss(position: Int): Boolean {
|
||||
return usersSearchAdapter!!.getItemViewType(position) == SuggestionsAdapter.VIEW_TYPE_SEARCH_HISTORY
|
||||
val adapter = suggestionsList.adapter as SuggestionsAdapter
|
||||
return adapter.getItemViewType(position) == SuggestionsAdapter.VIEW_TYPE_SEARCH_HISTORY
|
||||
}
|
||||
|
||||
override fun onDismiss(listView: ListView, reverseSortedPositions: IntArray) {
|
||||
val adapter = suggestionsList.adapter as SuggestionsAdapter
|
||||
val ids = LongArray(reverseSortedPositions.size)
|
||||
var i = 0
|
||||
val j = reverseSortedPositions.size
|
||||
while (i < j) {
|
||||
val position = reverseSortedPositions[i]
|
||||
val item = usersSearchAdapter!!.getSuggestionItem(position) ?: return
|
||||
val item = adapter.getSuggestionItem(position) ?: return
|
||||
ids[i] = item._id
|
||||
i++
|
||||
}
|
||||
usersSearchAdapter!!.addRemovedPositions(reverseSortedPositions)
|
||||
val cr = contentResolver
|
||||
ContentResolverUtils.bulkDelete(cr, SearchHistory.CONTENT_URI, SearchHistory._ID, ids,
|
||||
null)
|
||||
adapter.addRemovedPositions(reverseSortedPositions)
|
||||
ContentResolverUtils.bulkDelete(contentResolver, SearchHistory.CONTENT_URI,
|
||||
SearchHistory._ID, ids, null)
|
||||
supportLoaderManager.restartLoader(0, null, this)
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<Cursor> {
|
||||
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor?> {
|
||||
val accountId = selectedAccountKey
|
||||
val builder = Suggestions.Search.CONTENT_URI.buildUpon()
|
||||
builder.appendQueryParameter(QUERY_PARAM_QUERY, ParseUtils.parseString(searchQuery.text))
|
||||
|
@ -105,12 +106,14 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
return CursorLoader(this, builder.build(), Suggestions.Search.COLUMNS, null, null, null)
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<Cursor>, data: Cursor) {
|
||||
usersSearchAdapter!!.changeCursor(data)
|
||||
override fun onLoadFinished(loader: Loader<Cursor?>, data: Cursor?) {
|
||||
val adapter = suggestionsList.adapter as SuggestionsAdapter
|
||||
adapter.changeCursor(data)
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<Cursor>) {
|
||||
usersSearchAdapter!!.changeCursor(null)
|
||||
override fun onLoaderReset(loader: Loader<Cursor?>) {
|
||||
val adapter = suggestionsList.adapter as SuggestionsAdapter
|
||||
adapter.changeCursor(null)
|
||||
}
|
||||
|
||||
override fun onFitSystemWindows(insets: Rect) {
|
||||
|
@ -119,8 +122,9 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
}
|
||||
|
||||
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
|
||||
val item = usersSearchAdapter!!.getSuggestionItem(position)
|
||||
when (usersSearchAdapter!!.getItemViewType(position)) {
|
||||
val adapter = (suggestionsList.adapter ?: return) as SuggestionsAdapter
|
||||
val item = adapter.getSuggestionItem(position)
|
||||
when (adapter.getItemViewType(position)) {
|
||||
SuggestionsAdapter.VIEW_TYPE_USER_SUGGESTION_ITEM -> {
|
||||
IntentUtils.openUserProfile(this, selectedAccountKey,
|
||||
UserKey.valueOf(item!!.extra_id), item.summary, null,
|
||||
|
@ -182,8 +186,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
}
|
||||
}
|
||||
mainContent.setOnFitSystemWindowsListener(this)
|
||||
usersSearchAdapter = SuggestionsAdapter(this)
|
||||
suggestionsList.adapter = usersSearchAdapter
|
||||
suggestionsList.adapter = SuggestionsAdapter(this)
|
||||
suggestionsList.onItemClickListener = this
|
||||
|
||||
val listener = SwipeDismissListViewTouchListener(suggestionsList, this)
|
||||
|
@ -268,20 +271,22 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
}
|
||||
}
|
||||
|
||||
class SuggestionsAdapter internal constructor(private val mActivity: QuickSearchBarActivity) : CursorAdapter(mActivity, null, 0), OnClickListener {
|
||||
class SuggestionsAdapter internal constructor(
|
||||
private val activity: QuickSearchBarActivity
|
||||
) : CursorAdapter(activity, null, 0), OnClickListener {
|
||||
|
||||
private val mInflater: LayoutInflater
|
||||
private val mMediaLoader: MediaLoaderWrapper
|
||||
private val mUserColorNameManager: UserColorNameManager
|
||||
private val mRemovedPositions: SortableIntList?
|
||||
private val removedPositions: SortableIntList?
|
||||
|
||||
private var mIndices: Indices? = null
|
||||
private var indices: Indices? = null
|
||||
|
||||
init {
|
||||
mRemovedPositions = SortableIntList()
|
||||
mMediaLoader = mActivity.mediaLoader
|
||||
mUserColorNameManager = mActivity.userColorNameManager
|
||||
mInflater = LayoutInflater.from(mActivity)
|
||||
removedPositions = SortableIntList()
|
||||
mMediaLoader = activity.mediaLoader
|
||||
mUserColorNameManager = activity.userColorNameManager
|
||||
mInflater = LayoutInflater.from(activity)
|
||||
}
|
||||
|
||||
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
|
||||
|
@ -304,40 +309,40 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
|
||||
internal fun getSuggestionItem(position: Int): SuggestionItem? {
|
||||
val cursor = getItem(position) as Cursor? ?: return null
|
||||
val indices = mIndices ?: return null
|
||||
val indices = indices ?: return null
|
||||
return SuggestionItem(cursor, indices)
|
||||
}
|
||||
|
||||
override fun bindView(view: View, context: Context, cursor: Cursor) {
|
||||
if (mIndices == null) throw NullPointerException()
|
||||
val indices = indices!!
|
||||
when (getActualItemViewType(cursor.position)) {
|
||||
VIEW_TYPE_SEARCH_HISTORY -> {
|
||||
val holder = view.tag as SearchViewHolder
|
||||
val title = cursor.getString(mIndices!!.title)
|
||||
val title = cursor.getString(indices.title)
|
||||
holder.edit_query.tag = title
|
||||
holder.text1.text = title
|
||||
holder.icon.setImageResource(R.drawable.ic_action_history)
|
||||
}
|
||||
VIEW_TYPE_SAVED_SEARCH -> {
|
||||
val holder = view.tag as SearchViewHolder
|
||||
val title = cursor.getString(mIndices!!.title)
|
||||
val title = cursor.getString(indices.title)
|
||||
holder.edit_query.tag = title
|
||||
holder.text1.text = title
|
||||
holder.icon.setImageResource(R.drawable.ic_action_save)
|
||||
}
|
||||
VIEW_TYPE_USER_SUGGESTION_ITEM -> {
|
||||
val holder = view.tag as UserViewHolder
|
||||
val userKey = UserKey.valueOf(cursor.getString(mIndices!!.extra_id))!!
|
||||
val userKey = UserKey.valueOf(cursor.getString(indices.extra_id))!!
|
||||
holder.text1.text = mUserColorNameManager.getUserNickname(userKey,
|
||||
cursor.getString(mIndices!!.title))
|
||||
cursor.getString(indices.title))
|
||||
holder.text2.visibility = View.VISIBLE
|
||||
holder.text2.text = String.format("@%s", cursor.getString(mIndices!!.summary))
|
||||
holder.text2.text = "@${cursor.getString(indices.summary)}"
|
||||
holder.icon.clearColorFilter()
|
||||
mMediaLoader.displayProfileImage(holder.icon, cursor.getString(mIndices!!.icon))
|
||||
mMediaLoader.displayProfileImage(holder.icon, cursor.getString(indices.icon))
|
||||
}
|
||||
VIEW_TYPE_USER_SCREEN_NAME -> {
|
||||
val holder = view.tag as UserViewHolder
|
||||
holder.text1.text = String.format("@%s", cursor.getString(mIndices!!.title))
|
||||
holder.text1.text = "@${cursor.getString(indices.title)}"
|
||||
holder.text2.visibility = View.GONE
|
||||
holder.icon.setColorFilter(holder.text1.currentTextColor, Mode.SRC_ATOP)
|
||||
mMediaLoader.cancelDisplayTask(holder.icon)
|
||||
|
@ -352,8 +357,8 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
|
||||
fun getActualItemViewType(position: Int): Int {
|
||||
val cursor = super.getItem(position) as Cursor
|
||||
if (cursor == null || mIndices == null) throw NullPointerException()
|
||||
when (cursor.getString(mIndices!!.type)) {
|
||||
if (indices == null) throw NullPointerException()
|
||||
when (cursor.getString(indices!!.type)) {
|
||||
Suggestions.Search.TYPE_SAVED_SEARCH -> {
|
||||
return VIEW_TYPE_SAVED_SEARCH
|
||||
}
|
||||
|
@ -377,24 +382,20 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.edit_query -> {
|
||||
mActivity.setSearchQueryText(v.tag as String)
|
||||
activity.setSearchQueryText(v.tag as String)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun swapCursor(newCursor: Cursor?): Cursor {
|
||||
if (newCursor != null) {
|
||||
mIndices = Indices(newCursor)
|
||||
} else {
|
||||
mIndices = null
|
||||
}
|
||||
mRemovedPositions!!.clear()
|
||||
override fun swapCursor(newCursor: Cursor?): Cursor? {
|
||||
indices = if (newCursor != null) Indices(newCursor) else null
|
||||
removedPositions!!.clear()
|
||||
return super.swapCursor(newCursor)
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
if (mRemovedPositions == null) return super.getCount()
|
||||
return super.getCount() - mRemovedPositions.size()
|
||||
if (removedPositions == null) return super.getCount()
|
||||
return super.getCount() - removedPositions.size()
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Any {
|
||||
|
@ -405,21 +406,21 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
return super.getItemId(getActualPosition(position))
|
||||
}
|
||||
|
||||
override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
return super.getView(getActualPosition(position), convertView, parent)
|
||||
}
|
||||
|
||||
override fun getDropDownView(position: Int, convertView: View, parent: ViewGroup): View {
|
||||
override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
return super.getDropDownView(getActualPosition(position), convertView, parent)
|
||||
}
|
||||
|
||||
private fun getActualPosition(position: Int): Int {
|
||||
if (mRemovedPositions == null) return position
|
||||
if (removedPositions == null) return position
|
||||
var skipped = 0
|
||||
var i = 0
|
||||
val j = mRemovedPositions.size()
|
||||
val j = removedPositions.size()
|
||||
while (i < j) {
|
||||
if (position + skipped >= mRemovedPositions.get(i)) {
|
||||
if (position + skipped >= removedPositions.get(i)) {
|
||||
skipped++
|
||||
}
|
||||
i++
|
||||
|
@ -429,9 +430,9 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
|
|||
|
||||
fun addRemovedPositions(positions: IntArray) {
|
||||
for (position in positions) {
|
||||
mRemovedPositions!!.add(getActualPosition(position))
|
||||
removedPositions!!.add(getActualPosition(position))
|
||||
}
|
||||
mRemovedPositions!!.sort()
|
||||
removedPositions!!.sort()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
|
|
|
@ -70,62 +70,62 @@ import java.util.*
|
|||
|
||||
abstract class AbsActivitiesFragment protected constructor() : AbsContentListRecyclerViewFragment<ParcelableActivitiesAdapter>(), LoaderCallbacks<List<ParcelableActivity>>, ParcelableActivitiesAdapter.ActivityAdapterListener, KeyboardShortcutCallback {
|
||||
|
||||
private val mStatusesBusCallback: Any
|
||||
private val mHotMobiScrollTracker = object : OnScrollListener() {
|
||||
private val statusesBusCallback: Any
|
||||
private val hotMobiScrollTracker = object : OnScrollListener() {
|
||||
|
||||
var mRecords: MutableList<ScrollRecord>? = null
|
||||
private var mFirstVisibleTimestamp: Long = -1
|
||||
private var mFirstVisibleAccountId: UserKey? = null
|
||||
private var mFirstVisiblePosition = -1
|
||||
private var mScrollState: Int = 0
|
||||
var records: MutableList<ScrollRecord>? = null
|
||||
private var firstVisibleTimestamp: Long = -1
|
||||
private var firstVisibleAccountId: UserKey? = null
|
||||
private var firstVisiblePosition = -1
|
||||
private var scrollState: Int = 0
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
|
||||
val layoutManager = recyclerView!!.layoutManager as LinearLayoutManager
|
||||
val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
|
||||
if (firstVisiblePosition != mFirstVisiblePosition && firstVisiblePosition >= 0) {
|
||||
val pos = layoutManager.findFirstVisibleItemPosition()
|
||||
if (pos != firstVisiblePosition && pos >= 0) {
|
||||
//noinspection unchecked
|
||||
val adapter = recyclerView.adapter as ParcelableActivitiesAdapter
|
||||
val activity = adapter.getActivity(firstVisiblePosition)
|
||||
val activity = adapter.getActivity(pos)
|
||||
if (activity != null) {
|
||||
val timestamp = activity.timestamp
|
||||
val accountKey = activity.account_key
|
||||
if (timestamp != mFirstVisibleTimestamp || accountKey != mFirstVisibleAccountId) {
|
||||
if (mRecords == null) mRecords = ArrayList<ScrollRecord>()
|
||||
if (timestamp != firstVisibleTimestamp || accountKey != firstVisibleAccountId) {
|
||||
if (records == null) records = ArrayList<ScrollRecord>()
|
||||
val time = System.currentTimeMillis()
|
||||
mRecords!!.add(ScrollRecord.create(timestamp.toString(), accountKey, time,
|
||||
TimeZone.getDefault().getOffset(time).toLong(), mScrollState))
|
||||
records!!.add(ScrollRecord.create(timestamp.toString(), accountKey, time,
|
||||
TimeZone.getDefault().getOffset(time).toLong(), scrollState))
|
||||
}
|
||||
mFirstVisibleTimestamp = timestamp
|
||||
mFirstVisibleAccountId = accountKey
|
||||
firstVisibleTimestamp = timestamp
|
||||
firstVisibleAccountId = accountKey
|
||||
}
|
||||
}
|
||||
mFirstVisiblePosition = firstVisiblePosition
|
||||
firstVisiblePosition = pos
|
||||
}
|
||||
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
|
||||
mScrollState = newState
|
||||
scrollState = newState
|
||||
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
if (mRecords != null) {
|
||||
HotMobiLogger.getInstance(activity).logList(mRecords, null, "scroll")
|
||||
if (records != null) {
|
||||
HotMobiLogger.getInstance(activity).logList(records, null, "scroll")
|
||||
}
|
||||
mRecords = null
|
||||
records = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val mOnScrollListener = object : OnScrollListener() {
|
||||
private val onScrollListener = object : OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
|
||||
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
saveReadPosition()
|
||||
}
|
||||
}
|
||||
}
|
||||
private var mNavigationHelper: RecyclerViewNavigationHelper? = null
|
||||
private var mPauseOnScrollListener: OnScrollListener? = null
|
||||
private var mActiveHotMobiScrollTracker: OnScrollListener? = null
|
||||
private var navigationHelper: RecyclerViewNavigationHelper? = null
|
||||
private var pauseOnScrollListener: OnScrollListener? = null
|
||||
private var activeHotMobiScrollTracker: OnScrollListener? = null
|
||||
|
||||
init {
|
||||
mStatusesBusCallback = createMessageBusCallback()
|
||||
statusesBusCallback = createMessageBusCallback()
|
||||
}
|
||||
|
||||
abstract fun getActivities(param: RefreshTaskParam): Boolean
|
||||
|
@ -178,7 +178,7 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
|
|||
}
|
||||
}
|
||||
}
|
||||
return mNavigationHelper!!.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
|
||||
return navigationHelper!!.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
|
||||
}
|
||||
|
||||
private fun openActivity(activity: ParcelableActivity) {
|
||||
|
@ -200,12 +200,12 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
|
|||
when (action) {
|
||||
ACTION_STATUS_REPLY, ACTION_STATUS_RETWEET, ACTION_STATUS_FAVORITE -> return true
|
||||
}
|
||||
return mNavigationHelper!!.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
|
||||
return navigationHelper!!.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
|
||||
}
|
||||
|
||||
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler, keyCode: Int, repeatCount: Int,
|
||||
event: KeyEvent, metaState: Int): Boolean {
|
||||
return mNavigationHelper!!.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
||||
return navigationHelper!!.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableActivity>> {
|
||||
|
@ -381,8 +381,8 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
|
|||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
recyclerView.addOnScrollListener(mOnScrollListener)
|
||||
recyclerView.addOnScrollListener(mPauseOnScrollListener)
|
||||
recyclerView.addOnScrollListener(onScrollListener)
|
||||
recyclerView.addOnScrollListener(pauseOnScrollListener)
|
||||
val task = object : AbstractTask<Any?, Boolean, RecyclerView>() {
|
||||
public override fun doLongOperation(params: Any?): Boolean {
|
||||
val context = context ?: return false
|
||||
|
@ -395,24 +395,24 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
|
|||
|
||||
public override fun afterExecute(recyclerView: RecyclerView?, result: Boolean?) {
|
||||
if (result!!) {
|
||||
mActiveHotMobiScrollTracker = mHotMobiScrollTracker
|
||||
recyclerView!!.addOnScrollListener(mActiveHotMobiScrollTracker)
|
||||
activeHotMobiScrollTracker = hotMobiScrollTracker
|
||||
recyclerView!!.addOnScrollListener(activeHotMobiScrollTracker)
|
||||
}
|
||||
}
|
||||
}
|
||||
task.setCallback(recyclerView)
|
||||
TaskStarter.execute(task)
|
||||
bus.register(mStatusesBusCallback)
|
||||
bus.register(statusesBusCallback)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
bus.unregister(mStatusesBusCallback)
|
||||
if (mActiveHotMobiScrollTracker != null) {
|
||||
recyclerView.removeOnScrollListener(mActiveHotMobiScrollTracker)
|
||||
bus.unregister(statusesBusCallback)
|
||||
if (activeHotMobiScrollTracker != null) {
|
||||
recyclerView.removeOnScrollListener(activeHotMobiScrollTracker)
|
||||
}
|
||||
mActiveHotMobiScrollTracker = null
|
||||
recyclerView.removeOnScrollListener(mPauseOnScrollListener)
|
||||
recyclerView.removeOnScrollListener(mOnScrollListener)
|
||||
activeHotMobiScrollTracker = null
|
||||
recyclerView.removeOnScrollListener(pauseOnScrollListener)
|
||||
recyclerView.removeOnScrollListener(onScrollListener)
|
||||
if (userVisibleHint) {
|
||||
saveReadPosition()
|
||||
}
|
||||
|
@ -438,9 +438,9 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
|
|||
val layoutManager = layoutManager
|
||||
adapter!!.setListener(this)
|
||||
registerForContextMenu(recyclerView)
|
||||
mNavigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager!!, adapter,
|
||||
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager!!, adapter,
|
||||
this)
|
||||
mPauseOnScrollListener = PauseRecyclerViewOnScrollListener(adapter.mediaLoader.imageLoader, false, true)
|
||||
pauseOnScrollListener = PauseRecyclerViewOnScrollListener(adapter.mediaLoader.imageLoader, false, true)
|
||||
|
||||
val loaderArgs = Bundle(arguments)
|
||||
loaderArgs.putBoolean(IntentConstants.EXTRA_FROM_USER, true)
|
|
@ -115,11 +115,12 @@ abstract class AbsToolbarTabPagesFragment : BaseSupportFragment(), RefreshScroll
|
|||
return false
|
||||
}
|
||||
|
||||
override fun getCurrentVisibleFragment(): Fragment? {
|
||||
val currentItem = viewPager.currentItem
|
||||
if (currentItem < 0 || currentItem >= pagerAdapter!!.count) return null
|
||||
return pagerAdapter!!.instantiateItem(viewPager, currentItem) as Fragment
|
||||
}
|
||||
override val currentVisibleFragment: Fragment?
|
||||
get() {
|
||||
val currentItem = viewPager.currentItem
|
||||
if (currentItem < 0 || currentItem >= pagerAdapter!!.count) return null
|
||||
return pagerAdapter!!.instantiateItem(viewPager, currentItem) as Fragment
|
||||
}
|
||||
|
||||
override fun triggerRefresh(position: Int): Boolean {
|
||||
return false
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.*
|
||||
|
||||
class AccountNotificationSettingsFragment : BaseAccountPreferenceFragment() {
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
val preference = findPreference(KEY_NOTIFICATION_LIGHT_COLOR)
|
||||
val account = account
|
||||
if (preference != null && account != null) {
|
||||
preference.setDefaultValue(account.color)
|
||||
}
|
||||
}
|
||||
|
||||
override val preferencesResource: Int
|
||||
get() = R.xml.preferences_account_notifications
|
||||
|
||||
override val switchPreferenceDefault: Boolean
|
||||
get() = DEFAULT_NOTIFICATION
|
||||
|
||||
override val switchPreferenceKey: String?
|
||||
get() = KEY_NOTIFICATION
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.SharedPreferences
|
||||
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.DEFAULT_AUTO_REFRESH
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_AUTO_REFRESH
|
||||
|
||||
class AccountRefreshSettingsFragment : BaseAccountPreferenceFragment() {
|
||||
|
||||
override val preferencesResource: Int
|
||||
get() = R.xml.preferences_account_refresh
|
||||
|
||||
override val switchPreferenceDefault: Boolean
|
||||
get() = DEFAULT_AUTO_REFRESH
|
||||
|
||||
override val switchPreferenceKey: String?
|
||||
get() = null
|
||||
|
||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
|
||||
val activity = activity ?: return
|
||||
if (KEY_AUTO_REFRESH == key) {
|
||||
Utils.startRefreshServiceIfNeeded(activity)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -268,7 +268,7 @@ class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks<Cursor>
|
|||
}
|
||||
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
|
||||
if (KEY_DEFAULT_ACCOUNT_KEY == key) {
|
||||
updateDefaultAccountState()
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceActivity.EXTRA_SHOW_FRAGMENT
|
||||
import android.text.TextUtils
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_PREFERENCES_NAME_PREFIX
|
||||
import org.mariotaku.twidere.constant.IntentConstants
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
||||
import org.mariotaku.twidere.model.ParcelableAccount
|
||||
|
||||
abstract class BaseAccountPreferenceFragment : BasePreferenceFragment(), OnCheckedChangeListener, OnSharedPreferenceChangeListener {
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
val pm = preferenceManager
|
||||
val account = arguments.getParcelable<ParcelableAccount>(IntentConstants.EXTRA_ACCOUNT) ?: return
|
||||
val preferenceName = "$ACCOUNT_PREFERENCES_NAME_PREFIX${account.account_key}"
|
||||
pm.sharedPreferencesName = preferenceName
|
||||
addPreferencesFromResource(preferencesResource)
|
||||
val prefs = pm.sharedPreferences
|
||||
prefs.registerOnSharedPreferenceChangeListener(this)
|
||||
val activity = activity
|
||||
val intent = activity.intent
|
||||
if (intent.hasExtra(EXTRA_SHOW_FRAGMENT)) {
|
||||
val nameFirst = prefs.getBoolean(KEY_NAME_FIRST, true)
|
||||
val name = userColorNameManager.getDisplayName(account.account_key,
|
||||
account.name, account.screen_name, nameFirst)
|
||||
activity.title = name
|
||||
}
|
||||
updatePreferenceScreen()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
val pm = preferenceManager
|
||||
val prefs = pm.sharedPreferences
|
||||
prefs.unregisterOnSharedPreferenceChangeListener(this)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
|
||||
val prefs = preferenceManager.sharedPreferences
|
||||
val editor = prefs.edit()
|
||||
if (prefs.getBoolean(switchPreferenceKey, switchPreferenceDefault) != isChecked) {
|
||||
editor.putBoolean(switchPreferenceKey, isChecked)
|
||||
editor.apply()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
|
||||
val switchKey = switchPreferenceKey
|
||||
if (!TextUtils.isEmpty(switchKey)) {
|
||||
inflater!!.inflate(R.menu.menu_switch_preference, menu)
|
||||
val actionView = menu!!.findItem(R.id.toggle).actionView
|
||||
val toggle = actionView.findViewById(android.R.id.toggle) as CompoundButton
|
||||
val prefs = preferenceManager.sharedPreferences
|
||||
toggle.setOnCheckedChangeListener(this)
|
||||
toggle.isChecked = prefs.getBoolean(switchKey, switchPreferenceDefault)
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
|
||||
if (key == switchPreferenceKey) {
|
||||
updatePreferenceScreen()
|
||||
}
|
||||
}
|
||||
|
||||
protected val account: ParcelableAccount?
|
||||
get() {
|
||||
val args = arguments ?: return null
|
||||
return args.getParcelable<ParcelableAccount>(IntentConstants.EXTRA_ACCOUNT)
|
||||
}
|
||||
|
||||
protected abstract val preferencesResource: Int
|
||||
|
||||
protected abstract val switchPreferenceDefault: Boolean
|
||||
|
||||
protected abstract val switchPreferenceKey: String?
|
||||
|
||||
private fun updatePreferenceScreen() {
|
||||
val screen = preferenceScreen
|
||||
val sharedPreferences = preferenceManager.sharedPreferences
|
||||
if (screen == null || sharedPreferences == null) return
|
||||
screen.isEnabled = sharedPreferences.getBoolean(switchPreferenceKey, switchPreferenceDefault)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.media.RingtoneManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.support.v7.preference.Preference
|
||||
import android.support.v7.preference.PreferenceFragmentCompat
|
||||
|
||||
import org.mariotaku.twidere.preference.RingtonePreference
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler
|
||||
import org.mariotaku.twidere.util.UserColorNameManager
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
|
||||
private var ringtonePreferenceKey: String? = null
|
||||
|
||||
@Inject
|
||||
lateinit var keyboardShortcutHandler: KeyboardShortcutsHandler
|
||||
@Inject
|
||||
lateinit var userColorNameManager: UserColorNameManager
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
GeneralComponentHelper.build(context).inject(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
if (savedInstanceState != null) {
|
||||
ringtonePreferenceKey = savedInstanceState.getString(EXTRA_RINGTONE_PREFERENCE_KEY)
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
outState!!.putString(EXTRA_RINGTONE_PREFERENCE_KEY, ringtonePreferenceKey)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
REQUEST_PICK_RINGTONE -> {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
val ringtone = data.getParcelableExtra<Uri>(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
|
||||
if (ringtonePreferenceKey != null) {
|
||||
val ringtonePreference = findPreference(ringtonePreferenceKey) as RingtonePreference?
|
||||
if (ringtonePreference != null) {
|
||||
ringtonePreference.value = ringtone?.toString()
|
||||
}
|
||||
}
|
||||
ringtonePreferenceKey = null
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
override fun onPreferenceTreeClick(preference: Preference): Boolean {
|
||||
if (preference is RingtonePreference) {
|
||||
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, preference.ringtoneType)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, preference.isShowDefault)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, preference.isShowSilent)
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, Settings.System.DEFAULT_NOTIFICATION_URI)
|
||||
|
||||
val existingValue = preference.value // TODO
|
||||
if (existingValue != null) {
|
||||
if (existingValue.length == 0) {
|
||||
// Select "Silent"
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, null as Uri)
|
||||
} else {
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Uri.parse(existingValue))
|
||||
}
|
||||
} else {
|
||||
// No ringtone has been selected, set to the default
|
||||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Settings.System.DEFAULT_NOTIFICATION_URI)
|
||||
}
|
||||
startActivityForResult(intent, REQUEST_PICK_RINGTONE)
|
||||
ringtonePreferenceKey = preference.key
|
||||
return true
|
||||
}
|
||||
return super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val REQUEST_PICK_RINGTONE = 301
|
||||
private val EXTRA_RINGTONE_PREFERENCE_KEY = "internal:ringtone_preference_key"
|
||||
}
|
||||
|
||||
}
|
|
@ -26,14 +26,13 @@ import android.os.Bundle
|
|||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.text.BidiFormatter
|
||||
import com.squareup.otto.Bus
|
||||
import org.mariotaku.twidere.Constants
|
||||
import org.mariotaku.twidere.constant.IntentConstants
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
open class BaseSupportFragment : Fragment(), IBaseFragment, Constants {
|
||||
open class BaseSupportFragment : Fragment(), IBaseFragment {
|
||||
|
||||
// Utility classes
|
||||
@Inject
|
||||
|
@ -83,14 +82,16 @@ open class BaseSupportFragment : Fragment(), IBaseFragment, Constants {
|
|||
activity.supportInvalidateOptionsMenu()
|
||||
}
|
||||
|
||||
override fun getExtraConfiguration(): Bundle? {
|
||||
return null
|
||||
}
|
||||
override val extraConfiguration: Bundle?
|
||||
get() {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getTabPosition(): Int {
|
||||
val args = arguments
|
||||
return if (args != null) args.getInt(IntentConstants.EXTRA_TAB_POSITION, -1) else -1
|
||||
}
|
||||
override val tabPosition: Int
|
||||
get() {
|
||||
val args = arguments
|
||||
return if (args != null) args.getInt(IntentConstants.EXTRA_TAB_POSITION, -1) else -1
|
||||
}
|
||||
|
||||
override fun requestFitSystemWindows() {
|
||||
val activity = activity
|
||||
|
@ -109,7 +110,7 @@ open class BaseSupportFragment : Fragment(), IBaseFragment, Constants {
|
|||
}
|
||||
}
|
||||
|
||||
override fun executeAfterFragmentResumed(action: IBaseFragment.Action) {
|
||||
override fun executeAfterFragmentResumed(action: (IBaseFragment) -> Unit) {
|
||||
actionHelper.executeAfterFragmentResumed(action)
|
||||
}
|
||||
|
||||
|
@ -118,6 +119,11 @@ open class BaseSupportFragment : Fragment(), IBaseFragment, Constants {
|
|||
actionHelper.dispatchOnResumeFragments()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
actionHelper.dispatchOnPause()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
DebugModeUtils.watchReferenceLeak(this)
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import org.mariotaku.twidere.util.support.WebSettingsSupport
|
||||
import org.mariotaku.twidere.util.webkit.DefaultWebViewClient
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
open class BaseSupportWebViewFragment : BaseSupportFragment() {
|
||||
|
||||
private var internalWebView: WebView? = null
|
||||
private var webViewAvailable: Boolean = false
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
val view = webView
|
||||
view!!.setWebViewClient(createWebViewClient())
|
||||
val settings = view.settings
|
||||
settings.builtInZoomControls = true
|
||||
settings.javaScriptEnabled = true
|
||||
WebSettingsSupport.setAllowUniversalAccessFromFileURLs(settings, true)
|
||||
}
|
||||
|
||||
|
||||
protected fun createWebViewClient(): WebViewClient {
|
||||
return DefaultWebViewClient(activity)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to instantiate the view. Creates and returns the WebView.
|
||||
*/
|
||||
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
internalWebView?.destroy()
|
||||
internalWebView = WebView(activity)
|
||||
webViewAvailable = true
|
||||
return internalWebView
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is visible to the user and actively running. Resumes the WebView.
|
||||
*/
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
internalWebView!!.onPause()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is no longer resumed. Pauses the WebView.
|
||||
*/
|
||||
override fun onResume() {
|
||||
internalWebView!!.onResume()
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the WebView has been detached from the fragment.
|
||||
* The WebView is no longer available after this time.
|
||||
*/
|
||||
override fun onDestroyView() {
|
||||
webViewAvailable = false
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is no longer in use. Destroys the internal state of the WebView.
|
||||
*/
|
||||
override fun onDestroy() {
|
||||
if (internalWebView != null) {
|
||||
internalWebView!!.destroy()
|
||||
internalWebView = null
|
||||
}
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the WebView.
|
||||
*/
|
||||
val webView: WebView?
|
||||
get() = if (webViewAvailable) internalWebView else null
|
||||
}
|
|
@ -66,7 +66,7 @@ import java.util.*
|
|||
class DirectMessagesFragment : AbsContentListRecyclerViewFragment<MessageEntriesAdapter>(), LoaderCallbacks<Cursor>, MessageEntriesAdapterListener, KeyboardShortcutCallback {
|
||||
|
||||
// Listeners
|
||||
private val mReloadContentObserver = SupportFragmentReloadCursorObserver(
|
||||
private val reloadContentObserver = SupportFragmentReloadCursorObserver(
|
||||
this, 0, this)
|
||||
|
||||
private var mRemoveUnreadCountsTask: RemoveUnreadCountsTask? = null
|
||||
|
@ -82,10 +82,9 @@ class DirectMessagesFragment : AbsContentListRecyclerViewFragment<MessageEntries
|
|||
}
|
||||
|
||||
fun onLoadMoreContents(@IndicatorPosition position: Int) {
|
||||
var position = position
|
||||
// Only supports load from end, so remove START flag
|
||||
position = position and ILoadMoreSupportAdapter.START.inv().toInt()
|
||||
if (position == 0) return
|
||||
val pos = position and ILoadMoreSupportAdapter.START.inv().toInt()
|
||||
if (pos == 0) return
|
||||
loadMoreMessages()
|
||||
}
|
||||
|
||||
|
@ -236,8 +235,7 @@ class DirectMessagesFragment : AbsContentListRecyclerViewFragment<MessageEntries
|
|||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val resolver = contentResolver
|
||||
resolver!!.registerContentObserver(Accounts.CONTENT_URI, true, mReloadContentObserver)
|
||||
contentResolver.registerContentObserver(Accounts.CONTENT_URI, true, reloadContentObserver)
|
||||
bus.register(this)
|
||||
val adapter = adapter
|
||||
adapter!!.updateReadState()
|
||||
|
@ -246,8 +244,7 @@ class DirectMessagesFragment : AbsContentListRecyclerViewFragment<MessageEntries
|
|||
|
||||
override fun onStop() {
|
||||
bus.unregister(this)
|
||||
val resolver = contentResolver
|
||||
resolver!!.unregisterContentObserver(mReloadContentObserver)
|
||||
contentResolver.unregisterContentObserver(reloadContentObserver)
|
||||
super.onStop()
|
||||
}
|
||||
|
|
@ -17,31 +17,29 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment;
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Bundle
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter;
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredKeywordsFragment;
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredLinksFragment;
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredSourcesFragment;
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredUsersFragment;
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredKeywordsFragment
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredLinksFragment
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredSourcesFragment
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment.FilteredUsersFragment
|
||||
|
||||
public class FiltersFragment extends AbsToolbarTabPagesFragment {
|
||||
class FiltersFragment : AbsToolbarTabPagesFragment() {
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTabs(SupportTabsAdapter adapter) {
|
||||
adapter.addTab(FilteredUsersFragment.class, null, getString(R.string.users), null, 0, null);
|
||||
adapter.addTab(FilteredKeywordsFragment.class, null, getString(R.string.keywords), null, 1, null);
|
||||
adapter.addTab(FilteredSourcesFragment.class, null, getString(R.string.sources), null, 2, null);
|
||||
adapter.addTab(FilteredLinksFragment.class, null, getString(R.string.links), null, 3, null);
|
||||
override fun addTabs(adapter: SupportTabsAdapter) {
|
||||
adapter.addTab(FilteredUsersFragment::class.java, null, getString(R.string.users), null, 0, null)
|
||||
adapter.addTab(FilteredKeywordsFragment::class.java, null, getString(R.string.keywords), null, 1, null)
|
||||
adapter.addTab(FilteredSourcesFragment::class.java, null, getString(R.string.sources), null, 2, null)
|
||||
adapter.addTab(FilteredLinksFragment::class.java, null, getString(R.string.links), null, 3, null)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.SupportMapFragment
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
import org.mariotaku.twidere.Constants
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_LATITUDE
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_LONGITUDE
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment
|
||||
import org.mariotaku.twidere.fragment.iface.IMapFragment
|
||||
|
||||
class GoogleMapFragment : SupportMapFragment(), Constants, IMapFragment, IBaseFragment {
|
||||
|
||||
private val actionHelper = IBaseFragment.ActionHelper(this)
|
||||
|
||||
private var activeMap: GoogleMap? = null
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
val args = arguments
|
||||
if (args == null || !args.containsKey(EXTRA_LATITUDE) || !args.containsKey(EXTRA_LONGITUDE))
|
||||
return
|
||||
val lat = args.getDouble(EXTRA_LATITUDE, 0.0)
|
||||
val lng = args.getDouble(EXTRA_LONGITUDE, 0.0)
|
||||
getMapAsync { googleMap ->
|
||||
val marker = MarkerOptions()
|
||||
marker.position(LatLng(lat, lng))
|
||||
googleMap.addMarker(marker)
|
||||
center(false)
|
||||
activeMap = googleMap
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
actionHelper.dispatchOnPause()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
actionHelper.dispatchOnResumeFragments()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_google_maps_viewer, menu)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
requestFitSystemWindows()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.center -> {
|
||||
center()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
override fun center() {
|
||||
center(true)
|
||||
}
|
||||
|
||||
fun center(animate: Boolean) {
|
||||
val googleMap = activeMap ?: return
|
||||
val args = arguments ?: return
|
||||
if (!args.containsKey(EXTRA_LATITUDE) || !args.containsKey(EXTRA_LONGITUDE))
|
||||
return
|
||||
val lat = args.getDouble(EXTRA_LATITUDE, 0.0)
|
||||
val lng = args.getDouble(EXTRA_LONGITUDE, 0.0)
|
||||
val c = CameraUpdateFactory.newLatLngZoom(LatLng(lat, lng), 12f)
|
||||
if (animate) {
|
||||
googleMap.animateCamera(c)
|
||||
} else {
|
||||
googleMap.moveCamera(c)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override val extraConfiguration: Bundle?
|
||||
get() = null
|
||||
|
||||
override val tabPosition: Int
|
||||
get() = 0
|
||||
|
||||
override fun requestFitSystemWindows() {
|
||||
val activity = activity
|
||||
val parentFragment = parentFragment
|
||||
val callback: IBaseFragment.SystemWindowsInsetsCallback
|
||||
if (parentFragment is IBaseFragment.SystemWindowsInsetsCallback) {
|
||||
callback = parentFragment
|
||||
} else if (activity is IBaseFragment.SystemWindowsInsetsCallback) {
|
||||
callback = activity
|
||||
} else {
|
||||
return
|
||||
}
|
||||
val insets = Rect()
|
||||
if (callback.getSystemWindowsInsets(insets)) {
|
||||
fitSystemWindows(insets)
|
||||
}
|
||||
}
|
||||
|
||||
override fun executeAfterFragmentResumed(action: (IBaseFragment) -> Unit) {
|
||||
actionHelper.executeAfterFragmentResumed(action)
|
||||
}
|
||||
|
||||
protected fun fitSystemWindows(insets: Rect) {
|
||||
val view = view
|
||||
view?.setPadding(insets.left, insets.top, insets.right, insets.bottom)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.nfc.NdefMessage
|
||||
import android.nfc.NdefRecord
|
||||
import android.nfc.NfcAdapter
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.content.AsyncTaskLoader
|
||||
import android.support.v4.content.Loader
|
||||
import org.mariotaku.microblog.library.MicroBlogException
|
||||
import org.mariotaku.microblog.library.statusnet.model.Group
|
||||
import org.mariotaku.twidere.Constants.*
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
||||
import org.mariotaku.twidere.model.ParcelableGroup
|
||||
import org.mariotaku.twidere.model.SingleResponse
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.util.ParcelableGroupUtils
|
||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/3/23.
|
||||
*/
|
||||
class GroupFragment : AbsToolbarTabPagesFragment(), LoaderCallbacks<SingleResponse<ParcelableGroup>> {
|
||||
var group: ParcelableGroup? = null
|
||||
private set
|
||||
private var groupLoaderInitialized: Boolean = false
|
||||
|
||||
override fun addTabs(adapter: SupportTabsAdapter) {
|
||||
val args = arguments
|
||||
adapter.addTab(GroupTimelineFragment::class.java, args, getString(R.string.statuses), 0, 0, "statuses")
|
||||
adapter.addTab(GroupMembersFragment::class.java, args, getString(R.string.members), 0, 1, "members")
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
Utils.setNdefPushMessageCallback(activity, NfcAdapter.CreateNdefMessageCallback {
|
||||
val url = group?.url ?: return@CreateNdefMessageCallback null
|
||||
NdefMessage(arrayOf(NdefRecord.createUri(url)))
|
||||
})
|
||||
|
||||
getGroupInfo(false)
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<SingleResponse<ParcelableGroup>> {
|
||||
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
val groupId = args.getString(EXTRA_GROUP_ID)
|
||||
val groupName = args.getString(EXTRA_GROUP_NAME)
|
||||
val omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true)
|
||||
return ParcelableGroupLoader(context, omitIntentExtra, arguments, accountKey,
|
||||
groupId, groupName)
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<SingleResponse<ParcelableGroup>>, data: SingleResponse<ParcelableGroup>) {
|
||||
if (data.hasData()) {
|
||||
displayGroup(data.data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<SingleResponse<ParcelableGroup>>) {
|
||||
|
||||
}
|
||||
|
||||
fun displayGroup(group: ParcelableGroup?) {
|
||||
val activity = activity ?: return
|
||||
loaderManager.destroyLoader(0)
|
||||
this.group = group
|
||||
|
||||
if (group != null) {
|
||||
activity.title = group.fullname
|
||||
} else {
|
||||
activity.setTitle(R.string.user_list)
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
|
||||
|
||||
fun getGroupInfo(omitIntentExtra: Boolean) {
|
||||
val lm = loaderManager
|
||||
lm.destroyLoader(0)
|
||||
val args = Bundle(arguments)
|
||||
args.putBoolean(EXTRA_OMIT_INTENT_EXTRA, omitIntentExtra)
|
||||
if (!groupLoaderInitialized) {
|
||||
lm.initLoader(0, args, this)
|
||||
groupLoaderInitialized = true
|
||||
} else {
|
||||
lm.restartLoader(0, args, this)
|
||||
}
|
||||
}
|
||||
|
||||
internal class ParcelableGroupLoader(
|
||||
context: Context,
|
||||
private val omitIntentExtra: Boolean,
|
||||
private val extras: Bundle?,
|
||||
private val accountKey: UserKey,
|
||||
private val groupId: String?,
|
||||
private val groupName: String?
|
||||
) : AsyncTaskLoader<SingleResponse<ParcelableGroup>>(context) {
|
||||
|
||||
override fun loadInBackground(): SingleResponse<ParcelableGroup> {
|
||||
if (!omitIntentExtra && extras != null) {
|
||||
val cache = extras.getParcelable<ParcelableGroup>(EXTRA_GROUP)
|
||||
if (cache != null) return SingleResponse.getInstance(cache)
|
||||
}
|
||||
val twitter = MicroBlogAPIFactory.getInstance(context, accountKey,
|
||||
true) ?: return SingleResponse.getInstance<ParcelableGroup>()
|
||||
try {
|
||||
val group: Group
|
||||
if (groupId != null) {
|
||||
group = twitter.showGroup(groupId)
|
||||
} else if (groupName != null) {
|
||||
group = twitter.showGroupByName(groupName)
|
||||
} else {
|
||||
return SingleResponse.getInstance<ParcelableGroup>()
|
||||
}
|
||||
return SingleResponse.getInstance(ParcelableGroupUtils.from(group, accountKey, 0,
|
||||
group.isMember))
|
||||
} catch (e: MicroBlogException) {
|
||||
return SingleResponse.getInstance<ParcelableGroup>(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override fun onStartLoading() {
|
||||
forceLoad()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -130,7 +130,7 @@ class HostMappingsListFragment : BaseListFragment(), MultiChoiceModeListener, On
|
|||
updateTitle(mode)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
|
||||
reloadHostMappings()
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
import org.mariotaku.twidere.R
|
||||
|
||||
class InvalidTabFragment : BaseSupportFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_invalid_tab, container, false)
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue