Introduce new markdown parser;

Rework existing md files;
Show changelog/update dialog
This commit is contained in:
Gregor Santner 2017-03-25 16:45:32 +01:00
parent 8d6b09c800
commit 101c5f5b7d
16 changed files with 397 additions and 134 deletions

View File

@ -1,4 +1,13 @@
# v0.2.4
### v0.2.5 WIP
- Introduce minimalistic Markdown Parser
- Show LICENSE at first start
- Show CHANGELOG after update
- Convert existing Markup files to Markdown
- Update existing markdown files
- Update AboutActivity to use new Parser
- Added Korean and Danish as translation options
### v0.2.4 (2017-03-19)
- Different icon and color for secondlion
- Language switcher
- Handle dia.so links
@ -7,13 +16,13 @@
- Update gradle build scripts
- Added CircleCI
# v0.2.3
### v0.2.3 (2017-02-24)
- Add Czech translation (thanks @bezcitu)
- Add option to copy image urls to clipboard
- Fixed some bugs related to image upload/download
- Published secondlion\* (nighly version of dandelion\*)
# v0.2.2
### v0.2.2
- Move "toggle mobile/deskop" to nav-slider
- Reduce messages sent via broadcast
- Allow to jump to last visited page on stream
@ -23,14 +32,14 @@
- FIX #92 Roation settings
- FIX #111 Remove legacy code
# v0.2.1
### v0.2.1
- App name changed to **dandelion***
- Rotation options
- Top toolbar loads screen again (toggleable in settings)
- Fixed overlapping fragments
- Visual rework of the About-section of the app
# v0.2.0a
### v0.2.0a
- Added: Customizable Theme Colors!
- Improved account setup with easy tor hidden service configuration
- Eye candy for the settings activity
@ -39,7 +48,7 @@
- Lots of bugfixes
- Fixes for the bugfixes!
# v0.1.6
### v0.1.6
- Added: New languages
- Changed: New delicious visual style + launcher icon
- Changed: Notifications-/Messages-indicator does now display number of events!
@ -51,7 +60,7 @@
- Fixed: Image upload for older devices
- Added: Option to open external links in Chrome CustomTab
# v0.1.5
### v0.1.5
- Update title depending on what the user is doing
- New greenish color scheme
- Replaced SwipeToRefresh functionality with refresh button
@ -66,7 +75,7 @@
- Allow slider customization
- Show aspect name after selection
# v0.1.4 (2016-07-31)
### v0.1.4 (2016-07-31)
- by @vanitasvitae, @gsantner, @di72nn
- Allow turning off toolbar intellihide
- Handle links from browseable intent filter #38
@ -81,7 +90,7 @@
- Share screenshot fix; Minor Aspects rework
- Update to SDK 24 (Android N)
# v0.1.3 (2016-07-04)
### v0.1.3 (2016-07-04)
- Added titles on top toolbar (by @scoute-dich)
- Made bottom toolbar automatically disappear
- Added option to share images to external app
@ -92,7 +101,7 @@
- Removed swipe-to-refresh functionality in some places
- Big thanks and good luck to @scoute-dich and @martinchodev for accompanying this project :)
# v0.1.2 (2016-06-05)
### v0.1.2 (2016-06-05)
- Extract and show aspects (by @gsantner)
- Cache last podlist
- Better sharing from app
@ -105,7 +114,7 @@
- Lots of refactoring; Reworked Splash,PodSelectionActivity; Switch Pod; Clear settings;
- Activity transitions, usability MainActivity, green accent color
# v0.1.1
### v0.1.1
- Sharing updated (by @scoute-dich)
- Screenshotting updated
- Gitter integration (by @gsantner)
@ -115,8 +124,8 @@
- Travis CI integration
- Bump Gradle, Build-Tools, Libs to Android Studio 2.1 defaults
# v0.1.0 (Diaspora for Android)
First version of the organization *Diaspora for Android*
### v0.1.0 (Diaspora for Android)
First version of the organization *Diaspora for Android*
Consists mostly of code from:
- Diaspora-Native-Webapp (by @martinchodev )
- scoutedich additions (by @scoute-dich)

View File

