diff --git a/.travis.yml b/.travis.yml index 5ab11ff8..a3b5b461 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ android: - tools - tools # TODO https://github.com/travis-ci/travis-ci/issues/6193 - platform-tools - - build-tools-24.0.2 + - build-tools-24.0.3 - android-24 - extra-android-m2repository before_cache: diff --git a/app/build.gradle b/app/build.gradle index ff64f587..e580b2dc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'android-apt' android { compileSdkVersion 24 - buildToolsVersion "24.0.2" + buildToolsVersion "24.0.3" defaultConfig { applicationId "com.github.dfa.diaspora_android" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1fa2f2e4..1c0486e4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -66,7 +66,15 @@ - + + + + + + + + + @@ -74,7 +82,6 @@ - @@ -86,17 +93,16 @@ + - - + - @@ -104,15 +110,14 @@ + - - @@ -126,10 +131,14 @@ - - + + + + + + @@ -138,50 +147,43 @@ - - - - - - + - - + - @@ -200,32 +202,33 @@ - + - + + + + - - - + @@ -238,7 +241,10 @@ - + + + + @@ -246,4 +252,4 @@ - \ No newline at end of file + diff --git a/app/src/main/java/com/github/dfa/diaspora_android/activity/AboutActivity.java b/app/src/main/java/com/github/dfa/diaspora_android/activity/AboutActivity.java index 424a1d22..85c4dd32 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/activity/AboutActivity.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/activity/AboutActivity.java @@ -63,7 +63,7 @@ import butterknife.ButterKnife; * Activity that holds some fragments that show information about the app in a tab layout */ public class AboutActivity extends ThemedActivity -implements IntellihideToolbarActivityListener { + implements IntellihideToolbarActivityListener { private SectionsPagerAdapter mSectionsPagerAdapter; private ViewPager mViewPager; @@ -108,7 +108,7 @@ implements IntellihideToolbarActivityListener { @Override public void onResume() { super.onResume(); - if(getAppSettings().isIntellihideToolbars()) { + if (getAppSettings().isIntellihideToolbars()) { this.enableToolbarHiding(); } else { this.disableToolbarHiding(); @@ -310,6 +310,7 @@ implements IntellihideToolbarActivityListener { Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.about__fragment_debug, container, false); ButterKnife.bind(this, rootView); + App app = (App) getActivity().getApplication(); logBox.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { @@ -338,6 +339,9 @@ implements IntellihideToolbarActivityListener { osVersion.setText(getString(R.string.fragment_debug__android_version, Build.VERSION.RELEASE)); deviceName.setText(getString(R.string.fragment_debug__device_name, Build.MANUFACTURER + " " + Build.MODEL)); podDomain.setText(getString(R.string.fragment_debug__pod_domain, urls.getPodUrl())); + if (app.getSettings().getPod() != null) { + podDomain.setText(getString(R.string.fragment_debug__pod_domain, app.getSettings().getPod().getName())); + } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); diff --git a/app/src/main/java/com/github/dfa/diaspora_android/activity/MainActivity.java b/app/src/main/java/com/github/dfa/diaspora_android/activity/MainActivity.java index 28a132eb..689c45ee 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/activity/MainActivity.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/activity/MainActivity.java @@ -68,15 +68,15 @@ import com.github.dfa.diaspora_android.fragment.HashtagListFragment; import com.github.dfa.diaspora_android.fragment.PodSelectionFragment; import com.github.dfa.diaspora_android.listener.WebUserProfileChangedListener; import com.github.dfa.diaspora_android.receiver.OpenExternalLinkReceiver; -import com.github.dfa.diaspora_android.util.ProxyHandler; import com.github.dfa.diaspora_android.receiver.UpdateTitleReceiver; import com.github.dfa.diaspora_android.ui.BadgeDrawable; import com.github.dfa.diaspora_android.ui.IntellihideToolbarActivityListener; import com.github.dfa.diaspora_android.util.AppLog; import com.github.dfa.diaspora_android.util.CustomTabHelpers.CustomTabActivityHelper; import com.github.dfa.diaspora_android.util.DiasporaUrlHelper; -import com.github.dfa.diaspora_android.util.theming.ThemeHelper; +import com.github.dfa.diaspora_android.util.ProxyHandler; import com.github.dfa.diaspora_android.util.WebHelper; +import com.github.dfa.diaspora_android.util.theming.ThemeHelper; import butterknife.BindView; import butterknife.ButterKnife; @@ -181,7 +181,7 @@ public class MainActivity extends ThemedActivity @Override public void setTitle(int rId) { CustomFragment top = getTopFragment(); - if(top != null && top.getFragmentTag().equals(DiasporaStreamFragment.TAG)) { + if (top != null && top.getFragmentTag().equals(DiasporaStreamFragment.TAG)) { MainActivity.this.setTitle(rId); } } @@ -189,14 +189,15 @@ public class MainActivity extends ThemedActivity @Override public void setTitle(String title) { CustomFragment top = getTopFragment(); - if(top != null && top.getFragmentTag().equals(DiasporaStreamFragment.TAG)) { + if (top != null && top.getFragmentTag().equals(DiasporaStreamFragment.TAG)) { MainActivity.this.setTitle(title); } } }); - if (!appSettings.hasPodDomain()) { + if (!appSettings.hasPod()) { AppLog.d(this, "We have no pod. Show PodSelectionFragment"); + updateNavigationViewEntryVisibilities(); showFragment(getFragment(PodSelectionFragment.TAG)); } else { AppLog.d(this, "Pod found. Handle intents."); @@ -246,6 +247,7 @@ public class MainActivity extends ThemedActivity /** * Show DiasporaStreamFragment if necessary and load URL url + * * @param url URL to load in the DiasporaStreamFragment */ public void openDiasporaUrl(String url) { @@ -259,6 +261,7 @@ public class MainActivity extends ThemedActivity * Get an instance of the CustomFragment with the tag fragmentTag. * If there was no instance so far, create a new one and add it to the FragmentManagers pool. * If there is no Fragment with the corresponding Tag, return the top fragment. + * * @param fragmentTag tag * @return corresponding Fragment */ @@ -294,6 +297,7 @@ public class MainActivity extends ThemedActivity /** * Show the Fragment fragment in R.id.fragment_container. If the fragment was already visible, do nothing. + * * @param fragment Fragment to show */ protected void showFragment(CustomFragment fragment) { @@ -342,8 +346,8 @@ public class MainActivity extends ThemedActivity if (!appSettings.getName().equals("")) { navheaderTitle.setText(appSettings.getName()); } - if (!appSettings.getPodDomain().equals("")) { - navheaderDescription.setText(appSettings.getPodDomain()); + if (appSettings.getPod() != null) { + navheaderDescription.setText(appSettings.getPod().getName()); } String avatarUrl = appSettings.getAvatarUrl(); if (!avatarUrl.equals("")) { @@ -376,10 +380,16 @@ public class MainActivity extends ThemedActivity navMenu.findItem(R.id.nav_mentions).setVisible(appSettings.isVisibleInNavMentions()); navMenu.findItem(R.id.nav_profile).setVisible(appSettings.isVisibleInNavProfile()); navMenu.findItem(R.id.nav_public).setVisible(appSettings.isVisibleInNavPublic_activities()); + + // Top bar + if (!appSettings.hasPod()) { + navMenu.setGroupVisible(navMenu.findItem(R.id.nav_exit).getGroupId(), false); + } } /** * Forward incoming intents to handleIntent() + * * @param intent incoming */ @Override @@ -390,6 +400,7 @@ public class MainActivity extends ThemedActivity /** * Handle intents and execute intent specific actions + * * @param intent intent to get handled */ private void handleIntent(Intent intent) { @@ -418,6 +429,7 @@ public class MainActivity extends ThemedActivity } } else if (ACTION_CHANGE_ACCOUNT.equals(action)) { AppLog.v(this, "Reset pod data and show PodSelectionFragment"); + appSettings.setPod(null); app.resetPodData(((DiasporaStreamFragment) getFragment(DiasporaStreamFragment.TAG)).getWebView()); showFragment(getFragment(PodSelectionFragment.TAG)); } else if (ACTION_CLEAR_CACHE.equals(action)) { @@ -462,6 +474,7 @@ public class MainActivity extends ThemedActivity /** * Return the fragment which is currently displayed in R.id.fragment_container + * * @return top fragment or null if there is none displayed */ private CustomFragment getTopFragment() { @@ -545,6 +558,7 @@ public class MainActivity extends ThemedActivity /** * Clear and repopulate top and bottom toolbar. * Also add menu items of the displayed fragment + * * @param menu top toolbar * @return boolean */ @@ -575,12 +589,14 @@ public class MainActivity extends ThemedActivity /** * Set the notification and messages counter in the top toolbar + * * @param menu menu * @return boolean */ @Override public boolean onPrepareOptionsMenu(Menu menu) { MenuItem item; + updateNavigationViewEntryVisibilities(); if ((item = menu.findItem(R.id.action_notifications)) != null) { LayerDrawable icon = (LayerDrawable) item.getIcon(); @@ -596,6 +612,7 @@ public class MainActivity extends ThemedActivity /** * Handle clicks on the optionsmenu + * * @param item item * @return boolean */ @@ -694,6 +711,7 @@ public class MainActivity extends ThemedActivity /** * Update the profile name in the navigation slider + * * @param name name */ @Override @@ -704,6 +722,7 @@ public class MainActivity extends ThemedActivity /** * Update the profile picture in the navigation slider + * * @param avatarUrl url of the new profile pic */ @Override @@ -714,6 +733,7 @@ public class MainActivity extends ThemedActivity /** * Handle hashtag clicks. Open the new-post-url and inject the clicked hashtag into the post-editor + * * @param intent intent */ private void handleHashtag(Intent intent) { @@ -728,6 +748,7 @@ public class MainActivity extends ThemedActivity /** * Open the new-post-url and inject text that was shared into the app into the post editors text field + * * @param intent shareTextIntent */ private void handleSendText(Intent intent) { @@ -786,6 +807,7 @@ public class MainActivity extends ThemedActivity /** * Share an image shared to the app via diaspora + * * @param intent shareImageIntent */ //TODO: Implement some day @@ -802,6 +824,7 @@ public class MainActivity extends ThemedActivity /** * Invalidate the top toolbar to update the notification counter + * * @param notificationCount new notification count */ @Override @@ -813,6 +836,7 @@ public class MainActivity extends ThemedActivity /** * Invalidate the top toolbar to update the unread messages counter + * * @param unreadMessageCount new unread messages count */ @Override @@ -945,8 +969,9 @@ public class MainActivity extends ThemedActivity /** * React to results of requestPermission - * @param requestCode resCode - * @param permissions requested permissions + * + * @param requestCode resCode + * @param permissions requested permissions * @param grantResults granted results */ @Override @@ -970,6 +995,7 @@ public class MainActivity extends ThemedActivity /** * Return the string that will be shared into the new-post-editor + * * @return String */ public String getTextToBeShared() { @@ -978,6 +1004,7 @@ public class MainActivity extends ThemedActivity /** * Set the string that will be shared into the new-post-editor + * * @param textToBeShared */ public void setTextToBeShared(String textToBeShared) { diff --git a/app/src/main/java/com/github/dfa/diaspora_android/activity/SettingsActivity.java b/app/src/main/java/com/github/dfa/diaspora_android/activity/SettingsActivity.java index 89ec73d5..807e6069 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/activity/SettingsActivity.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/activity/SettingsActivity.java @@ -41,9 +41,10 @@ import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.R; import com.github.dfa.diaspora_android.data.AppSettings; import com.github.dfa.diaspora_android.ui.IntellihideToolbarActivityListener; -import com.github.dfa.diaspora_android.util.theming.ColorPalette; -import com.github.dfa.diaspora_android.util.ProxyHandler; import com.github.dfa.diaspora_android.util.AppLog; +import com.github.dfa.diaspora_android.util.DiasporaUrlHelper; +import com.github.dfa.diaspora_android.util.ProxyHandler; +import com.github.dfa.diaspora_android.util.theming.ColorPalette; import com.github.dfa.diaspora_android.util.theming.ThemeHelper; import butterknife.BindView; @@ -63,6 +64,7 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb private ProxyHandler.ProxySettings oldProxySettings; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -140,11 +142,11 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { updatePreference(findPreference(key)); - if(key.equals(getString(R.string.pref_key__intellihide_toolbars))) { - if(sharedPreferences.getBoolean(getString(R.string.pref_key__intellihide_toolbars), false)) { - ((SettingsActivity)getActivity()).enableToolbarHiding(); + if (key.equals(getString(R.string.pref_key__intellihide_toolbars))) { + if (sharedPreferences.getBoolean(getString(R.string.pref_key__intellihide_toolbars), false)) { + ((SettingsActivity) getActivity()).enableToolbarHiding(); } else { - ((SettingsActivity)getActivity()).disableToolbarHiding(); + ((SettingsActivity) getActivity()).disableToolbarHiding(); } } } @@ -168,7 +170,7 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { App app = ((App) getActivity().getApplication()); AppSettings appSettings = app.getSettings(); - if(Build.VERSION.SDK_INT >= 21) { + if (Build.VERSION.SDK_INT >= 21) { if (preference instanceof PreferenceScreen && ((PreferenceScreen) preference).getDialog() != null) { Window window = ((PreferenceScreen) preference).getDialog().getWindow(); if (window != null) { @@ -178,7 +180,7 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb } Intent intent = new Intent(getActivity(), MainActivity.class); - String podDomain = appSettings.getPodDomain(); + DiasporaUrlHelper diasporaUrlHelper = new DiasporaUrlHelper(app.getSettings()); switch (preference.getTitleRes()) { case R.string.pref_title__primary_color: { @@ -193,17 +195,17 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb } case R.string.pref_title__personal_settings: { intent.setAction(MainActivity.ACTION_OPEN_URL); - intent.putExtra(MainActivity.URL_MESSAGE, "https://" + podDomain + "/user/edit"); + intent.putExtra(MainActivity.URL_MESSAGE, diasporaUrlHelper.getPersonalSettingsUrl()); break; } case R.string.pref_title__manage_tags: { intent.setAction(MainActivity.ACTION_OPEN_URL); - intent.putExtra(MainActivity.URL_MESSAGE, "https://" + podDomain + "/tag_followings/manage"); + intent.putExtra(MainActivity.URL_MESSAGE, diasporaUrlHelper.getManageTagsUrl()); break; } case R.string.pref_title__manage_contacts: { intent.setAction(MainActivity.ACTION_OPEN_URL); - intent.putExtra(MainActivity.URL_MESSAGE, "https://" + podDomain + "/contacts"); + intent.putExtra(MainActivity.URL_MESSAGE, diasporaUrlHelper.getManageContactsUrl()); break; } case R.string.pref_title__change_account: { @@ -229,8 +231,7 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb return true; } - case R.string.pref_title__clear_cache: - { + case R.string.pref_title__clear_cache: { intent.setAction(MainActivity.ACTION_CLEAR_CACHE); break; } @@ -250,10 +251,11 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb /** * Show a colorPicker Dialog + * * @param type 1 -> Primary Color, 2 -> Accent Color */ public void showColorPickerDialog(final int type) { - final AppSettings appSettings = ((App)getActivity().getApplication()).getSettings(); + final AppSettings appSettings = ((App) getActivity().getApplication()).getSettings(); final Context context = getActivity(); //Inflate dialog layout @@ -278,10 +280,10 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb base.setOnColorChangedListener(new OnColorChangedListener() { @Override public void onColorChanged(int i) { - AppLog.d(this, "Selected Base color changed: "+i); + AppLog.d(this, "Selected Base color changed: " + i); shade.setColors(ColorPalette.getColors(context, i)); titleBackground.setBackgroundColor(i); - if(i == current[0]) { + if (i == current[0]) { shade.setSelectedColor(current[1]); titleBackground.setBackgroundColor(shade.getColor()); } @@ -300,12 +302,12 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { - if(type == 1) { + if (type == 1) { appSettings.setPrimaryColorSettings(base.getColor(), shade.getColor()); - if(Build.VERSION.SDK_INT >= 21) { + if (Build.VERSION.SDK_INT >= 21) { getActivity().getWindow().setStatusBarColor(ThemeHelper.getPrimaryDarkColor()); } - ((ThemedActivity)getActivity()).applyColorToViews(); + ((ThemedActivity) getActivity()).applyColorToViews(); } else { appSettings.setAccentColorSettings(base.getColor(), shade.getColor()); } @@ -327,10 +329,10 @@ public class SettingsActivity extends ThemedActivity implements IntellihideToolb @Override protected void onStop() { ProxyHandler.ProxySettings newProxySettings = getAppSettings().getProxySettings(); - if(!oldProxySettings.equals(newProxySettings)) { + if (!oldProxySettings.equals(newProxySettings)) { AppLog.d(this, "ProxySettings changed."); //Proxy on-off? => Restart app - if(oldProxySettings.isEnabled() && !newProxySettings.isEnabled()) { + if (oldProxySettings.isEnabled() && !newProxySettings.isEnabled()) { Intent restartActivity = new Intent(SettingsActivity.this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(SettingsActivity.this, 12374, restartActivity, PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager mgr = (AlarmManager) SettingsActivity.this.getSystemService(Context.ALARM_SERVICE); diff --git a/app/src/main/java/com/github/dfa/diaspora_android/activity/ThemedActivity.java b/app/src/main/java/com/github/dfa/diaspora_android/activity/ThemedActivity.java index 840b1964..aba3c1c0 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/activity/ThemedActivity.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/activity/ThemedActivity.java @@ -37,7 +37,7 @@ import com.github.dfa.diaspora_android.util.theming.ThemeHelper; public abstract class ThemedActivity extends AppCompatActivity { protected AppSettings getAppSettings() { - return ((App)getApplication()).getSettings(); + return ((App) getApplication()).getSettings(); } @Override @@ -48,6 +48,7 @@ public abstract class ThemedActivity extends AppCompatActivity { updateRecentAppColor(); applyColorToViews(); } + protected abstract void applyColorToViews(); /** @@ -64,10 +65,10 @@ public abstract class ThemedActivity extends AppCompatActivity { * Update primary color in recent apps overview */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void updateRecentAppColor(){ + private void updateRecentAppColor() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { BitmapDrawable drawable = ((BitmapDrawable) getDrawable(R.drawable.ic_launcher)); - if(drawable != null) { + if (drawable != null) { setTaskDescription(new ActivityManager.TaskDescription( getResources().getString(R.string.app_name), drawable.getBitmap(), diff --git a/app/src/main/java/com/github/dfa/diaspora_android/data/AppSettings.java b/app/src/main/java/com/github/dfa/diaspora_android/data/AppSettings.java index b6cb17b2..d105a8f0 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/data/AppSettings.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/data/AppSettings.java @@ -19,8 +19,13 @@ import android.content.Context; import android.content.SharedPreferences; import com.github.dfa.diaspora_android.R; +import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod; +import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod.DiasporaPodUrl; import com.github.dfa.diaspora_android.util.ProxyHandler; +import org.json.JSONException; +import org.json.JSONObject; + /** * Settings * Created by gsantner (https://gsantner.github.io/) on 20.03.16. Part of Diaspora for Android. @@ -29,6 +34,7 @@ public class AppSettings { private final SharedPreferences prefApp; private final SharedPreferences prefPod; private final Context context; + private DiasporaPod currentPod0Cached; public AppSettings(Context context) { this.context = context.getApplicationContext(); @@ -135,24 +141,44 @@ public class AppSettings { setString(prefPod, R.string.pref_key__podprofile_name, name); } - public String getPodDomain() { - return getString(prefPod, R.string.pref_key__poddomain, ""); + + // TODO: Remove legacy at some time ;) + public void upgradeLegacyPoddomain() { + String legacy = getString(prefPod, R.string.pref_key__poddomain_legacy, ""); + if (!legacy.equals("")) { + DiasporaPod pod = new DiasporaPod(); + pod.setName(legacy); + pod.getPodUrls().add(new DiasporaPodUrl().setHost(legacy)); + setPod(pod); + } } - public void setPodDomain(String podDomain) { - setString(prefPod, R.string.pref_key__poddomain, podDomain); + public DiasporaPod getPod() { + upgradeLegacyPoddomain(); + if (currentPod0Cached == null) { + String pref = getString(prefPod, R.string.pref_key__current_pod_0, ""); + + try { + currentPod0Cached = new DiasporaPod().fromJson(new JSONObject(pref)); + } catch (JSONException e) { + currentPod0Cached = null; + } + } + return currentPod0Cached; } - public boolean hasPodDomain() { - return !getString(prefPod, R.string.pref_key__poddomain, "").equals(""); + public void setPod(DiasporaPod pod) { + try { + setString(prefPod, R.string.pref_key__current_pod_0, + pod == null ? null : pod.toJson().toString()); + currentPod0Cached = pod; + } catch (JSONException ignored) { + } } - public String[] getPreviousPodlist() { - return getStringArray(prefApp, R.string.pref_key__previous_podlist); - } - - public void setPreviousPodlist(String[] pods) { - setStringArray(prefApp, R.string.pref_key__previous_podlist, pods); + public boolean hasPod() { + upgradeLegacyPoddomain(); + return !getString(prefPod, R.string.pref_key__current_pod_0, "").equals(""); } public void setPodAspects(PodAspect[] aspects) { @@ -238,6 +264,7 @@ public class AppSettings { public void setProxyHttpHost(String value) { setString(prefApp, R.string.pref_key__http_proxy_host, value); } + /** * Default value: 0 * diff --git a/app/src/main/java/com/github/dfa/diaspora_android/data/DiasporaPodList.java b/app/src/main/java/com/github/dfa/diaspora_android/data/DiasporaPodList.java new file mode 100644 index 00000000..150f7303 --- /dev/null +++ b/app/src/main/java/com/github/dfa/diaspora_android/data/DiasporaPodList.java @@ -0,0 +1,516 @@ +package com.github.dfa.diaspora_android.data; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + + +/** + * Created by gsantner (https://gsantner.github.io/ on 30.09.16. + * DiasporaPodList - List container for DiasporaPod's, with methods to merge with other DiasporaPodLists + * DiasporaPod - Data container for a Pod, can include N DiasporaPodUrl's + * DiasporaPodUrl - A Url of an DiasporaPod + * For all Classes a loading and saving to JSON method is available + */ +public class DiasporaPodList implements Iterable, Serializable { + private List pods = new ArrayList<>(); + private boolean trackMergeChanges = false; + private Integer trackAddedIndexStart = -1; + private List trackUpdatedIndexes = new ArrayList<>(); + private boolean keepOldNameDuringMerge = false; + private long timestamp; + + public DiasporaPodList() { + } + + /** + * Load DiasporaPodList from Json + * + * @param json Json Object + */ + public DiasporaPodList fromJson(JSONObject json) throws JSONException { + JSONArray jarr; + pods.clear(); + + if (json.has("pods")) { + jarr = json.getJSONArray("pods"); + for (int i = 0; i < jarr.length(); i++) { + DiasporaPod pod = new DiasporaPod().fromJson(jarr.getJSONObject(i)); + pods.add(pod); + } + } + if (json.has("timestamp")) { + timestamp = json.getLong("timestamp"); + } + return this; + } + + /** + * Convert DiasporaPodList to JSON + */ + public JSONObject toJson() throws JSONException { + JSONObject json = new JSONObject(); + JSONArray jpods = new JSONArray(); + for (DiasporaPod pod : pods) { + jpods.put(pod.toJson()); + } + json.put("pods", jpods); + json.put("timestamp", System.currentTimeMillis()); + return json; + } + + /** + * Merge newer entries into this podlist + * Will add new pods, and update data of pods with data from the new list + * + * @param newPodList Another podlist + */ + public void mergeWithNewerEntries(final DiasporaPodList newPodList) throws JSONException { + if (isTrackMergeChanges()) { + trackAddedIndexStart = -1; + trackUpdatedIndexes.clear(); + } + for (DiasporaPod newPod : newPodList) { + int index = pods.indexOf(newPod); + if (index >= 0) { + DiasporaPod updatePodBak = new DiasporaPod().fromJson(pods.get(index).toJson()); + DiasporaPod updatePod = pods.get(index); + updatePod.fromJson(newPod.toJson()); + + // Restore Pod id (if was set to zero) + if (updatePodBak.getId() != 0 && updatePod.getId() == 0) { + updatePod.setId(updatePodBak.getId()); + } + if (updatePodBak.getActive6() != 0 && updatePod.getActive6() == 0) { + updatePod.setActive6(updatePodBak.getActive6()); + } + if (updatePodBak.getScore() != 0 && updatePod.getScore() == 0) { + updatePod.setScore(updatePodBak.getScore()); + } + if (!updatePodBak.getName().equals("") && keepOldNameDuringMerge) { + updatePod.setName(updatePodBak.getName()); + } + if (isTrackMergeChanges()) { + trackUpdatedIndexes.add(index); + } + } else { + pods.add(newPod); + if (isTrackMergeChanges() && trackAddedIndexStart == -1) { + trackAddedIndexStart = pods.size() - 1; + } + } + } + } + + /** + * Sort the pod list + */ + public void sortPods() { + Collections.sort(pods); + } + + /** + * Iterator for Iterable interface (forEach, ..) + */ + public Iterator iterator() { + return pods.iterator(); + } + + public int size() { + return pods.size(); + } + + public int indexOf(DiasporaPod pod) { + return pods.indexOf(pod); + } + + public List getPods() { + return pods; + } + + public void setPods(List pods) { + this.pods = pods; + } + + public DiasporaPod getPodAt(int index) { + if (index >= 0 && index < pods.size()) { + return pods.get(index); + } + return null; + } + + public boolean isTrackMergeChanges() { + return trackMergeChanges; + } + + public void setTrackMergeChanges(boolean trackMergeChanges) { + this.trackMergeChanges = trackMergeChanges; + } + + public Integer getTrackAddedIndexStart() { + return trackAddedIndexStart; + } + + public List getTrackUpdatedIndexes() { + return trackUpdatedIndexes; + } + + public boolean isKeepOldNameDuringMerge() { + return keepOldNameDuringMerge; + } + + public void setKeepOldNameDuringMerge(boolean keepOldNameDuringMerge) { + this.keepOldNameDuringMerge = keepOldNameDuringMerge; + } + + + /* ██████╗ ██████╗ ██████╗ + * ██╔══██╗██╔═══██╗██╔══██╗ + * ██████╔╝██║ ██║██║ ██║ + * ██╔═══╝ ██║ ██║██║ ██║ + * ██║ ╚██████╔╝██████╔╝ + * ╚═╝ ╚═════╝ ╚═════╝ + */ + public static class DiasporaPod implements Iterable, Comparable, Serializable { + private List podUrls = new ArrayList<>(); + private List mainLangs = new ArrayList<>(); + private String name = ""; + private int score = 0; + private int id = 0; + private long active6 = 0; + + + public DiasporaPod() { + } + + /** + * Load a DiasporaPod from JSON + * + * @param json Json Object + */ + public DiasporaPod fromJson(JSONObject json) throws JSONException { + JSONArray jarr; + + if (json.has("name")) { + name = json.getString("name"); + } + if (json.has("mainLangs")) { + jarr = json.getJSONArray("mainLangs"); + for (int i = 0; i < jarr.length(); i++) { + String val = jarr.getString(i); + if (!mainLangs.contains(val)) { + mainLangs.add(val); + } + } + } + if (json.has("podUrls")) { + jarr = json.getJSONArray("podUrls"); + for (int i = 0; i < jarr.length(); i++) { + DiasporaPodUrl podUrl = new DiasporaPodUrl().fromJson(jarr.getJSONObject(i)); + if (!podUrls.contains(podUrl)) { + podUrls.add(podUrl); + } + } + } + if (json.has("score")) { + score = json.getInt("score"); + } + if (json.has("active6")) { + active6 = json.getLong("active6"); + } + if (json.has("id")) { + id = json.getInt("id"); + } + return this; + } + + /** + * Convert DiasporaPod to JSON + */ + public JSONObject toJson() throws JSONException { + JSONObject json = new JSONObject(); + json.put("name", name); + json.put("score", score); + json.put("active6", active6); + json.put("id", id); + + // Pod urls + JSONArray jarr = new JSONArray(); + for (DiasporaPodUrl value : podUrls) { + jarr.put(value.toJson()); + } + json.put("podUrls", jarr); + + // main langs + jarr = new JSONArray(); + for (String value : mainLangs) { + jarr.put(value); + } + json.put("mainLangs", jarr); + return json; + } + + @Override + public boolean equals(Object o) { + boolean ret = false; + if (o instanceof DiasporaPod) { + DiasporaPod otherPod = (DiasporaPod) o; + + // Check if id is equal + ret = this.id != 0 && this.id == otherPod.id; + + // Check if host is the same (fallback if id is 0) + if (!ret) { + for (DiasporaPodUrl podUrl : podUrls) { + for (DiasporaPodUrl otherPodUrl : otherPod.getPodUrls()) { + if (podUrl.getBaseUrl().equals(otherPodUrl.getBaseUrl())) { + ret = true; + } + } + } + } + } + return ret; + } + + @Override + public int compareTo(DiasporaPod otherPod) { + if (otherPod != null) { + List myPodUrls = getPodUrls(); + List otherPodUrls = otherPod.getPodUrls(); + if (!myPodUrls.isEmpty() && !otherPodUrls.isEmpty()) { + return myPodUrls.get(0).getHost().compareTo(otherPodUrls.get(0).getHost()); + } + } + return name.compareTo(otherPod.getName()); + } + + @Override + public String toString() { + return name + "(" + id + ")"; + } + + /** + * Iterator for Iterable interface (forEach, ..) + */ + public Iterator iterator() { + return podUrls.iterator(); + } + + /* + * Getter & Setter + */ + public List getPodUrls() { + return podUrls; + } + + public DiasporaPod setPodUrls(List podUrls) { + this.podUrls = podUrls; + return this; + } + + public List getMainLangs() { + return mainLangs; + } + + public DiasporaPod setMainLangs(List mainLangs) { + this.mainLangs = mainLangs; + return this; + } + + public DiasporaPod appendMainLangs(String... values) { + for (String mainLang : values) { + this.mainLangs.add(mainLang); + } + return this; + } + + /** + * Returns the first DiasporaPodUrl in the list + */ + public DiasporaPodUrl getPodUrl() { + if (podUrls.size() > 0) { + return podUrls.get(0); + } + return null; + } + + public DiasporaPod appendPodUrls(DiasporaPodUrl... values) { + for (DiasporaPodUrl value : values) { + this.podUrls.add(value); + } + return this; + } + + public String getName() { + return name; + } + + public DiasporaPod setName(String name) { + this.name = name; + return this; + } + + public int getScore() { + return score; + } + + public DiasporaPod setScore(int score) { + this.score = score; + return this; + } + + public long getActive6() { + return active6; + } + + public DiasporaPod setActive6(long active6) { + this.active6 = active6; + return this; + } + + public int getId() { + return id; + } + + public DiasporaPod setId(int id) { + this.id = id; + return this; + } + + /* ██████╗ ██████╗ ██████╗ ██╗ ██╗██████╗ ██╗ + * ██╔══██╗██╔═══██╗██╔══██╗ ██║ ██║██╔══██╗██║ + * ██████╔╝██║ ██║██║ ██║ ██║ ██║██████╔╝██║ + * ██╔═══╝ ██║ ██║██║ ██║ ██║ ██║██╔══██╗██║ + * ██║ ╚██████╔╝██████╔╝ ╚██████╔╝██║ ██║███████╗ + * ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ + */ + public static class DiasporaPodUrl implements Serializable { + private String host = ""; + private String protocol = "https"; + private Integer port = 443; + + public DiasporaPodUrl() { + } + + public DiasporaPodUrl(JSONObject json) throws JSONException { + fromJson(json); + } + + /** + * Get the base url + * + * @return + */ + public String getBaseUrl() { + return protocol + "://" + host + (isPortNeeded() ? port : ""); + } + + /** + * Convert JSON to DiasporaPodList + * + * @param json JSON Object + */ + public DiasporaPodUrl fromJson(JSONObject json) throws JSONException { + if (json.has("host")) { + host = json.getString("host"); + } + if (json.has("protocol")) { + protocol = json.getString("protocol"); + } + if (json.has("port")) { + port = json.getInt("port"); + } + return this; + } + + /*** + * Convert DiasporaPodList to JSON + */ + public JSONObject toJson() throws JSONException { + JSONObject json = new JSONObject(); + json.put("host", host); + if (!protocol.equals("https")) { + json.put("protocol", protocol); + } + if (port != 443) { + json.put("port", port); + } + return json; + } + + /** + * Set default values for https + */ + public void setHttpsDefaults() { + setProtocol("https"); + setPort(443); + } + + + /** + * Set default values for http + */ + public void setHttpDefaults() { + setProtocol("http"); + setPort(80); + } + + /** + * Tells if the ports needs to shown + */ + public boolean isPortNeeded() { + return !((port == 80 && protocol.equals("http")) || (port == 443 && protocol.equals("https"))); + } + + @Override + public String toString() { + return getBaseUrl(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof DiasporaPodUrl) { + return getBaseUrl().equals(((DiasporaPodUrl) o).getBaseUrl()); + } + return false; + } + + /* + * GETTER & SETTER + */ + public String getHost() { + return host; + } + + public DiasporaPodUrl setHost(String host) { + this.host = host; + return this; + } + + public String getProtocol() { + return protocol; + } + + public DiasporaPodUrl setProtocol(String protocol) { + this.protocol = protocol; + return this; + } + + public Integer getPort() { + return port; + } + + public DiasporaPodUrl setPort(Integer port) { + this.port = port; + return this; + } + } + } +} diff --git a/app/src/main/java/com/github/dfa/diaspora_android/data/PodAspect.java b/app/src/main/java/com/github/dfa/diaspora_android/data/PodAspect.java index b878f679..7c9c2fab 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/data/PodAspect.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/data/PodAspect.java @@ -70,8 +70,8 @@ public class PodAspect { public String toHtmlLink(final App app) { final AppSettings appSettings = app.getSettings(); return String.format(Locale.getDefault(), - "%s", - appSettings.getPodDomain(), id, name); + "%s", + appSettings.getPod().getPodUrl().getBaseUrl(), id, name); } @Override diff --git a/app/src/main/java/com/github/dfa/diaspora_android/data/PodUserProfile.java b/app/src/main/java/com/github/dfa/diaspora_android/data/PodUserProfile.java index b670513c..d6d3b2e2 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/data/PodUserProfile.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/data/PodUserProfile.java @@ -20,11 +20,9 @@ package com.github.dfa.diaspora_android.data; import android.os.Handler; -import com.github.dfa.diaspora_android.util.AppLog; -import com.github.dfa.diaspora_android.util.Log; - import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.listener.WebUserProfileChangedListener; +import com.github.dfa.diaspora_android.util.AppLog; import org.json.JSONArray; import org.json.JSONException; @@ -128,7 +126,7 @@ public class PodUserProfile { isWebUserProfileLoaded = true; } catch (JSONException e) { - AppLog.d(this, e.getMessage()); + AppLog.d(this, e.getMessage()); isWebUserProfileLoaded = false; } lastLoaded = System.currentTimeMillis(); @@ -173,6 +171,7 @@ public class PodUserProfile { /** * Sets the avatar, returns true if this was a new one, false if already the old one + * * @param avatarUrl url * @return true if new avatar url */ diff --git a/app/src/main/java/com/github/dfa/diaspora_android/fragment/BrowserFragment.java b/app/src/main/java/com/github/dfa/diaspora_android/fragment/BrowserFragment.java index 9213ca9f..38cabc79 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/fragment/BrowserFragment.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/fragment/BrowserFragment.java @@ -41,10 +41,10 @@ import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.R; import com.github.dfa.diaspora_android.activity.MainActivity; import com.github.dfa.diaspora_android.data.AppSettings; -import com.github.dfa.diaspora_android.util.ProxyHandler; import com.github.dfa.diaspora_android.ui.ContextMenuWebView; -import com.github.dfa.diaspora_android.util.theming.ThemeHelper; import com.github.dfa.diaspora_android.util.AppLog; +import com.github.dfa.diaspora_android.util.ProxyHandler; +import com.github.dfa.diaspora_android.util.theming.ThemeHelper; import com.github.dfa.diaspora_android.webview.CustomWebViewClient; import com.github.dfa.diaspora_android.webview.ProgressBarWebChromeClient; @@ -78,7 +78,7 @@ public class BrowserFragment extends ThemedFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { AppLog.d(this, "onCreateView()"); - if(rootLayout == null) { + if (rootLayout == null) { rootLayout = inflater.inflate(R.layout.browser__fragment, container, false); } return rootLayout; @@ -89,21 +89,21 @@ public class BrowserFragment extends ThemedFragment { AppLog.d(this, "onViewCreated()"); super.onViewCreated(view, savedInstanceState); - if(this.appSettings == null) { + if (this.appSettings == null) { this.appSettings = ((App) getActivity().getApplication()).getSettings(); } - if(this.webView == null) { + if (this.webView == null) { this.webView = (ContextMenuWebView) view.findViewById(R.id.webView); this.applyWebViewSettings(); ProxyHandler.getInstance().addWebView(webView); } - if(this.progressBar == null) { + if (this.progressBar == null) { this.progressBar = (ProgressBar) view.findViewById(R.id.progressBar); } - if(pendingUrl != null) { + if (pendingUrl != null) { loadUrl(pendingUrl); pendingUrl = null; } @@ -149,7 +149,7 @@ public class BrowserFragment extends ThemedFragment { @Override public void onResume() { super.onResume(); - if(webView != null) { + if (webView != null) { webSettings.setMinimumFontSize(appSettings.getMinimumFontSize()); webSettings.setLoadsImagesAutomatically(appSettings.isLoadImages()); } @@ -188,8 +188,8 @@ public class BrowserFragment extends ThemedFragment { String fileSaveName = hasToShareScreenshot ? ".DfA_share.jpg" : String.format("DfA_%s.jpg", dateFormat.format(dateNow)); if (!fileSaveDirectory.exists()) { - if(!fileSaveDirectory.mkdirs()) { - AppLog.w(this, "Could not mkdir "+fileSaveDirectory.getAbsolutePath()); + if (!fileSaveDirectory.mkdirs()) { + AppLog.w(this, "Could not mkdir " + fileSaveDirectory.getAbsolutePath()); } } @@ -248,7 +248,7 @@ public class BrowserFragment extends ThemedFragment { } public boolean onBackPressed() { - if(webView.canGoBack()) { + if (webView.canGoBack()) { webView.goBack(); return true; } @@ -256,17 +256,17 @@ public class BrowserFragment extends ThemedFragment { } public void loadUrl(String url) { - if(getWebView() != null) { - AppLog.v(this, "loadUrl(): load "+url); + if (getWebView() != null) { + AppLog.v(this, "loadUrl(): load " + url); getWebView().loadUrlNew(url); } else { - AppLog.v(this, "loadUrl(): WebView null: Set pending url to "+url); + AppLog.v(this, "loadUrl(): WebView null: Set pending url to " + url); pendingUrl = url; } } public String getUrl() { - if(getWebView() != null) { + if (getWebView() != null) { return getWebView().getUrl(); } else { return pendingUrl; @@ -275,7 +275,7 @@ public class BrowserFragment extends ThemedFragment { public void reloadUrl() { AppLog.v(this, "reloadUrl()"); - if(getWebView() != null) { + if (getWebView() != null) { getWebView().reload(); } } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/fragment/CustomFragment.java b/app/src/main/java/com/github/dfa/diaspora_android/fragment/CustomFragment.java index 3673d739..4283acf6 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/fragment/CustomFragment.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/fragment/CustomFragment.java @@ -34,6 +34,7 @@ public abstract class CustomFragment extends Fragment { /** * We have an optionsMenu + * * @param savedInstanceState state */ @Override @@ -44,13 +45,15 @@ public abstract class CustomFragment extends Fragment { /** * Return the tag used to identify the Fragment. + * * @return tag */ public abstract String getFragmentTag(); /** * Add fragment-dependent options to the bottom options toolbar - * @param menu bottom menu + * + * @param menu bottom menu * @param inflater inflater */ public abstract void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater); @@ -58,6 +61,7 @@ public abstract class CustomFragment extends Fragment { /** * Return true if the fragment reacted to a back button press, false else. * In case the fragment returned false, the parent activity should handle the backPress. + * * @return did we react to the back press? */ public abstract boolean onBackPressed(); diff --git a/app/src/main/java/com/github/dfa/diaspora_android/fragment/DiasporaStreamFragment.java b/app/src/main/java/com/github/dfa/diaspora_android/fragment/DiasporaStreamFragment.java index d10b4e6d..7d289d70 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/fragment/DiasporaStreamFragment.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/fragment/DiasporaStreamFragment.java @@ -44,12 +44,12 @@ import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.R; import com.github.dfa.diaspora_android.activity.MainActivity; import com.github.dfa.diaspora_android.data.PodUserProfile; -import com.github.dfa.diaspora_android.webview.DiasporaStreamWebChromeClient; -import com.github.dfa.diaspora_android.webview.FileUploadWebChromeClient; import com.github.dfa.diaspora_android.util.AppLog; import com.github.dfa.diaspora_android.util.DiasporaUrlHelper; import com.github.dfa.diaspora_android.util.Helpers; import com.github.dfa.diaspora_android.util.WebHelper; +import com.github.dfa.diaspora_android.webview.DiasporaStreamWebChromeClient; +import com.github.dfa.diaspora_android.webview.FileUploadWebChromeClient; import org.json.JSONException; @@ -79,9 +79,9 @@ public class DiasporaStreamFragment extends BrowserFragment { webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new JavaScriptInterface(), "AndroidBridge"); - if(((MainActivity)getActivity()).getTextToBeShared() != null) { + if (((MainActivity) getActivity()).getTextToBeShared() != null) { loadUrl(urls.getNewPostUrl()); - } else if(webView.getUrl() == null) { + } else if (webView.getUrl() == null) { loadUrl(urls.getStreamUrl()); } } @@ -98,11 +98,11 @@ public class DiasporaStreamFragment extends BrowserFragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - AppLog.d(this, "onActivityResult(): "+requestCode); + AppLog.d(this, "onActivityResult(): " + requestCode); switch (requestCode) { case MainActivity.INPUT_FILE_REQUEST_CODE_NEW: case MainActivity.INPUT_FILE_REQUEST_CODE_OLD: - AppLog.v(this, "INPUT_FILE_REQUEST_CODE: "+requestCode); + AppLog.v(this, "INPUT_FILE_REQUEST_CODE: " + requestCode); onImageUploadResult(requestCode, resultCode, data); return; } @@ -114,7 +114,7 @@ public class DiasporaStreamFragment extends BrowserFragment { AppLog.d(this, "StreamFragment.onOptionsItemSelected()"); switch (item.getItemId()) { case R.id.action_reload: { - if(WebHelper.isOnline(getContext())) { + if (WebHelper.isOnline(getContext())) { reloadUrl(); return true; } else { @@ -226,18 +226,19 @@ public class DiasporaStreamFragment extends BrowserFragment { protected DiasporaStreamWebChromeClient.SharedTextCallback sharedTextCallback = new DiasporaStreamWebChromeClient.SharedTextCallback() { @Override public String getSharedText() { - return ((MainActivity)getActivity()).getTextToBeShared(); + return ((MainActivity) getActivity()).getTextToBeShared(); } + @Override public void setSharedText(String shared) { - ((MainActivity)getActivity()).setTextToBeShared(shared); + ((MainActivity) getActivity()).setTextToBeShared(shared); } }; protected FileUploadWebChromeClient.FileUploadCallback fileUploadCallback = new FileUploadWebChromeClient.FileUploadCallback() { @Override public boolean imageUpload(WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { - if(Build.VERSION.SDK_INT >= 23) { + if (Build.VERSION.SDK_INT >= 23) { int hasWRITE_EXTERNAL_STORAGE = getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE); if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) { if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { @@ -261,7 +262,8 @@ public class DiasporaStreamFragment extends BrowserFragment { } } AppLog.v(this, "onOpenFileChooser"); - if (imageUploadFilePathCallbackNew != null) imageUploadFilePathCallbackNew.onReceiveValue(null); + if (imageUploadFilePathCallbackNew != null) + imageUploadFilePathCallbackNew.onReceiveValue(null); imageUploadFilePathCallbackNew = filePathCallback; Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getContext().getPackageManager()) != null) { @@ -271,7 +273,7 @@ public class DiasporaStreamFragment extends BrowserFragment { photoFile = Helpers.createImageFile(); takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath); } catch (IOException ex) { - AppLog.e(this, "ERROR creating temp file: "+ ex.toString()); + AppLog.e(this, "ERROR creating temp file: " + ex.toString()); // Error occurred while creating the File Snackbar.make(webView, R.string.unable_to_load_image, Snackbar.LENGTH_LONG).show(); return false; @@ -321,7 +323,7 @@ public class DiasporaStreamFragment extends BrowserFragment { @SuppressWarnings("unused") @JavascriptInterface public void setUserProfile(final String webMessage) throws JSONException { - PodUserProfile pup = ((App)getActivity().getApplication()).getPodUserProfile(); + PodUserProfile pup = ((App) getActivity().getApplication()).getPodUserProfile(); AppLog.v(this, "StreamFragment.JavaScriptInterface.setUserProfile()"); if (pup.isRefreshNeeded()) { AppLog.v(this, "PodUserProfile needs refresh; Try to parse JSON"); @@ -334,7 +336,7 @@ public class DiasporaStreamFragment extends BrowserFragment { @SuppressWarnings("unused") @JavascriptInterface public void contentHasBeenShared() { - ((MainActivity)getActivity()).setTextToBeShared(null); + ((MainActivity) getActivity()).setTextToBeShared(null); } } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/fragment/HashtagListFragment.java b/app/src/main/java/com/github/dfa/diaspora_android/fragment/HashtagListFragment.java index 104d6951..6c32d6b9 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/fragment/HashtagListFragment.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/fragment/HashtagListFragment.java @@ -94,9 +94,9 @@ public class HashtagListFragment extends CustomFragment { @Override public void onClick(View view) { int itemPosition = followedTagsRecyclerView.getChildLayoutPosition(view); - if(itemPosition > -1 && itemPosition < followedTags.length) { + if (itemPosition > -1 && itemPosition < followedTags.length) { String tag = followedTags[itemPosition]; - ((MainActivity)getActivity()).openDiasporaUrl(urls.getSearchTagsUrl(tag)); + ((MainActivity) getActivity()).openDiasporaUrl(urls.getSearchTagsUrl(tag)); } } }; diff --git a/app/src/main/java/com/github/dfa/diaspora_android/fragment/PodSelectionFragment.java b/app/src/main/java/com/github/dfa/diaspora_android/fragment/PodSelectionFragment.java index 9a2ad317..c131c03d 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/fragment/PodSelectionFragment.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/fragment/PodSelectionFragment.java @@ -18,20 +18,16 @@ */ package com.github.dfa.diaspora_android.fragment; -import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.os.Build; import android.os.Bundle; import android.support.design.widget.Snackbar; import android.support.v4.content.LocalBroadcastManager; -import android.text.Editable; -import android.text.SpannableString; -import android.text.TextWatcher; -import android.text.util.Linkify; +import android.support.v4.view.MenuItemCompat; +import android.support.v7.widget.SearchView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -41,74 +37,98 @@ import android.view.ViewGroup; import android.webkit.CookieManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.ImageView; import android.widget.ListView; +import android.widget.TextView; import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.R; import com.github.dfa.diaspora_android.activity.MainActivity; import com.github.dfa.diaspora_android.data.AppSettings; +import com.github.dfa.diaspora_android.data.DiasporaPodList; +import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod; import com.github.dfa.diaspora_android.task.GetPodsService; +import com.github.dfa.diaspora_android.ui.PodSelectionDialog; import com.github.dfa.diaspora_android.util.AppLog; import com.github.dfa.diaspora_android.util.DiasporaUrlHelper; -import com.github.dfa.diaspora_android.util.WebHelper; +import com.github.dfa.diaspora_android.util.Helpers; + +import org.json.JSONException; +import org.json.JSONObject; import java.util.ArrayList; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + /** * Fragment that lets the user choose a Pod * Created by vanitas on 01.10.16. */ -public class PodSelectionFragment extends CustomFragment { +public class PodSelectionFragment extends CustomFragment implements SearchView.OnQueryTextListener, PodSelectionDialog.PodSelectionDialogResultListener { public static final String TAG = "com.github.dfa.diaspora_android.PodSelectionFragment"; - protected EditText editFilter; - protected ListView listPods; - protected ImageView selectPodButton; + @BindView(R.id.podselection__fragment__listpods) + protected ListView listViewPod; protected App app; protected AppSettings appSettings; + private DiasporaPodList podList; + private ArrayAdapter listViewPodAdapter; + private String filterString = ""; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { AppLog.d(this, "onCreateView()"); - return inflater.inflate(R.layout.podselection__fragment, container, false); + View view = inflater.inflate(R.layout.podselection__fragment, container, false); + ButterKnife.bind(this, view); + return view; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - this.app = (App) getActivity().getApplication(); - this.appSettings = app.getSettings(); + app = (App) getActivity().getApplication(); + appSettings = app.getSettings(); - this.editFilter = (EditText) view.findViewById(R.id.podselection__edit_filter); - this.listPods = (ListView) view.findViewById(R.id.podselection__listpods); - this.selectPodButton = (ImageView) view.findViewById(R.id.podselection__button_select_pod); + // Load local podlist + podList = new DiasporaPodList(); + mergePodlistWithRessources(podList); + podList.setTrackMergeChanges(true); + updateListedPods(); - listPods.setTextFilterEnabled(true); - listPods.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override + + listViewPod.setTextFilterEnabled(true); + listViewPod.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView adapterView, View view, int i, long l) { - showPodConfirmationDialog((String) listPods.getAdapter().getItem(i)); - } - }); - setListedPods(appSettings.getPreviousPodlist()); - LocalBroadcastManager.getInstance(getContext()).registerReceiver(podListReceiver, new IntentFilter(GetPodsService.MESSAGE_PODS_RECEIVED)); - if (!WebHelper.isOnline(getContext())) { - Snackbar.make(listPods, R.string.no_internet, Snackbar.LENGTH_LONG).show(); - } - selectPodButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (editFilter.getText().length() > 4 && editFilter.getText().toString().contains("")) { - showPodConfirmationDialog(editFilter.getText().toString()); - } else { - Snackbar.make(listPods, R.string.valid_pod, Snackbar.LENGTH_LONG).show(); + String text = ((TextView) view).getText().toString(); + for (DiasporaPod pod : podList) { + if (pod.getPodUrl().getHost().equals(text)) { + showPodSelectionDialog(pod); + return; + } } + } }); + LocalBroadcastManager.getInstance(getContext()).registerReceiver(podListReceiver, new IntentFilter(GetPodsService.MESSAGE_PODS_RECEIVED)); + Helpers.showInfoIfUserNotConnectedToInternet(getContext(), listViewPod); + } + + public void mergePodlistWithRessources(DiasporaPodList podlist) { + String sPodlist = Helpers.readTextfileFromRawRessource(getContext(), R.raw.podlist, "", ""); + try { + JSONObject jPodlist = new JSONObject(sPodlist); + podlist.mergeWithNewerEntries(new DiasporaPodList().fromJson(jPodlist)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @OnClick(R.id.podselection__fragment__button_use_custom_pod) + public void onPodButtonClicked(View v) { + showPodSelectionDialog(new DiasporaPod()); } @Override @@ -116,28 +136,20 @@ public class PodSelectionFragment extends CustomFragment { return TAG; } - @Override - public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) { - /* Nothing to do */ - } - - @Override - public boolean onBackPressed() { - return false; - } - private final BroadcastReceiver podListReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (intent.hasExtra("pods")) { + if (intent.hasExtra(GetPodsService.EXTRA_PODLIST)) { Bundle extras = intent.getExtras(); - String[] pods = extras.getStringArray("pods"); - if (pods != null && pods.length > 0) { - app.getSettings().setPreviousPodlist(pods); - setListedPods(pods); + DiasporaPodList newPods = (DiasporaPodList) extras.get(GetPodsService.EXTRA_PODLIST); + if (newPods != null && newPods.getPods().size() > 0) { + try { + podList.mergeWithNewerEntries(newPods); + updateListedPods(); + } catch (JSONException ignored) { + } } else { - setListedPods(app.getSettings().getPreviousPodlist()); - Snackbar.make(listPods, R.string.podlist_error, Snackbar.LENGTH_SHORT).show(); + Snackbar.make(listViewPod, R.string.podlist_error, Snackbar.LENGTH_SHORT).show(); } } } @@ -150,83 +162,30 @@ public class PodSelectionFragment extends CustomFragment { getContext().startService(i); } - - private void setListedPods(String[] listedPodsArr) { + private void updateListedPods() { final ArrayList listedPodsList = new ArrayList<>(); - for (String pod : listedPodsArr) { - listedPodsList.add(pod.toLowerCase()); + for (DiasporaPod pod : this.podList) { + listedPodsList.add(pod.getPodUrl().getHost()); } - final ArrayAdapter adapter = new ArrayAdapter<>( + listViewPodAdapter = new ArrayAdapter<>( getContext(), android.R.layout.simple_list_item_1, listedPodsList); // save index and top position - int index = listPods.getFirstVisiblePosition(); - View v = listPods.getChildAt(0); - int top = (v == null) ? 0 : (v.getTop() - listPods.getPaddingTop()); - listPods.setAdapter(adapter); - listPods.setSelectionFromTop(index, top); + int index = listViewPod.getFirstVisiblePosition(); + View v = listViewPod.getChildAt(0); + int top = (v == null) ? 0 : (v.getTop() - listViewPod.getPaddingTop()); + listViewPod.setAdapter(listViewPodAdapter); + listViewPod.setSelectionFromTop(index, top); - adapter.getFilter().filter(editFilter.getText()); - editFilter.addTextChangedListener(new TextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - (adapter).getFilter().filter(s.toString()); - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - public void afterTextChanged(Editable s) { - } - }); + listViewPodAdapter.getFilter().filter(filterString); } - private void showPodConfirmationDialog(final String selectedPod) { - // Make a clickable link - final SpannableString dialogMessage = new SpannableString(getString(R.string.confirm_pod, selectedPod)); - Linkify.addLinks(dialogMessage, Linkify.ALL); - - // Check if online - if (!WebHelper.isOnline(getContext())) { - Snackbar.make(listPods, R.string.no_internet, Snackbar.LENGTH_LONG).show(); - return; - } - - // Show dialog - new AlertDialog.Builder(getContext()) - .setTitle(getString(R.string.confirmation)) - .setMessage(dialogMessage) - .setPositiveButton(android.R.string.yes, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - onPodSelectionConfirmed(selectedPod); - } - }) - .setNegativeButton(android.R.string.no, null) - .show(); - } - - private void onPodSelectionConfirmed(String selectedPod) { - app.getSettings().setPodDomain(selectedPod); - - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - CookieManager.getInstance().removeAllCookies(null); - CookieManager.getInstance().removeSessionCookies(null); - } else { - //noinspection deprecation - CookieManager.getInstance().removeAllCookie(); - //noinspection deprecation - CookieManager.getInstance().removeSessionCookie(); - } - } catch (Exception e) { - e.printStackTrace(); - } - - ((MainActivity)getActivity()).openDiasporaUrl(new DiasporaUrlHelper(appSettings).getPodUrl()); + private void showPodSelectionDialog(final DiasporaPod selectedPod) { + PodSelectionDialog dialog = PodSelectionDialog.newInstance(selectedPod, this); + dialog.show(getFragmentManager(), PodSelectionDialog.TAG); } @Override @@ -238,6 +197,13 @@ public class PodSelectionFragment extends CustomFragment { @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.podselection__menu, menu); + + MenuItem searchItem = menu.findItem(R.id.podselection__action_search); + if (searchItem != null) { + SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); + searchView.setOnQueryTextListener(this); + } + super.onCreateOptionsMenu(menu, inflater); } @@ -245,16 +211,67 @@ public class PodSelectionFragment extends CustomFragment { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_reload: { - if (WebHelper.isOnline(getContext())) { + if (!Helpers.showInfoIfUserNotConnectedToInternet(getContext(), listViewPod)) { Intent i = new Intent(getContext(), GetPodsService.class); getContext().startService(i); return true; - } else { - Snackbar.make(listPods, R.string.no_internet, Snackbar.LENGTH_LONG).show(); - return false; } } } return super.onOptionsItemSelected(item); } -} + + @Override + public boolean onQueryTextChange(String newText) { + if (listViewPodAdapter != null) { + (listViewPodAdapter).getFilter().filter(newText); + } + return true; + } + + @Override + public void onPodSelectionDialogResult(DiasporaPod pod, boolean accepted) { + System.out.println(accepted + ": " + pod.toString()); + if (accepted) { + app.getSettings().setPod(pod); + + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + CookieManager.getInstance().removeAllCookies(null); + CookieManager.getInstance().removeSessionCookies(null); + } else { + //noinspection deprecation + CookieManager.getInstance().removeAllCookie(); + //noinspection deprecation + CookieManager.getInstance().removeSessionCookie(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + MainActivity mainActivity = (MainActivity) getActivity(); + DiasporaUrlHelper urlHelper = new DiasporaUrlHelper(appSettings); + mainActivity.invalidateOptionsMenu(); + mainActivity.openDiasporaUrl(urlHelper.getSignInUrl()); + } + } + + + /* + * Dummy implementations + */ + + @Override + public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) { + } + + @Override + public boolean onQueryTextSubmit(String query) { + return false; + } + + @Override + public boolean onBackPressed() { + return false; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/dfa/diaspora_android/fragment/ThemedFragment.java b/app/src/main/java/com/github/dfa/diaspora_android/fragment/ThemedFragment.java index ca3f3965..96c034b0 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/fragment/ThemedFragment.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/fragment/ThemedFragment.java @@ -29,7 +29,7 @@ import com.github.dfa.diaspora_android.util.theming.ThemeHelper; public abstract class ThemedFragment extends CustomFragment { protected AppSettings getAppSettings() { - return ((App)getActivity().getApplication()).getSettings(); + return ((App) getActivity().getApplication()).getSettings(); } protected abstract void applyColorToViews(); diff --git a/app/src/main/java/com/github/dfa/diaspora_android/receiver/OpenExternalLinkReceiver.java b/app/src/main/java/com/github/dfa/diaspora_android/receiver/OpenExternalLinkReceiver.java index 41ef57a5..add3f685 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/receiver/OpenExternalLinkReceiver.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/receiver/OpenExternalLinkReceiver.java @@ -58,7 +58,7 @@ public class OpenExternalLinkReceiver extends BroadcastReceiver { String sUrl = receiveIntent.getStringExtra(MainActivity.EXTRA_URL); url = Uri.parse(sUrl); } catch (Exception _ignored) { - AppLog.v(this, "Could not open Chrome Custom Tab (bad URL)"); + AppLog.v(this, "Could not open Chrome Custom Tab (bad URL)"); return; } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/task/GetPodsService.java b/app/src/main/java/com/github/dfa/diaspora_android/task/GetPodsService.java index afce5e01..0b6a510b 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/task/GetPodsService.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/task/GetPodsService.java @@ -24,24 +24,24 @@ import android.os.AsyncTask; import android.os.IBinder; import android.support.v4.content.LocalBroadcastManager; +import com.github.dfa.diaspora_android.data.DiasporaPodList; import com.github.dfa.diaspora_android.util.AppLog; -import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; import javax.net.ssl.HttpsURLConnection; import info.guardianproject.netcipher.NetCipher; public class GetPodsService extends Service { + public static final String EXTRA_PODLIST = "pods"; public static final String MESSAGE_PODS_RECEIVED = "com.github.dfa.diaspora.podsreceived"; + public static final String PODDY_PODLIST_URL = "https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/podList/podlist.json"; public GetPodsService() { } @@ -53,75 +53,48 @@ public class GetPodsService extends Service { } private void getPods() { - /* - * Most of the code in this AsyncTask is from the file getPodlistTask.java - * from the app "Diaspora Webclient". - * A few modifications and adaptations were made by me. - * Source: - * https://github.com/voidcode/Diaspora-Webclient/blob/master/src/com/voidcode/diasporawebclient/getPodlistTask.java - * Thanks to Terkel Sørensen ; License : GPLv3 - */ - AsyncTask getPodsAsync = new AsyncTask() { + AsyncTask getPodsAsync = new AsyncTask() { @Override - protected String[] doInBackground(Void... params) { - - // TODO: Update deprecated code - - StringBuilder builder = new StringBuilder(); - //HttpClient client = new DefaultHttpClient(); - List list = null; - HttpsURLConnection connection; - InputStream inStream; + protected DiasporaPodList doInBackground(Void... params) { + StringBuilder sb = new StringBuilder(); + BufferedReader br = null; try { - connection = NetCipher.getHttpsURLConnection("https://podupti.me/api.php?key=4r45tg&format=json"); - int statusCode = connection.getResponseCode(); - if (statusCode == 200) { - inStream = connection.getInputStream(); - BufferedReader reader = new BufferedReader( - new InputStreamReader(inStream)); + HttpsURLConnection con = NetCipher.getHttpsURLConnection(PODDY_PODLIST_URL); + if (con.getResponseCode() == HttpsURLConnection.HTTP_OK) { + br = new BufferedReader(new InputStreamReader(con.getInputStream())); String line; - while ((line = reader.readLine()) != null) { - builder.append(line); + while ((line = br.readLine()) != null) { + sb.append(line); } - try { - inStream.close(); - } catch (IOException e) {/*Nothing to do*/} - - connection.disconnect(); + // Parse JSON & return pod list + JSONObject json = new JSONObject(sb.toString()); + return new DiasporaPodList().fromJson(json); } else { AppLog.e(this, "Failed to download list of pods"); } - } catch (IOException e) { - //TODO handle json buggy feed + } catch (IOException | JSONException e) { e.printStackTrace(); - } - //Parse the JSON Data - try { - JSONObject jsonObjectAll = new JSONObject(builder.toString()); - JSONArray jsonArrayAll = jsonObjectAll.getJSONArray("pods"); - AppLog.d(this, "Number of entries " + jsonArrayAll.length()); - list = new ArrayList<>(); - for (int i = 0; i < jsonArrayAll.length(); i++) { - JSONObject jo = jsonArrayAll.getJSONObject(i); - if (jo.getString("secure").equals("true")) - list.add(jo.getString("domain")); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ignored) { + } } - - } catch (Exception e) { - //TODO Handle Parsing errors here - e.printStackTrace(); } - if (list != null) - return list.toArray(new String[list.size()]); - else - return null; + + // Could not fetch list of pods :( + return new DiasporaPodList(); } @Override - protected void onPostExecute(String[] pods) { + protected void onPostExecute(DiasporaPodList pods) { + if (pods == null) { + pods = new DiasporaPodList(); + } Intent broadcastIntent = new Intent(MESSAGE_PODS_RECEIVED); - broadcastIntent.putExtra("pods", pods != null ? pods : new String[0]); + broadcastIntent.putExtra(EXTRA_PODLIST, pods); LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(broadcastIntent); stopSelf(); } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/task/ImageDownloadTask.java b/app/src/main/java/com/github/dfa/diaspora_android/task/ImageDownloadTask.java index e9b6677f..b7e9ff99 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/task/ImageDownloadTask.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/task/ImageDownloadTask.java @@ -22,12 +22,9 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.support.annotation.Nullable; - -import com.github.dfa.diaspora_android.util.AppLog; -import com.github.dfa.diaspora_android.util.Log; import android.widget.ImageView; -import com.github.dfa.diaspora_android.App; +import com.github.dfa.diaspora_android.util.AppLog; import java.io.FileOutputStream; import java.io.IOException; @@ -80,7 +77,7 @@ public class ImageDownloadTask extends AsyncTask { connection.disconnect(); } catch (Exception e) { - AppLog.e(this, e.getMessage()); + AppLog.e(this, e.getMessage()); } finally { try { if (out != null) { diff --git a/app/src/main/java/com/github/dfa/diaspora_android/task/ProfileFetchTask.java b/app/src/main/java/com/github/dfa/diaspora_android/task/ProfileFetchTask.java index 7d4e70e2..e4b5835b 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/task/ProfileFetchTask.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/task/ProfileFetchTask.java @@ -20,13 +20,11 @@ package com.github.dfa.diaspora_android.task; import android.content.Context; import android.os.AsyncTask; - -import com.github.dfa.diaspora_android.util.AppLog; -import com.github.dfa.diaspora_android.util.Log; import android.webkit.CookieManager; import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.data.PodUserProfile; +import com.github.dfa.diaspora_android.util.AppLog; import com.github.dfa.diaspora_android.util.DiasporaUrlHelper; import java.io.BufferedReader; @@ -62,7 +60,7 @@ public class ProfileFetchTask extends AsyncTask { String extractedProfileData = null; final CookieManager cookieManager = app.getCookieManager(); String cookies = cookieManager.getCookie(urls.getPodUrl()); - AppLog.d(this, cookies); + AppLog.d(this, cookies); HttpsURLConnection connection; InputStream inStream; @@ -88,10 +86,10 @@ public class ProfileFetchTask extends AsyncTask { } } - try{ + try { br.close(); inStream.close(); - } catch (IOException e){/*Nothing*/} + } catch (IOException e) {/*Nothing*/} connection.disconnect(); @@ -103,7 +101,7 @@ public class ProfileFetchTask extends AsyncTask { if (extractedProfileData != null) { PodUserProfile profile = new PodUserProfile(app); profile.parseJson(extractedProfileData); - AppLog.d(this, "Extracted new_messages (service):" + profile.getUnreadMessagesCount()); + AppLog.d(this, "Extracted new_messages (service):" + profile.getUnreadMessagesCount()); } return null; diff --git a/app/src/main/java/com/github/dfa/diaspora_android/task/StatisticsFetchTask.java b/app/src/main/java/com/github/dfa/diaspora_android/task/StatisticsFetchTask.java index 2a82b609..b8b0b0e9 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/task/StatisticsFetchTask.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/task/StatisticsFetchTask.java @@ -20,12 +20,10 @@ package com.github.dfa.diaspora_android.task; import android.content.Context; import android.os.AsyncTask; - -import com.github.dfa.diaspora_android.util.AppLog; -import com.github.dfa.diaspora_android.util.Log; import android.webkit.CookieManager; import com.github.dfa.diaspora_android.App; +import com.github.dfa.diaspora_android.util.AppLog; import com.github.dfa.diaspora_android.util.DiasporaUrlHelper; import java.io.BufferedReader; @@ -79,13 +77,13 @@ public class StatisticsFetchTask extends AsyncTask { BufferedReader br = new BufferedReader(new InputStreamReader(inStream)); String line; while ((line = br.readLine()) != null) { - AppLog.d(this, "STATS: "+line); + AppLog.d(this, "STATS: " + line); } - try{ + try { br.close(); inStream.close(); - } catch (IOException e){/*Nothing*/} + } catch (IOException e) {/*Nothing*/} connection.disconnect(); diff --git a/app/src/main/java/com/github/dfa/diaspora_android/ui/BottomBarBehavior.java b/app/src/main/java/com/github/dfa/diaspora_android/ui/BottomBarBehavior.java index 6e89bfc4..c9648574 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/ui/BottomBarBehavior.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/ui/BottomBarBehavior.java @@ -47,7 +47,7 @@ public class BottomBarBehavior extends CoordinatorLayout.Behavior if (defaultDependencyTop == -1) { defaultDependencyTop = dependency.getTop(); } - if(dependency.getTop()<0) + if (dependency.getTop() < 0) child.setTranslationY(-dependency.getTop() + defaultDependencyTop); else child.setTranslationY(defaultDependencyTop); diff --git a/app/src/main/java/com/github/dfa/diaspora_android/ui/ContextMenuWebView.java b/app/src/main/java/com/github/dfa/diaspora_android/ui/ContextMenuWebView.java index 3be4ce63..6f7ba003 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/ui/ContextMenuWebView.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/ui/ContextMenuWebView.java @@ -217,7 +217,7 @@ public class ContextMenuWebView extends NestedWebView { } } - public void loadUrlNew(String url){ + public void loadUrlNew(String url) { stopLoading(); loadUrl(url); } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/ui/HtmlTextView.java b/app/src/main/java/com/github/dfa/diaspora_android/ui/HtmlTextView.java index 444088a6..9274e701 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/ui/HtmlTextView.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/ui/HtmlTextView.java @@ -64,16 +64,16 @@ public class HtmlTextView extends TextView { /** * Linkify, format markdown and escape the displayed text. */ - private void init(){ + private void init() { formatHtmlAndCustomTags(); } - public void setTextFormatted(String text){ + public void setTextFormatted(String text) { setText(text); formatHtmlAndCustomTags(); } - private void formatHtmlAndCustomTags(){ + private void formatHtmlAndCustomTags() { setText(new SpannableString(Html.fromHtml(getText().toString()))); Linkify.TransformFilter filter = new Linkify.TransformFilter() { public final String transformUrl(final Matcher match, String url) { diff --git a/app/src/main/java/com/github/dfa/diaspora_android/ui/IntellihideToolbarActivityListener.java b/app/src/main/java/com/github/dfa/diaspora_android/ui/IntellihideToolbarActivityListener.java index 61b68a2e..c3fd6406 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/ui/IntellihideToolbarActivityListener.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/ui/IntellihideToolbarActivityListener.java @@ -9,6 +9,8 @@ import android.support.design.widget.AppBarLayout; public interface IntellihideToolbarActivityListener { int toolbarDefaultScrollFlags = AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP; + void enableToolbarHiding(); + void disableToolbarHiding(); } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/ui/PodSelectionDialog.java b/app/src/main/java/com/github/dfa/diaspora_android/ui/PodSelectionDialog.java new file mode 100644 index 00000000..80f0d3f8 --- /dev/null +++ b/app/src/main/java/com/github/dfa/diaspora_android/ui/PodSelectionDialog.java @@ -0,0 +1,195 @@ +package com.github.dfa.diaspora_android.ui; + + +import android.app.Dialog; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatDialogFragment; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.RadioGroup; +import android.widget.Spinner; +import android.widget.TextView; + +import com.github.dfa.diaspora_android.R; +import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod; +import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod.DiasporaPodUrl; + +import org.json.JSONException; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import butterknife.OnItemSelected; + +/** + * Created by gsantner (https://gsantner.github.io) on 06.10.16. + */ +public class PodSelectionDialog extends AppCompatDialogFragment { + public static final String TAG = "com.github.dfa.diaspora_android.PodSelectionDialog"; + + public static interface PodSelectionDialogResultListener { + void onPodSelectionDialogResult(DiasporaPod pod, boolean accepted); + } + + public static PodSelectionDialog newInstance(PodSelectionDialogResultListener resultListener) { + return newInstance(new DiasporaPod(), resultListener); + } + + public static PodSelectionDialog newInstance(DiasporaPod pod, PodSelectionDialogResultListener resultListener) { + PodSelectionDialog dialog = new PodSelectionDialog(); + dialog.setPod(pod); + dialog.setResultListener(resultListener); + return dialog; + } + + /* + // ██████╗ ██╗ █████╗ ██╗ ██████╗ ██████╗ + // ██╔══██╗██║██╔══██╗██║ ██╔═══██╗██╔════╝ + // ██║ ██║██║███████║██║ ██║ ██║██║ ███╗ + // ██║ ██║██║██╔══██║██║ ██║ ██║██║ ██║ + // ██████╔╝██║██║ ██║███████╗╚██████╔╝╚██████╔╝ + // ╚═════╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ + */ + + @BindView(R.id.podselection__dialog__edit_podaddress) + EditText editPodAddress; + + @BindView(R.id.podselection__dialog__edit_podname) + EditText editPodName; + + @BindView(R.id.podselection__dialog__radiogroup_protocol) + RadioGroup radiogrpProtocol; + + @BindView(R.id.podselection__dialog__text_profile) + TextView textProfile; + + @BindView(R.id.podselection__dialog__spinner_profile) + Spinner spinnerProfile; + + private PodSelectionDialogResultListener resultListener; + private View root; + private DiasporaPod pod = new DiasporaPod(); + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + LayoutInflater inflater = getActivity().getLayoutInflater(); + + // Bind UI + root = inflater.inflate(R.layout.podselection__dialog, null); + ButterKnife.bind(this, root); + editPodName.setText(pod.getName()); + List podUrls = pod.getPodUrls(); + if (podUrls.size() > 0) { + uiLoadDiasporaUrl(0); + } + if (podUrls.size() > 1) { + textProfile.setVisibility(View.VISIBLE); + spinnerProfile.setVisibility(View.VISIBLE); + String[] podUrlss = new String[podUrls.size()]; + for (int i = 0; i < podUrls.size(); podUrlss[i] = podUrls.get(i++).getBaseUrl()) ; + ArrayAdapter spinnerAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, podUrlss); + spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinnerProfile.setAdapter(spinnerAdapter); + } + + + builder.setView(root); + return builder.create(); + } + + @OnItemSelected(R.id.podselection__dialog__spinner_profile) + public void spinnerItemSelected(Spinner spinner, int position) { + uiLoadDiasporaUrl(position); + } + + public void uiLoadDiasporaUrl(int wantedPodUrlPos) { + List podUrls = pod.getPodUrls(); + if (podUrls.size() == 0) { + return; + } + wantedPodUrlPos = wantedPodUrlPos < podUrls.size() ? wantedPodUrlPos : 0; + + DiasporaPodUrl url1 = podUrls.get(wantedPodUrlPos); + editPodAddress.setText(url1.getHost()); + radiogrpProtocol.check(url1.getProtocol().equals("https") + ? R.id.podselection__dialog__radio_https : R.id.podselection__dialog__radio_http); + } + + + @OnClick({R.id.podselection__dialog__btn_ok, R.id.podselection__dialog__btn_cancel}) + public void onResultButtonClicked(View view) { + boolean POSITIVE_PRESSED = view.getId() == R.id.podselection__dialog__btn_ok; + if (POSITIVE_PRESSED) { + if (!checkInputs()) { + return; + } + DiasporaPodUrl podUrl = new DiasporaPodUrl(); + if (radiogrpProtocol.getCheckedRadioButtonId() == R.id.podselection__dialog__radio_https) { + podUrl.setHttpsDefaults(); + } else { + podUrl.setHttpDefaults(); + } + podUrl.setHost(editPodAddress.getText().toString()); + pod.setName(editPodName.getText().toString()); + pod.getPodUrls().clear(); + pod.getPodUrls().add(podUrl); + getDialog().dismiss(); + publishResult(POSITIVE_PRESSED); + } else { + getDialog().cancel(); + publishResult(POSITIVE_PRESSED); + } + } + + public boolean checkInputs() { + boolean ok = true; + String s = editPodAddress.getText().toString(); + if (TextUtils.isEmpty(s) || s.length() < 3) { + editPodAddress.setError(getString(R.string.missing_value)); + ok = false; + } + s = editPodName.getText().toString(); + if (TextUtils.isEmpty(s) || s.length() < 3) { + editPodName.setError(getString(R.string.missing_value)); + ok = false; + } + return ok; + } + + public void publishResult(boolean accepted) { + if (resultListener != null) { + resultListener.onPodSelectionDialogResult(pod, accepted); + } + } + + /* + * GETTER & SETTER + */ + public PodSelectionDialogResultListener getResultListener() { + return resultListener; + } + + public void setResultListener(PodSelectionDialogResultListener resultListener) { + this.resultListener = resultListener; + } + + public DiasporaPod getPod() { + return pod; + } + + public void setPod(DiasporaPod pod) { + try { + this.pod = new DiasporaPod().fromJson(pod.toJson()); + } catch (JSONException ignored) { + } + } +} diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/AvatarImageLoader.java b/app/src/main/java/com/github/dfa/diaspora_android/util/AvatarImageLoader.java index eee45f6a..d8857d80 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/AvatarImageLoader.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/AvatarImageLoader.java @@ -16,7 +16,7 @@ If not, see . */ - + package com.github.dfa.diaspora_android.util; import android.content.Context; diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabActivityHelper.java b/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabActivityHelper.java index b515adcc..0429b44b 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabActivityHelper.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabActivityHelper.java @@ -26,7 +26,6 @@ import android.support.customtabs.CustomTabsClient; import android.support.customtabs.CustomTabsIntent; import android.support.customtabs.CustomTabsServiceConnection; import android.support.customtabs.CustomTabsSession; -import android.util.Log; import java.util.List; @@ -43,10 +42,10 @@ public class CustomTabActivityHelper { /** * Opens the URL on a Custom Tab if possible. Otherwise fallsback to opening it on a WebView * - * @param activity The host activity + * @param activity The host activity * @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available - * @param uri the Uri to be opened - * @param fallback a CustomTabFallback to be used if Custom Tabs is not available + * @param uri the Uri to be opened + * @param fallback a CustomTabFallback to be used if Custom Tabs is not available */ public static void openCustomTab(Activity activity, CustomTabsIntent customTabsIntent, @@ -68,6 +67,7 @@ public class CustomTabActivityHelper { /** * Unbinds the Activity from the Custom Tabs Service + * * @param activity the activity that is connected to the service */ public void unbindCustomTabsService(Activity activity) { @@ -93,6 +93,7 @@ public class CustomTabActivityHelper { /** * Register a Callback to be called when connected or disconnected from the Custom Tabs Service + * * @param connectionCallback */ public void setConnectionCallback(ConnectionCallback connectionCallback) { @@ -101,6 +102,7 @@ public class CustomTabActivityHelper { /** * Binds the Activity to the Custom Tabs Service + * * @param activity the activity to be binded to the service */ public void bindCustomTabsService(Activity activity) { @@ -161,9 +163,8 @@ public class CustomTabActivityHelper { */ public interface CustomTabFallback { /** - * * @param activity The Activity that wants to open the Uri - * @param uri The uri to be opened by the fallback + * @param uri The uri to be opened by the fallback */ void openUri(Activity activity, Uri uri); } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabsHelper.java b/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabsHelper.java index c1b9c546..1aa6713f 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabsHelper.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/CustomTabHelpers/CustomTabsHelper.java @@ -26,7 +26,6 @@ import android.content.pm.ResolveInfo; import android.net.Uri; import android.support.customtabs.CustomTabsService; import android.text.TextUtils; -import android.util.Log; import com.github.dfa.diaspora_android.util.AppLog; @@ -47,13 +46,14 @@ public class CustomTabsHelper { private static String sPackageNameToUse; - private CustomTabsHelper() {} + private CustomTabsHelper() { + } /** * Goes through all apps that handle VIEW intents and have a warmup service. Picks * the one chosen by the user if there is one, otherwise makes a best effort to return a * valid package name. - * + *