@ -1,22 +1,25 @@
# App
This program is free software: you can redistribute it and/or modify
# dandelion\*
`---------------`
<small>This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see https://www.gnu.org/licenses/.
along with this program. If not, see https://www.gnu.org/licenses/.</small>
`---------------`
If you want to publish dandelion\* in an app store, you have to change the app name (dandelion\*), package name & (blue) launcher icon. See "7. Additional Terms" of GPL. You also have to provide the modifications in source code somewhere online for free. This is explicitly not about building the app and sharing with some friends, it's about app stores. F-Droid is explicitly allowed to publish as dandelion\*. The reason is, that most app stores allow an app id just once, which would block our uploads if somebody else uploaded. Also, we want to keep control on where the app is published, and want to make sure there is no malware in it.
If you want to publish dandelion\* in an app store, you have to change the app name (dandelion\*), package name & launcher icon (blue). See "7. Additional Terms" of GPL.
You also have to provide the modifications in source code somewhere online for free. This is explicitly not about building the app and sharing with some friends, it's about app stores.
The reason is, that most app stores allow an app id just once, which would block our uploads if somebody else uploaded. Also, we want to keep control on where the app is published, and want to make sure there is no malware in it.
The F-Droid project team is explicitly allowed to publish dandelion\* without listed required modifications above at official F-Droid repository.
# Miscellaneous
## Miscellaneous
We took some inspiration and code from LeafPic. Go check it out, its free software as well!
https://github.com/HoraApps/LeafPic
<https://github.com/HoraApps/LeafPic>

View File

@ -1,6 +1,6 @@
[![F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdid=com.github.dfa.diaspora_android)
<a name="badgers"></a>[![Build Status](https://travis-ci.org/Diaspora-for-Android/dandelion.svg?branch=master)](https://travis-ci.org/Diaspora-for-Android/dandelion)
<a name="badgers"></a>[![CircleCI](https://circleci.com/gh/Diaspora-for-Android/dandelion.svg?style=shield)](https://circleci.com/gh/Diaspora-for-Android/dandelion)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/diaspora-for-android/localized.svg)](https://crowdin.com/project/diaspora-for-android)
[![Chat - Matrix](https://img.shields.io/badge/chat-on%20matrix-blue.svg)](https://matrix.to/#/#dandelion:matrix.org)
@ -9,19 +9,19 @@
# dandelion\*
FORMERLY KNOWN AS DIASPORA-FOR-ANDROID
This is an unofficial webview based client for the community-run, distributed social network **[diaspora*](https://diasporafoundation.org/)**. It's currently under development and should be used with that in mind. Please submit any bugs you might find.
This is an unofficial webview based client for the community-run, distributed social network **[diaspora*](https://diasporafoundation.org/)**. It's currently under development and should be used with that in mind. Please submit any bugs you might find.
- Download latest release on ([F-Droid](https://f-droid.org/repository/browse/?fdid=com.github.dfa.diaspora_android)
- Download latest development version (nightly): [secondlion\*](https://gsantner.gitlab.io/fdroid/latest/com.github.dfa.secondlion.apk)
- Download latest release on ([F-Droid](https://f-droid.org/repository/browse/?fdid=com.github.dfa.diaspora_android))
- Download latest nightly - [secondlion\*](https://gsantner.gitlab.io/fdroid/latest/com.github.dfa.secondlion.apk)
- Watch [Changelog](https://github.com/Diaspora-for-Android/dandelion/blob/master/CHANGELOG.md)
- See [Screenshots](https://github.com/Diaspora-for-Android/dandelion/blob/master/SCREENSHOTS.md)
- Get updates from our diaspora\* account: [dandelion00@diasp.org](https://diasp.org/people/48b78420923501341ef3782bcb452bd5)
## Contributions
We are always open for any kind of contribution. (PR's, bug reports, feature requests, translations, ..)
We are always open for any kind of contribution. (PR's, bug reports, feature requests, translations, ..)
If you got any questions feel free to contact us on IRC, XMPP or Gitter. You can start chatting by clicking on the [blue chat badges](#badgers) listed on top.
We use Crowdin to translate dandelion\*. Join our project here: <https://crowdin.com/project/diaspora-for-android/invite>. If your desired language is not listed please contact the maintainers/owner.
We use Crowdin to translate dandelion\*. Join our project here: <https://crowdin.com/project/diaspora-for-android/invite>. If your desired language is not listed please contact the maintainers/owner.
Note that the main project members are working on this project for free during leisure time, are mostly busy with their job/university/school, and may not react or start coding immediately.
@ -29,10 +29,10 @@ Note that the main project members are working on this project for free during l
dandelion\* is released under GNU GENERAL PUBLIC LICENSE (see [LICENCE](https://github.com/Diaspora-for-Android/dandelion/blob/master/LICENSE.md)).
### WebApp
The app is developed as a WebApp because currently diaspora\* doesn't have an API that can be used to create a native interface to retrieve the user's data, publications, direct messages and so on. That's why there are only WebApps for diaspora\* out there.
The app is developed as a WebApp because currently diaspora\* doesn't have an API that can be used to create a native interface to retrieve the user's data, publications, direct messages and so on. That's why there are only WebApps for diaspora\* out there.
[Stay tuned on diaspora\* issues](https://github.com/diaspora/diaspora/labels/api) about API.
Why is a WebApp better than using the mobile site on a browser?
Why is a WebApp better than using the mobile site on a browser?
Basically it provides better integration with the system (events coming into and going out of the app), notifications, customized interface and functions and a nice little icon that takes you directly to your favorite social network :)
### Device Requirements
@ -42,7 +42,7 @@ The minimum Android version supported is Jelly Bean, Android v4.2.0 / API 17
dandelion\* requires access to the Internet and to external storage to be able to upload photos when creating a new post and for taking screenshots.
## Maintainers
- gsantner ([GitHub](https://github.com/gsantner), [Web](https://gsantner.github.io), [diaspora*](https://pod.geraspora.de/people/d1cbdd70095301341e834860008dbc6c))
- Bitcoin: [1B9ZyYdQoY9BxMe9dRUEKaZbJWsbQqfXU5](https://gsantner.github.io/donate/#donate)
- gsantner ([GitHub](https://github.com/gsantner), [Web](https://gsantner.github.io), [diaspora*](https://pod.geraspora.de/people/d1cbdd70095301341e834860008dbc6c))
- Bitcoin: [1B9ZyYdQoY9BxMe9dRUEKaZbJWsbQqfXU5](https://gsantner.github.io/donate/#donate)
- vanitasvitae ([GitHub](https://github.com/vanitasvitae), [diaspora*](https://pod.geraspora.de/people/bbd7af90fbec013213e34860008dbc6c))
- Bitcoin: 1Ao3W6NaQv3xKppviB7RSFKjHo6PGd8RTy
- Bitcoin: 1Ao3W6NaQv3xKppviB7RSFKjHo6PGd8RTy

View File

@ -265,9 +265,12 @@ public class AboutActivity extends ThemedActivity
final Context context = rootView.getContext();
accentColor = Helpers.colorToHex(ThemeHelper.getAccentColor());
maintainers.setTextFormatted(getString(R.string.fragment_license__maintainers_text, getMaintainersHtml(context)));
contributors.setTextFormatted(getString(R.string.fragment_license__contributors_thank_you, getContributorsHtml(context)));
thirdPartyLibs.setTextFormatted(getLicense3dPartyHtml(context));
maintainers.setTextFormatted(getString(R.string.fragment_license__maintainers_text,
Helpers.loadMarkdownFromRawForTextView(context, R.raw.maintainers, "")));
contributors.setTextFormatted(getString(R.string.fragment_license__contributors_thank_you,
Helpers.loadMarkdownFromRawForTextView(context, R.raw.contributors, "* ")));
thirdPartyLibs.setTextFormatted(
Helpers.loadMarkdownFromRawForTextView(context, R.raw.license_third_party, ""));
return rootView;
}
@ -283,25 +286,6 @@ public class AboutActivity extends ThemedActivity
}
}
public String getContributorsHtml(Context context) {
return Helpers.readTextfileFromRawRessource(context, R.raw.contributors,
"<font color='" + accentColor + "'><b>*</b></font> ", "<br>");
}
public String getMaintainersHtml(Context context) {
String text = Helpers.readTextfileFromRawRessource(context, R.raw.maintainers, "", "<br>");
text = text
.replace("NEWENTRY", "<font color='" + accentColor + "'><b>*</b></font> ")
.replace("SUBTABBY", "&nbsp;&nbsp;");
return text;
}
public String getLicense3dPartyHtml(Context context) {
String text = Helpers.readTextfileFromRawRessource(context, R.raw.license_third_party, "", "<br>");
text = text.replace("NEWENTRY", "<font color='" + accentColor + "'><b>*</b></font> ");
return text;
}
@Override
protected void applyColorToViews() {
ThemeHelper.getInstance(getAppSettings());

View File

@ -76,12 +76,16 @@ import com.github.dfa.diaspora_android.ui.theme.ThemedAlertDialogBuilder;
import com.github.dfa.diaspora_android.util.AppLog;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.DiasporaUrlHelper;
import com.github.dfa.diaspora_android.util.Helpers;
import com.github.dfa.diaspora_android.util.SimpleMarkdownParser;
import com.github.dfa.diaspora_android.web.BrowserFragment;
import com.github.dfa.diaspora_android.web.ContextMenuWebView;
import com.github.dfa.diaspora_android.web.ProxyHandler;
import com.github.dfa.diaspora_android.web.WebHelper;
import com.github.dfa.diaspora_android.web.custom_tab.CustomTabActivityHelper;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
@ -212,6 +216,30 @@ public class MainActivity extends ThemedActivity
openDiasporaUrl(urls.getStreamUrl());
}
}
// Show first start dialog
try {
if (appSettings.isAppFirstStart()) {
SimpleMarkdownParser smp = new SimpleMarkdownParser().parse(
getResources().openRawResource(R.raw.license),
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, "");
String html = smp.getHtml()
+ "<br/><br/><br/>"
+ "<h1>" + getString(R.string.fragment_license__thirdparty_libs) + "</h1>"
+ smp.parse(getResources().openRawResource(R.raw.license_third_party),
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, "");
html = smp.setHtml(html).removeMultiNewlines().getHtml();
Helpers.showDialogWithHtmlTextView(this, html, R.string.about_activity__title_about_license);
appSettings.isAppCurrentVersionFirstStart();
} else if (appSettings.isAppCurrentVersionFirstStart()) {
SimpleMarkdownParser smp = new SimpleMarkdownParser().parse(
getResources().openRawResource(R.raw.changelog),
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, "");
Helpers.showDialogWithHtmlTextView(this, smp.getHtml(), R.string.changelog);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
@ -244,14 +272,14 @@ public class MainActivity extends ThemedActivity
moveTaskToBack(true);
}
});
snackbarLastVisitedTimestampInStream =
Snackbar.make(fragmentContainer,
R.string.jump_to_last_visited_timestamp_in_stream, Snackbar.LENGTH_LONG)
.setAction(android.R.string.yes, new View.OnClickListener() {
public void onClick(View view) {
openDiasporaUrl(urls.getStreamWithTimestampUrl(diasporaUserProfile.getLastVisitedPositionInStream()));
}
});
snackbarLastVisitedTimestampInStream =
Snackbar.make(fragmentContainer,
R.string.jump_to_last_visited_timestamp_in_stream, Snackbar.LENGTH_LONG)
.setAction(android.R.string.yes, new View.OnClickListener() {
public void onClick(View view) {
openDiasporaUrl(urls.getStreamWithTimestampUrl(diasporaUserProfile.getLastVisitedPositionInStream()));
}
});
snackbarNoInternet = Snackbar.make(fragmentContainer, R.string.no_internet, Snackbar.LENGTH_LONG);
// Load app settings
@ -392,8 +420,7 @@ public class MainActivity extends ThemedActivity
app.getAvatarImageLoader().startImageDownload(navheaderImage, avatarUrl);
}
}
}
else if (BuildConfig.IS_TEST_BUILD){
} else if (BuildConfig.IS_TEST_BUILD) {
navheaderImage.setImageResource(R.drawable.ic_launcher_test);
}
updateNavigationViewEntryVisibilities();

View File

@ -122,7 +122,7 @@ public class AppSettings {
return pref.getString(context.getString(ressourceId), context.getString(ressourceIdDefaultValue));
}
private boolean getBoolean(SharedPreferences pref, int ressourceId, boolean defaultValue) {
private boolean getBool(SharedPreferences pref, int ressourceId, boolean defaultValue) {
return pref.getBoolean(context.getString(ressourceId), defaultValue);
}
@ -164,7 +164,7 @@ public class AppSettings {
}
public boolean isLoadImages() {
return getBoolean(prefApp, R.string.pref_key__load_images, true);
return getBool(prefApp, R.string.pref_key__load_images, true);
}
public int getMinimumFontSize() {
@ -277,7 +277,7 @@ public class AppSettings {
}
public boolean isAppendSharedViaApp() {
return getBoolean(prefApp, R.string.pref_key__append_shared_via_app, true);
return getBool(prefApp, R.string.pref_key__append_shared_via_app, true);
}
@SuppressLint("CommitPrefEdits")
@ -293,7 +293,7 @@ public class AppSettings {
*/
public boolean isProxyHttpEnabled() {
try {
return getBoolean(prefApp, R.string.pref_key__http_proxy_enabled, false);
return getBool(prefApp, R.string.pref_key__http_proxy_enabled, false);
} catch (ClassCastException e) {
setProxyHttpEnabled(false);
return false;
@ -301,7 +301,7 @@ public class AppSettings {
}
public boolean wasProxyEnabled() {
return getBoolean(prefApp, R.string.pref_key__proxy_was_enabled, false);
return getBool(prefApp, R.string.pref_key__proxy_was_enabled, false);
}
/**
@ -353,81 +353,92 @@ public class AppSettings {
}
public boolean isIntellihideToolbars() {
return getBoolean(prefApp, R.string.pref_key__intellihide_toolbars, true);
return getBool(prefApp, R.string.pref_key__intellihide_toolbars, true);
}
public boolean isChromeCustomTabsEnabled() {
return getBoolean(prefApp, R.string.pref_key__chrome_custom_tabs_enabled, true);
return getBool(prefApp, R.string.pref_key__chrome_custom_tabs_enabled, true);
}
public boolean isLoggingEnabled() {
return getBoolean(prefApp, R.string.pref_key__logging_enabled, false);
return getBool(prefApp, R.string.pref_key__logging_enabled, false);
}
public boolean isLoggingSpamEnabled() {
return getBoolean(prefApp, R.string.pref_key__logging_spam_enabled, false);
return getBool(prefApp, R.string.pref_key__logging_spam_enabled, false);
}
public boolean isVisibleInNavExit() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__exit, false);
return getBool(prefApp, R.string.pref_key__visibility_nav__exit, false);
}
public boolean isVisibleInNavHelp_license() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__help_license, true);
return getBool(prefApp, R.string.pref_key__visibility_nav__help_license, true);
}
public boolean isVisibleInNavPublic_activities() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__public_activities, false);
return getBool(prefApp, R.string.pref_key__visibility_nav__public_activities, false);
}
public boolean isVisibleInNavMentions() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__mentions, false);
return getBool(prefApp, R.string.pref_key__visibility_nav__mentions, false);
}
public boolean isVisibleInNavCommented() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__commented, true);
return getBool(prefApp, R.string.pref_key__visibility_nav__commented, true);
}
public boolean isVisibleInNavLiked() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__liked, true);
return getBool(prefApp, R.string.pref_key__visibility_nav__liked, true);
}
public boolean isVisibleInNavActivities() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__activities, true);
return getBool(prefApp, R.string.pref_key__visibility_nav__activities, true);
}
public boolean isVisibleInNavAspects() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__aspects, true);
return getBool(prefApp, R.string.pref_key__visibility_nav__aspects, true);
}
public boolean isVisibleInNavFollowed_tags() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__followed_tags, true);
return getBool(prefApp, R.string.pref_key__visibility_nav__followed_tags, true);
}
public boolean isVisibleInNavProfile() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__profile, true);
return getBool(prefApp, R.string.pref_key__visibility_nav__profile, true);
}
public boolean isVisibleInNavContacts() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__contacts, false);
return getBool(prefApp, R.string.pref_key__visibility_nav__contacts, false);
}
public boolean isVisibleInNavReports() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__reports, false);
return getBool(prefApp, R.string.pref_key__visibility_nav__reports, false);
}
public boolean isVisibleToggleMobileDesktop() {
return getBoolean(prefApp, R.string.pref_key__visibility_nav__toggle_mobile_desktop, false);
return getBool(prefApp, R.string.pref_key__visibility_nav__toggle_mobile_desktop, false);
}
public boolean isTopbarStreamShortcutEnabled() {
return getBoolean(prefApp, R.string.pref_key__topbar_stream_shortcut, false);
return getBool(prefApp, R.string.pref_key__topbar_stream_shortcut, false);
}
public String getScreenRotation() {
return getString(prefApp, R.string.pref_key__screen_rotation, R.string.rotation_val_system);
}
public boolean isAppFirstStart(){
boolean value = getBool(prefApp, R.string.pref_key__app_first_start, true);
setBool(prefApp, R.string.pref_key__app_first_start, false);
return value;
}
public boolean isAppCurrentVersionFirstStart(){
int value = getInt(prefApp, R.string.pref_key__app_first_start_current_version, -1);
setInt(prefApp, R.string.pref_key__app_first_start_current_version, BuildConfig.VERSION_CODE);
return value != BuildConfig.VERSION_CODE && !BuildConfig.IS_TEST_BUILD;
}
public long getLastVisitedPositionInStream() {
return getLong(prefPod, R.string.pref_key__podprofile_last_stream_position, -1);
@ -479,6 +490,6 @@ public class AppSettings {
}
public boolean isExtendedNotificationsActivated() {
return getBoolean(prefApp, R.string.pref_key__extended_notifications, false);
return getBool(prefApp, R.string.pref_key__extended_notifications, false);
}
}

View File

@ -18,7 +18,6 @@
*/
package com.github.dfa.diaspora_android.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@ -26,11 +25,21 @@ import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.RawRes;
import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.util.TypedValue;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.web.WebHelper;
@ -44,17 +53,6 @@ import java.util.Date;
import java.util.Locale;
public class Helpers {
public static void animateToActivity(Activity from, Class to, boolean finishFromActivity) {
Intent intent = new Intent(from, to);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
from.startActivity(intent);
from.overridePendingTransition(R.anim.fadein, R.anim.fadeout);
if (finishFromActivity) {
from.finish();
}
}
public static int getColorFromRessource(Context context, int ressourceId) {
Resources res = context.getResources();
if (Build.VERSION.SDK_INT >= 23) {
@ -64,14 +62,6 @@ public class Helpers {
}
}
public static void loadUrlInExternalBrowser(Context context, String url) {
try {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(browserIntent);
} catch (Exception ignored) {
}
}
public static File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("dd-MM-yy_HH-mm", Locale.getDefault()).format(new Date());
@ -123,8 +113,41 @@ public class Helpers {
return sb.toString();
}
public static String hexColorFromRessourceColor(Context context, int idColor) {
return "#" + Integer.toHexString(context.getResources().getColor(idColor) & 0x00ffffff);
public static String loadMarkdownFromRawForTextView(Context context, @RawRes int rawMdFile, String prepend) {
try {
return new SimpleMarkdownParser()
.parse(context.getResources().openRawResource(rawMdFile),
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, prepend)
.replaceColor("#000001", ContextCompat.getColor(context, R.color.accent))
.removeMultiNewlines().replaceBulletCharacter("*").getHtml();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
public static void showDialogWithHtmlTextView(Context context, String html, @StringRes int resTitleId) {
LinearLayout layout = new LinearLayout(context);
TextView textView = new TextView(context);
textView.setMovementMethod(LinkMovementMethod.getInstance());
ScrollView root = new ScrollView(context);
int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20,
context.getResources().getDisplayMetrics());
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
layoutParams.setMargins(margin, 0, margin, 0);
layout.setLayoutParams(layoutParams);
layout.addView(textView);
root.addView(layout);
textView.setText(new SpannableString(Html.fromHtml(html)));
AlertDialog.Builder dialog = new AlertDialog.Builder(context)
.setPositiveButton(android.R.string.ok, null)
.setTitle(resTitleId)
.setView(root);
dialog.show();
}
public static String colorToHex(int color) {

View File

@ -0,0 +1,202 @@
/*
* ----------------------------------------------------------------------------
* "THE COKE-WARE LIBRARY LICENSE" (Revision 255):
* Gregor Santner <gsantner.github.io> wrote this file. You can do whatever
* you want with this stuff. If we meet some day, and you think this stuff is
* worth it, you can buy me a coke in return. Provided as is without any kind
* of warranty. No attribution required. - Gregor Santner
* ----------------------------------------------------------------------------
*/
package com.github.dfa.diaspora_android.util;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* Simple Markdown Parser
* <p>
* Parses most common markdown tags. Only inline tags are supported, multiline/block syntax
* is not supported (citation, multiline code, ..). This is intended to stay as easy as possible.
* <p>
* You can e.g. apply a accent color by replacing #000001 with your accentColor string.
* <p>
* FILTER_ANDROID_TEXTVIEW output is intended to be used at simple Android TextViews,
* were a limited set of html tags is supported. This allow to still display e.g. a simple
* CHANGELOG.md file without inlcuding a WebView for showing HTML, or other additional UI-libraries.
* <p>
* FILTER_HTMLPART is intended to be used at engines understanding most common HTML tags.
* <p>
* You can use this anywhere you want, no backlink/attribution required, but I would appreciate it.
*/
@SuppressWarnings({"WeakerAccess", "CaughtExceptionImmediatelyRethrown"})
public class SimpleMarkdownParser {
public interface SimpleLineFilter {
String filterLine(String line);
}
public static final SimpleLineFilter FILTER_ANDROID_TEXTVIEW = new SimpleLineFilter() {
@Override
public String filterLine(String line) {
// TextView supports a limited set of html tags, most notably
// a href, b, big, font size&color, i, li, small, u
line = line
.replace("", "&nbsp;&nbsp;") // double space/half tab
.replaceAll("^### ([^<]*)", "<br/><big><b><font color='#000000'>$1</font></b></big> ") // h3
.replaceAll("^## ([^<]*)", "<br/><big><big><b><font color='#000000'>$1</font></b></big></big><br/> ") // h2 (DEP: h3)
.replaceAll("^# ([^<]*)", "<br/><big><big><big><b><font color='#000000'>$1</font></b></big></big></big><br/> ") // h1 (DEP: h2,h3)
.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // img
.replaceAll("\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // a href (DEP: img)
.replaceAll("<(http|https):\\/\\/(.*)>", "<a href='$1://$2'>$1://$2</a>") // a href (DEP: img)
.replaceAll("^(-|\\*) ([^<]*)", "<font color='#000001'>&#8226;</font> $2 ") // unordered list + end line
.replaceAll("^ (-|\\*) ([^<]*)", "&nbsp;&nbsp;<font color='#000001'>&#8226;</font> $2 ") // unordered list2 + end line
.replaceAll("`([^<]*)`", "<font face='monospace'>$1</font>") // code
.replace("\\*", "") // temporary replace escaped star symbol
.replaceAll("\\*\\*([^<]*)\\*\\*", "<b>$1</b>") // bold (DEP: temp star)
.replaceAll("\\*([^<]*)\\*", "<i>$1</i>") // italic (DEP: temp star code)
.replace("", "*") // restore escaped star symbol (DEP: b,i)
.replaceAll(" $", "<br/>") // new line (DEP: ul)
;
return line.isEmpty() ? line + "<br/>" : line;
}
};
public static final SimpleLineFilter FILTER_HTMLPART = new SimpleLineFilter() {
@Override
public String filterLine(String line) {
line = line
.replaceAll("", "&nbsp;&nbsp;") // double space/half tab
.replaceAll("^### ([^<]*)", "<h3>$1</h3>") // h3
.replaceAll("^## ([^<]*)", "<h2>$1</h2>") /// h2 (DEP: h3)
.replaceAll("^# ([^<]*)", "<h1>$1</h1>") // h1 (DEP: h2,h3)
.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "<img src=\\'$2\\' alt='$1' />") // img
.replaceAll("<(http|https):\\/\\/(.*)>", "<a href='$1://$2'>$1://$2</a>") // a href (DEP: img)
.replaceAll("\\[(.*?)\\]\\((.*?)\\)", "<a href=\\'$2\\'>$1</a>") // a href (DEP: img)
.replaceAll("^(-|\\*) ([^<]*)", "<font color='#000001'>&#8226;</font> $2 ") // unordered list + end line
.replaceAll("^ (-|\\*) ([^<]*)", "&nbsp;&nbsp;<font color='#000001'>&#8226;</font> $2 ") // unordered list2 + end line
.replaceAll("`([^<]*)`", "<code>$1</code>") // code
.replace("\\*", "") // temporary replace escaped star symbol
.replaceAll("\\*\\*([^<]*)\\*\\*", "<b>$1</b>") // bold (DEP: temp star)
.replaceAll("\\*([^<]*)\\*", "<b>$1</b>") // italic (DEP: temp star)
.replace("", "*") // restore escaped star symbol (DEP: b,i)
.replaceAll(" $", "<br/>") // new line (DEP: ul)
;
return line.isEmpty() ? line + "<br/>" : line;
}
};
//########################
//##
//## Members
//##
//########################
private String html;
public SimpleMarkdownParser parse(String filepath, SimpleLineFilter simpleLineFilter) throws IOException {
return parse(new FileInputStream(filepath), simpleLineFilter, "");
}
public SimpleMarkdownParser parse(InputStream inputStream, SimpleLineFilter simpleLineFilter, String lineMdPrefix) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
String line;
try {
br = new BufferedReader(new InputStreamReader(inputStream));
while ((line = br.readLine()) != null) {
sb.append(simpleLineFilter.filterLine(lineMdPrefix + line));
sb.append("\n");
}
} catch (IOException rethrow) {
html = "";
throw rethrow;
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
html = sb.toString().trim();
return this;
}
public String getHtml() {
return html;
}
public SimpleMarkdownParser setHtml(String html) {
this.html = html;
return this;
}
public SimpleMarkdownParser removeMultiNewlines() {
html = html.replace("\n", "").replaceAll("(<br/>){3,}", "<br/><br/>");
return this;
}
public SimpleMarkdownParser replaceBulletCharacter(String replacment) {
html = html.replace("&#8226;", replacment);
return this;
}
public SimpleMarkdownParser replaceColor(String hexColor, int newIntColor) {
html = html.replace(hexColor, colorToHexString(newIntColor));
return this;
}
public static String colorToHexString(int intColor) {
return String.format("#%06X", 0xFFFFFF & intColor);
}
@Override
public String toString() {
return html != null ? html : "";
}
}
/*
// Apply to Android TextView:
textView.setText(new SpannableString(Html.fromHtml(htmlFromParser)));
// As wrapper method, includes applying accent color
public static String loadMarkdownFromRawForTextView(Context context, @RawRes int rawMdFile, String prepend) {
try {
return new SimpleMarkdownParser()
.parse(context.getResources().openRawResource(rawMdFile),
SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, prepend)
.replaceColor("#000001", ContextCompat.getColor(context, R.color.accent))
.removeMultiNewlines().replaceBulletCharacter("*").getHtml();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
// Show HTML a TextView in a scrollable Dialog
public static void showDialogWithHtmlTextView(Context context, String html, @StringRes int resTitleId) {
LinearLayout layout = new LinearLayout(context);
TextView textView = new TextView(context);
textView.setMovementMethod(LinkMovementMethod.getInstance());
ScrollView root = new ScrollView(context);
int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20,
context.getResources().getDisplayMetrics());
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
layoutParams.setMargins(margin, 0, margin, 0);
layout.setLayoutParams(layoutParams);
layout.addView(textView);
root.addView(layout);
textView.setText(new SpannableString(Html.fromHtml(html)));
AlertDialog.Builder dialog = new AlertDialog.Builder(context)
.setPositiveButton(android.R.string.ok, null)
.setTitle(resTitleId)
.setView(root);
dialog.show();
}
*/

View File

@ -0,0 +1,14 @@
* NetCipher
<https://github.com/guardianproject/NetCipher>
* ButterKnife
<https://jakewharton.github.io/butterknife>
* ShiftColorPicker
<https://github.com/DASAR/ShiftColorPicker>
* Android Support Library
<https://developer.android.com/topic/libraries/support-library/index.html>
* Android Design Library
<https://android-developers.blogspot.de/2015/05/android-design-support-library.html>

View File

@ -1,14 +0,0 @@
NEWENTRY NetCipher
https://github.com/guardianproject/NetCipher
NEWENTRY ButterKnife
https://jakewharton.github.io/butterknife
NEWENTRY ShiftColorPicker
https://github.com/DASAR/ShiftColorPicker
NEWENTRY Android Support Library
https://developer.android.com/topic/libraries/support-library/index.html
NEWENTRY Android Design Library
https://android-developers.blogspot.de/2015/05/android-design-support-library.html

View File

@ -0,0 +1,5 @@
* Gregor Santner (gsantner)
~° https://gsantner.github.io
* Paul Schaub (vanitasvitae)
~° https://github.com/vanitasvitae

View File

@ -1,5 +0,0 @@
NEWENTRY Gregor Santner (gsantner)
SUBTABBY https://gsantner.github.io
NEWENTRY Paul Schaub (vanitasvitae)
SUBTABBY https://github.com/vanitasvitae

View File

@ -15,6 +15,8 @@
<string name="pref_key__http_proxy_load_tor_preset" translatable="false">pref_key__http_proxy_load_tor_preset</string>
<string name="pref_key__extended_notifications" translatable="false">pref_key__extended_notifications</string>
<string name="pref_key__topbar_stream_shortcut" translatable="false">pref_key__topbar_stream_shortcut</string>
<string name="pref_key__app_first_start" translatable="false">pref_key__app_first_start</string>
<string name="pref_key__app_first_start_current_version" translatable="false">pref_key__app_first_start_current_version</string>
<!-- Themes -->
<string name="pref_key__primary_color__preference_click" translatable="false">@string/pref_key__primary_color_shade</string>

View File

@ -27,6 +27,7 @@
<string name="public_">Public</string>
<string name="search">Search</string>
<string name="contacts">Contacts</string>
<string name="changelog">Changelog</string>
<string name="tor" translatable="false">Tor</string>
<!-- Notifications dropdown menu -->

View File

@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong

View File

@ -1,5 +1,5 @@
files:
-
-
source: '/app/src/main/res/values/strings*.xml'
translation: '/app/src/main/res/values-%android_code%/%original_file_name%'
languages_mapping:
@ -18,6 +18,7 @@ files:
nl: nl # Dutch
hu: hu # Hungarian
cs: cs # Czech
ko: ko # Korean
# hi: hi # Hindi
# el: el # Greel
# "no": 'no' # Norwegian