* This is not threadsafe. * * @param context {@link Context} to use for accessing {@link PackageManager}. @@ -107,6 +107,7 @@ public class CustomTabsHelper { /** * Used to check whether there is a specialized handler for a given intent. + * * @param intent The intent to check with. * @return Whether there is a specialized handler for the given intent. */ @@ -127,7 +128,7 @@ public class CustomTabsHelper { return true; } } catch (RuntimeException e) { - AppLog.e(TAG, "Runtime exception while getting specialized handlers"); + AppLog.e(TAG, "Runtime exception while getting specialized handlers"); } return false; } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/DiasporaUrlHelper.java b/app/src/main/java/com/github/dfa/diaspora_android/util/DiasporaUrlHelper.java index b3c99805..e13eae48 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/DiasporaUrlHelper.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/DiasporaUrlHelper.java @@ -21,6 +21,7 @@ package com.github.dfa.diaspora_android.util; import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.R; import com.github.dfa.diaspora_android.data.AppSettings; +import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod; import com.github.dfa.diaspora_android.data.PodAspect; /** @@ -31,7 +32,6 @@ import com.github.dfa.diaspora_android.data.PodAspect; public class DiasporaUrlHelper { private final AppSettings settings; - public static final String HTTPS = "https://"; public static final String SUBURL_NOTIFICATIONS = "/notifications"; public static final String SUBURL_POSTS = "/posts/"; public static final String SUBURL_STREAM = "/stream"; @@ -49,6 +49,10 @@ public class DiasporaUrlHelper { public static final String SUBURL_FOLOWED_TAGS = "/followed_tags"; public static final String SUBURL_ASPECTS = "/aspects"; public static final String SUBURL_STATISTICS = "/statistics"; + public static final String SUBURL_PERSONAL_SETTINGS = "/user/edit"; + public static final String SUBURL_MANAGE_TAGS = "/tag_followings/manage"; + public static final String SUBURL_SIGN_IN = "/users/sign_in"; + public static final String SUBURL_MANAGE_CONTACTS = "/contacts"; public static final String URL_BLANK = "about:blank"; public DiasporaUrlHelper(AppSettings settings) { @@ -56,17 +60,22 @@ public class DiasporaUrlHelper { } /** - * Return a https url of the pod set in AppSettings. + * Return a url of the pod set in AppSettings. * Eg. https://pod.geraspora.de * * @return https://(pod-domain.tld) */ public String getPodUrl() { - return HTTPS + settings.getPodDomain(); + DiasporaPod pod = settings.getPod(); + if (pod != null) { + return pod.getPodUrl().getBaseUrl(); + } + return "http://127.0.0.1"; + } /** - * Return a https url that points to the stream of the configured diaspora account + * Return a url that points to the stream of the configured diaspora account * * @return https://(pod-domain.tld)/stream */ @@ -75,7 +84,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the notifications feed of the configured diaspora account + * Return a url that points to the notifications feed of the configured diaspora account * * @return https://(pod-domain.tld)/notifications */ @@ -84,7 +93,7 @@ public class DiasporaUrlHelper { } /** - * Returns a https url that points to the post with the id postId + * Returns a url that points to the post with the id postId * * @return https://(pod-domain.tld)/posts/(postId) */ @@ -93,7 +102,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the conversations overview of the registered diaspora account + * Return a url that points to the conversations overview of the registered diaspora account * * @return https://(pod-domain.tld)/conversations */ @@ -102,7 +111,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the new-post form that lets the user create a new post + * Return a url that points to the new-post form that lets the user create a new post * * @return https://(pod-domain.tld)/status_messages/new */ @@ -111,7 +120,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that shows the profile of the currently registered diaspora account + * Return a url that shows the profile of the currently registered diaspora account * * @return https://(pod-domain.tld)/people/(profileId) */ @@ -120,7 +129,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that shows the profile of the user with user id profileId + * Return a url that shows the profile of the user with user id profileId * * @param profileId Id of the profile to be shown * @return https://(pod-domain.tld)/people/(profileId) @@ -130,7 +139,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the activities feed of the currently registered diaspora account + * Return a url that points to the activities feed of the currently registered diaspora account * * @return https://(pod-domain.tld)/activity */ @@ -139,7 +148,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the feed of posts that were liked by the currently registered diaspora account + * Return a url that points to the feed of posts that were liked by the currently registered diaspora account * * @return https://(pod-domain.tld)/liked */ @@ -148,7 +157,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the stream of posts that were commented by the currently registered diaspora account + * Return a url that points to the stream of posts that were commented by the currently registered diaspora account * * @return https://(pod-domain.tld)/commented */ @@ -157,7 +166,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the stream of posts in which the currently registered diaspora account has been mentioned in + * Return a url that points to the stream of posts in which the currently registered diaspora account has been mentioned in * * @return https://(pod-domain.tld)/mentions */ @@ -166,7 +175,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the stream of public posts + * Return a url that points to the stream of public posts * * @return https://(pod-domain.tld)/public */ @@ -175,7 +184,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that toggles between mobile and desktop view when opened + * Return a url that toggles between mobile and desktop view when opened * * @return https://(pod-domain.tld)/mobile/toggle */ @@ -184,7 +193,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that queries posts for the given hashtag query + * Return a url that queries posts for the given hashtag query * * @param query hashtag to be searched * @return https://(pod-domain.tld)/tags/query @@ -194,7 +203,7 @@ public class DiasporaUrlHelper { } /** - * Return a https url that queries user accounts for query + * Return a url that queries user accounts for query * * @param query search term * @return https://(pod-domain.tld)/people.mobile?q=(query) @@ -204,13 +213,50 @@ public class DiasporaUrlHelper { } /** - * Return a https url that points to the statistics page of the pod. + * Return a url that points to the statistics page of the pod. + * * @return https://(pod-domain.tld)/statistics */ public String getStatisticsUrl() { return getPodUrl() + SUBURL_STATISTICS; } + /** + * Return a url that points to the sign in page of the pod. + * + * @return https://(pod-domain.tld)/users/sign_in + */ + public String getSignInUrl() { + return getPodUrl() + SUBURL_SIGN_IN; + } + + /** + * Return a url that points to the personal settings page of the pod. + * + * @return https://(pod-domain.tld)/user/edit + */ + public String getPersonalSettingsUrl() { + return getPodUrl() + SUBURL_PERSONAL_SETTINGS; + } + + /** + * Return a url that points to the manage tags page of the pod. + * + * @return https://(pod-domain.tld)/tag_followings/manage + */ + public String getManageTagsUrl() { + return getPodUrl() + SUBURL_MANAGE_TAGS; + } + + /** + * Return a url that points to the manage tags page of the pod. + * + * @return https://(pod-domain.tld)/contacts + */ + public String getManageContactsUrl() { + return getPodUrl() + SUBURL_MANAGE_CONTACTS; + } + /** * Returns the url of the blank WebView * diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/Helpers.java b/app/src/main/java/com/github/dfa/diaspora_android/util/Helpers.java index 2c4ba62b..68b10dca 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/Helpers.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/Helpers.java @@ -26,8 +26,9 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; +import android.support.design.widget.Snackbar; +import android.view.View; -import com.github.dfa.diaspora_android.App; import com.github.dfa.diaspora_android.R; import java.io.BufferedReader; @@ -72,7 +73,7 @@ public class Helpers { // Create an image file name String timeStamp = new SimpleDateFormat("dd-MM-yy_HH-mm", Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; - AppLog.d(Helpers.class, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()); + AppLog.d(Helpers.class, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()); File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); return new File( @@ -120,18 +121,32 @@ public class Helpers { public static void printBundle(Bundle savedInstanceState, String k) { if (savedInstanceState != null) { for (String key : savedInstanceState.keySet()) { - AppLog.d("SAVED", key + " is a key in the bundle " + k); + AppLog.d("SAVED", key + " is a key in the bundle " + k); Object bun = savedInstanceState.get(key); if (bun != null) { if (bun instanceof Bundle) { printBundle((Bundle) bun, k + "." + key); } else if (bun instanceof byte[]) { - AppLog.d("SAVED", "Key: " + k + "." + key + ": " + Arrays.toString((byte[]) bun)); + AppLog.d("SAVED", "Key: " + k + "." + key + ": " + Arrays.toString((byte[]) bun)); } else { - AppLog.d("SAVED", "Key: " + k + "." + key + ": " + bun.toString()); + AppLog.d("SAVED", "Key: " + k + "." + key + ": " + bun.toString()); } } } } } + + /** + * Show Information if user is offline, returns true if is not connected to internet + * + * @param context Context + * @param anchor A view anchor + */ + public static boolean showInfoIfUserNotConnectedToInternet(Context context, View anchor) { + boolean isOnline = WebHelper.isOnline(context); + if (!isOnline) { + Snackbar.make(anchor, R.string.no_internet, Snackbar.LENGTH_LONG).show(); + } + return !isOnline; + } } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/Log.java b/app/src/main/java/com/github/dfa/diaspora_android/util/Log.java index f8743b1d..2cca9acf 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/Log.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/Log.java @@ -43,8 +43,9 @@ public class Log extends Observable { private Log() { this(null); } + private Log(AppSettings appSettings) { - if(appSettings != null) { + if (appSettings != null) { //TODO: Store/Restore logBuffer between app starts logBuffer = new ArrayList<>(); } else { @@ -55,17 +56,17 @@ public class Log extends Observable { } public static Log getInstance() { - if(instance == null) instance = new Log(); + if (instance == null) instance = new Log(); return instance; } public static Log getInstance(AppSettings appSettings) { - if(instance == null) instance = new Log(appSettings); + if (instance == null) instance = new Log(appSettings); return instance; } private static String time() { - return getInstance().dateFormat.format(new Date())+": "; + return getInstance().dateFormat.format(new Date()) + ": "; } public static void d(String tag, String msg) { @@ -116,23 +117,23 @@ public class Log extends Observable { public synchronized static String getLogBuffer() { String out = ""; - for(String s : getInstance().logBuffer) { + for (String s : getInstance().logBuffer) { out = out + s + "\n"; } return out; } private void notifyLogBufferChanged() { - if(observers == null) return; - for(Observer o : observers) { - if(o != null) { + if (observers == null) return; + for (Observer o : observers) { + if (o != null) { o.update(this, null); } } } private synchronized void addLogEntry(String msg) { - logBuffer.add(time()+msg); + logBuffer.add(time() + msg); while (logBuffer.size() > MAX_BUFFER_SIZE) { logBuffer.remove(0); } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/ProxyHandler.java b/app/src/main/java/com/github/dfa/diaspora_android/util/ProxyHandler.java index a2cbf924..d3ab9711 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/ProxyHandler.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/ProxyHandler.java @@ -46,7 +46,7 @@ public class ProxyHandler { } public static ProxyHandler getInstance() { - if(instance == null) { + if (instance == null) { instance = new ProxyHandler(); } return instance; @@ -77,7 +77,7 @@ public class ProxyHandler { public void addWebView(WebView wv) { AppLog.d(this, "AddWebView"); - if(wv != null && !webViews.contains(wv)) { + if (wv != null && !webViews.contains(wv)) { webViews.add(wv); updateWebViewProxySettings(wv, wv.getContext()); } @@ -89,7 +89,7 @@ public class ProxyHandler { StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy(); StrictMode.ThreadPolicy tmp = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(tmp); - if(appSettings.isProxyEnabled()) { + if (appSettings.isProxyEnabled()) { if (wv != null) { try { WebkitProxy.setProxy(MainActivity.class.getName(), context.getApplicationContext(), wv, appSettings.getProxyHost(), appSettings.getProxyPort()); diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/WebHelper.java b/app/src/main/java/com/github/dfa/diaspora_android/util/WebHelper.java index ba760d7b..21861da6 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/WebHelper.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/WebHelper.java @@ -16,7 +16,7 @@ If not, see . */ - + package com.github.dfa.diaspora_android.util; import android.content.Context; @@ -46,14 +46,14 @@ public class WebHelper { return ni != null && ni.isConnectedOrConnecting(); } - public static String replaceUrlWithMarkdown(String url){ - if( url != null && URLUtil.isHttpUrl(url) || URLUtil.isHttpsUrl(url)){ + public static String replaceUrlWithMarkdown(String url) { + if (url != null && URLUtil.isHttpUrl(url) || URLUtil.isHttpsUrl(url)) { return "<" + url + ">"; } return url; } - public static String escapeHtmlText(String text){ + public static String escapeHtmlText(String text) { text = Html.escapeHtml(text); text = text.replace("\n", " "); return text; @@ -95,7 +95,7 @@ public class WebHelper { "})();"); } - public static void shareTextIntoWebView(final WebView webView, String sharedText){ + public static void shareTextIntoWebView(final WebView webView, String sharedText) { sharedText = sharedText.replace("'", "'").replace("\"", """); webView.loadUrl("javascript:(function() { " + " document.documentElement.style.paddingBottom = '500px';" + @@ -139,16 +139,17 @@ public class WebHelper { // Content AppSettings appSettings = app.getSettings(); + String pod0BaseUrl = appSettings.getPod().getPodUrl().getBaseUrl(); sb.append("»  "); sb.append(String.format(Locale.getDefault(), - "%s", - appSettings.getPodDomain(), app.getString(R.string.all_tags))); + "%s", + pod0BaseUrl, app.getString(R.string.all_tags))); sb.append("


"); - for (String tag: profile.getFollowedTags()) { + for (String tag : profile.getFollowedTags()) { sb.append("»  "); sb.append(String.format(Locale.getDefault(), - "#%s", - appSettings.getPodDomain(), tag, tag)); + "#%s", + pod0BaseUrl, tag, tag)); sb.append("
"); } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ColorPalette.java b/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ColorPalette.java index 16f02b90..160ea719 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ColorPalette.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ColorPalette.java @@ -12,7 +12,7 @@ import com.github.dfa.diaspora_android.R; */ public class ColorPalette { - public static int[] getAccentColors(Context context){ + public static int[] getAccentColors(Context context) { return new int[]{ ContextCompat.getColor(context, R.color.md_red_500), ContextCompat.getColor(context, R.color.md_purple_500), @@ -30,7 +30,7 @@ public class ColorPalette { }; } - public static int getObscuredColor(int c){ + public static int getObscuredColor(int c) { float[] hsv = new float[3]; int color = c; Color.colorToHSV(color, hsv); @@ -39,14 +39,14 @@ public class ColorPalette { return color; } - public static int getTransparentColor(int color, int alpha){ - return ColorUtils.setAlphaComponent(color, alpha); + public static int getTransparentColor(int color, int alpha) { + return ColorUtils.setAlphaComponent(color, alpha); } public static int[] getTransparencyShadows(int color) { int[] shadows = new int[10]; - for (int i=0; i<10;i++) - shadows[i]= (ColorPalette.getTransparentColor(color, ((100-(i*10))*255) /100)); + for (int i = 0; i < 10; i++) + shadows[i] = (ColorPalette.getTransparentColor(color, ((100 - (i * 10)) * 255) / 100)); return shadows; } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ThemeHelper.java b/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ThemeHelper.java index 2900663a..d23c3785 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ThemeHelper.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/util/theming/ThemeHelper.java @@ -47,51 +47,52 @@ public class ThemeHelper { } public static ThemeHelper getInstance(AppSettings appSettings) { - if(instance == null) { + if (instance == null) { instance = new ThemeHelper(appSettings); } return instance; } public static ThemeHelper getInstance() { - if(instance == null) throw new IllegalStateException("ThemeHelper must be initialized using getInstance(AppSettings) before it can be used!"); + if (instance == null) + throw new IllegalStateException("ThemeHelper must be initialized using getInstance(AppSettings) before it can be used!"); return instance; } public static void updateEditTextColor(EditText editText) { - if(editText != null) { + if (editText != null) { editText.setHighlightColor(getInstance().appSettings.getAccentColor()); } } public static void updateCheckBoxColor(CheckBox checkBox) { - if(checkBox != null) { + if (checkBox != null) { checkBox.setHighlightColor(getInstance().appSettings.getAccentColor()); } } public static void updateTabLayoutColor(TabLayout tabLayout) { - if(tabLayout != null) { + if (tabLayout != null) { tabLayout.setBackgroundColor(getInstance().appSettings.getPrimaryColor()); tabLayout.setSelectedTabIndicatorColor(getInstance().appSettings.getAccentColor()); } } public static void updateTextViewColor(TextView textView) { - if(textView != null) { + if (textView != null) { textView.setHighlightColor(getInstance().appSettings.getAccentColor()); textView.setLinkTextColor(getInstance().appSettings.getAccentColor()); } } public static void updateToolbarColor(Toolbar toolbar) { - if(toolbar != null) { + if (toolbar != null) { toolbar.setBackgroundColor(getInstance().appSettings.getPrimaryColor()); } } public static void updateActionMenuViewColor(ActionMenuView actionMenuView) { - if(actionMenuView != null) { + if (actionMenuView != null) { actionMenuView.setBackgroundColor(getInstance().appSettings.getPrimaryColor()); } } @@ -105,7 +106,7 @@ public class ThemeHelper { } public static void setPrimaryColorAsBackground(View view) { - if(view != null) { + if (view != null) { view.setBackgroundColor(getPrimaryColor()); } } @@ -115,13 +116,13 @@ public class ThemeHelper { } public static void updateActionBarColor(ActionBar actionBar) { - if(actionBar != null) { + if (actionBar != null) { actionBar.setBackgroundDrawable(new ColorDrawable(getInstance().appSettings.getPrimaryColor())); } } public static void updateProgressBarColor(ProgressBar progressBar) { - if(progressBar != null && progressBar.getProgressDrawable() != null) { + if (progressBar != null && progressBar.getProgressDrawable() != null) { progressBar.getProgressDrawable().setColorFilter(getAccentColor(), PorterDuff.Mode.SRC_IN); } } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/webview/CustomWebViewClient.java b/app/src/main/java/com/github/dfa/diaspora_android/webview/CustomWebViewClient.java index 914abcbb..beb85d19 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/webview/CustomWebViewClient.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/webview/CustomWebViewClient.java @@ -19,7 +19,6 @@ package com.github.dfa.diaspora_android.webview; import android.content.Intent; -import android.net.Uri; import android.support.v4.content.LocalBroadcastManager; import android.webkit.CookieManager; import android.webkit.WebView; @@ -39,7 +38,7 @@ public class CustomWebViewClient extends WebViewClient { //Open non-diaspora links in customtab/external browser public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (!url.contains(app.getSettings().getPodDomain())) { + if (!url.contains(app.getSettings().getPod().getPodUrl().getHost())) { Intent i = new Intent(MainActivity.ACTION_OPEN_EXTERNAL_URL); i.putExtra(MainActivity.EXTRA_URL, url); LocalBroadcastManager.getInstance(app.getApplicationContext()).sendBroadcast(i); @@ -57,7 +56,7 @@ public class CustomWebViewClient extends WebViewClient { if (cookies != null) { cookieManager.setCookie(url, cookies); - cookieManager.setCookie("https://" + app.getSettings().getPodDomain(), cookies); + cookieManager.setCookie(app.getSettings().getPod().getPodUrl().getBaseUrl(), cookies); //for (String c : cookies.split(";")) { //AppLog.d(this, "Cookie: " + c.split("=")[0] + " Value:" + c.split("=")[1]); //} diff --git a/app/src/main/java/com/github/dfa/diaspora_android/webview/DiasporaStreamWebChromeClient.java b/app/src/main/java/com/github/dfa/diaspora_android/webview/DiasporaStreamWebChromeClient.java index f3572e97..1efaadb9 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/webview/DiasporaStreamWebChromeClient.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/webview/DiasporaStreamWebChromeClient.java @@ -39,7 +39,7 @@ public class DiasporaStreamWebChromeClient extends FileUploadWebChromeClient { @Override public void onProgressChanged(WebView wv, int progress) { super.onProgressChanged(wv, progress); - if (progress > 0 && progress <= 60) { + if (progress > 10 && progress <= 60) { WebHelper.getUserProfile(wv); WebHelper.optimizeMobileSiteLayout(wv); } @@ -57,6 +57,7 @@ public class DiasporaStreamWebChromeClient extends FileUploadWebChromeClient { public interface SharedTextCallback { String getSharedText(); + void setSharedText(String shared); } } diff --git a/app/src/main/java/com/github/dfa/diaspora_android/webview/FileUploadWebChromeClient.java b/app/src/main/java/com/github/dfa/diaspora_android/webview/FileUploadWebChromeClient.java index a730182e..5e714211 100644 --- a/app/src/main/java/com/github/dfa/diaspora_android/webview/FileUploadWebChromeClient.java +++ b/app/src/main/java/com/github/dfa/diaspora_android/webview/FileUploadWebChromeClient.java @@ -42,8 +42,7 @@ public class FileUploadWebChromeClient extends ProgressBarWebChromeClient { //For Android 4.1/4.2 only. DO NOT REMOVE! @SuppressWarnings("unused") - protected void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) - { + protected void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) { fileUploadCallback.legacyImageUpload(uploadMsg, acceptType, capture); } @@ -54,6 +53,7 @@ public class FileUploadWebChromeClient extends ProgressBarWebChromeClient { public interface FileUploadCallback { boolean imageUpload(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams); + void legacyImageUpload(ValueCallback uploadMsg, String acceptType, String capture); } } diff --git a/app/src/main/res/layout/about__activity.xml b/app/src/main/res/layout/about__activity.xml index 6e17bd47..6f0f2006 100644 --- a/app/src/main/res/layout/about__activity.xml +++ b/app/src/main/res/layout/about__activity.xml @@ -1,6 +1,5 @@ - + android:layout_height="wrap_content" /> + android:layout_height="wrap_content" /> diff --git a/app/src/main/res/layout/about__fragment_about.xml b/app/src/main/res/layout/about__fragment_about.xml index d67ec343..6283eee7 100644 --- a/app/src/main/res/layout/about__fragment_about.xml +++ b/app/src/main/res/layout/about__fragment_about.xml @@ -19,16 +19,16 @@ + android:textAlignment="center" /> + android:layout_height="wrap_content" /> + android:linksClickable="true" + android:text="@string/fragment_about__about_content" />
diff --git a/app/src/main/res/layout/about__fragment_debug.xml b/app/src/main/res/layout/about__fragment_debug.xml index de397350..bde176a9 100644 --- a/app/src/main/res/layout/about__fragment_debug.xml +++ b/app/src/main/res/layout/about__fragment_debug.xml @@ -20,74 +20,77 @@ + android:text="@string/fragment_debug__section_app" /> + android:layout_height="wrap_content" /> + android:layout_height="wrap_content" /> + android:text="@string/fragment_debug__section_device" /> + android:layout_height="wrap_content" /> + android:layout_height="wrap_content" /> + android:text="@string/fragment_debug__section_pod" /> + android:layout_height="wrap_content" /> + android:text="@string/fragment_debug__section_log" /> + + + + android:longClickable="true" /> diff --git a/app/src/main/res/layout/about__fragment_license.xml b/app/src/main/res/layout/about__fragment_license.xml index 12b319c0..5b8360d4 100644 --- a/app/src/main/res/layout/about__fragment_license.xml +++ b/app/src/main/res/layout/about__fragment_license.xml @@ -16,32 +16,33 @@ + + android:text="@string/fragment_license__copyright_years" /> + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:linksClickable="true" + android:text="@string/fragment_license__license_content" /> + android:text="@string/fragment_license__3rd_party_libs_title" /> diff --git a/app/src/main/res/layout/browser__fragment.xml b/app/src/main/res/layout/browser__fragment.xml index 2ecf4791..9a6c941d 100644 --- a/app/src/main/res/layout/browser__fragment.xml +++ b/app/src/main/res/layout/browser__fragment.xml @@ -1,6 +1,5 @@ - @@ -15,6 +14,6 @@ android:layout_width="fill_parent" android:layout_height="7dp" android:indeterminate="false" - android:progressDrawable="@drawable/progressbar"/> + android:progressDrawable="@drawable/progressbar" /> \ No newline at end of file diff --git a/app/src/main/res/layout/color_picker__dialog.xml b/app/src/main/res/layout/color_picker__dialog.xml index 53a0a4d2..26223ed4 100644 --- a/app/src/main/res/layout/color_picker__dialog.xml +++ b/app/src/main/res/layout/color_picker__dialog.xml @@ -1,35 +1,38 @@ + android:layout_height="match_parent" + android:orientation="vertical"> + + + android:layout_margin="20dp" + android:textAppearance="@style/TextAppearance.AppCompat.Large.Inverse" /> + + android:layout_marginTop="20dp" + app:orientation="horizontal" /> + + android:layout_marginTop="30dp" + app:orientation="horizontal" /> \ No newline at end of file diff --git a/app/src/main/res/layout/hashtag_list__fragment.xml b/app/src/main/res/layout/hashtag_list__fragment.xml index 94df572b..7ca77b13 100644 --- a/app/src/main/res/layout/hashtag_list__fragment.xml +++ b/app/src/main/res/layout/hashtag_list__fragment.xml @@ -1,27 +1,30 @@ + android:layout_height="match_parent"> + + + + android:scrollbars="vertical" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + android:layout_height="@dimen/bottom_toolbar_height" /> \ No newline at end of file diff --git a/app/src/main/res/layout/main__activity.xml b/app/src/main/res/layout/main__activity.xml index 7de0204c..eeaeebec 100644 --- a/app/src/main/res/layout/main__activity.xml +++ b/app/src/main/res/layout/main__activity.xml @@ -19,10 +19,10 @@ android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" - app:itemTextColor="@color/primary_text" - app:paddingEnd="0dp" - app:paddingStart="0dp" app:headerLayout="@layout/main__nav_header" - app:menu="@menu/main__navdrawer" /> + app:itemTextColor="@color/primary_text" + app:menu="@menu/main__navdrawer" + app:paddingEnd="0dp" + app:paddingStart="0dp" /> diff --git a/app/src/main/res/layout/main__app_bar.xml b/app/src/main/res/layout/main__app_bar.xml index c81b49ae..225de964 100644 --- a/app/src/main/res/layout/main__app_bar.xml +++ b/app/src/main/res/layout/main__app_bar.xml @@ -1,6 +1,5 @@ - + app:popupTheme="@style/AppTheme.PopupOverlay" /> @@ -27,7 +26,7 @@ android:id="@+id/fragment_container" android:layout_width="fill_parent" android:layout_height="fill_parent" - app:layout_behavior="@string/appbar_scrolling_view_behavior"/> + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + app:popupTheme="@style/Theme.AppCompat.NoActionBar" /> diff --git a/app/src/main/res/layout/main__nav_header.xml b/app/src/main/res/layout/main__nav_header.xml index dfd33c01..3b90f95b 100644 --- a/app/src/main/res/layout/main__nav_header.xml +++ b/app/src/main/res/layout/main__nav_header.xml @@ -3,18 +3,18 @@ android:id="@+id/nav_drawer" android:layout_width="wrap_content" android:layout_height="110dp" + android:background="@color/colorPrimary" android:gravity="bottom" android:orientation="vertical" - android:background="@color/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +