1
0
Fork 0
mirror of https://github.com/gsantner/dandelion synced 2025-09-10 02:39:43 +02:00

Compare commits

..

No commits in common. "master" and "v0.2.0" have entirely different histories.

324 changed files with 4992 additions and 21581 deletions

View file

@ -1,23 +0,0 @@
.git
.github
.gradle
.idea
build
gradle
.gitlab-ci.yml
*.iml
local.properties
settings.gradle
gradlew
gradlew.bat
LICENSE.md
app/build
app/.gitignore
app/pom.xml
app/proguard-rules.pro
.hidden
.travis.yml
circle.yml
CODE_OF_CONDUCT*
gradle.properties
LICENSE*

View file

@ -1,24 +1,51 @@
#### General information
* **App version:**
* **System:**
* **Pod:**
#### Description
* **Device:** <!-- eg Nexus 5 -->
* **Android Version:** <!--eg Android 6.0.1 -->
* **App version:** <!-- See in About -> Debug. eg 0.1.5, or commit -->
* **App source:** <!--F-Droid, self build (latest HEAD) -- Can be left blank if not related -->
* **Pod:** <!--eg pod.geraspora.de -- Can be left blank if not related -->
* **Diaspora pod version:** <!--eg 0.5.99.0-p9bd2337c (can be found on the bottom) -- Can be left blank if not related -->
#### Log
<!--
Look for already reported issues before posting!
Also take a look at documentation and wiki, or write in the project chat.
I have:
App version: The version of the app installed and the installation source. Example: v0.3.5 F-Droid
Please keep in mind that only the latest downloadable version is supported and that there are no backports to older versions.
System: Information about where the app is running. Give all details you know, but at least the Android OS version.
Example: Android 8.0.1, Nexus 5, LineageOS
Description:
What this is about, what happens and what is expected to happen. What needs to be done for it to happen.
If a crash is happening a log is needed. Screenshots or demonstration videos are always helpful too.
- searched open and closed issues for duplicates
- read <https://github.com/Diaspora-for-Android/diaspora-android/blob/master/CONTRIBUTING.md>
- not submitted translations - see [Crowdin](https://crowdin.com/project/diaspora-for-android/invite)
-->
#### Steps to reproduce
1. …
2. …
3. …
#### Expected result
**What is the expected output?**
**What do you see instead?**
Upload screenshots via drag&drop if needed and apply resizing:
`<img width="30%" height="30%" src="https://cloud.githubusercontent.com/assets/67..b55.jpg">`
#### Debug output
Please post the output of adb logcat. The log should begin with the start of Diaspora for Android and include all the steps it takes to reproduce the problem.
````
adb logcat -s com.github.dfa.diaspora_android
````
#### In-App debug log
This is useful for visual bugs without application crashes
````
You can long click on the in-app debug log in order to copy it to the clipboard
````

View file

@ -1,27 +0,0 @@
<!--
Hello, and thanks for contributing!
Please always do auto-reformat on code before creating a PR.
In Android-Studio do a right-click on java->Reformat and check the first two options.
After creating the PR please wait patiently till somebody from the team has time to give a review.
The top-priority requirement for this to get merged is, that building/tests don't fail.
If theres an continious integration system integrated in this project, you should see a colored checkmark in the PR window which tells the status.
## Contributors document
Add yourself! When adding your information to the `CONTRIBUTORS.md` file, please use the following format:
Schema: **[Name](Reference)**<br/>~° Text
Where:
* Name: username, first/lastname
* Reference: E-Mail, Webpage
* Text: Information about / kind of contribution
Example:
* **[Nice Guy](http://niceguy.web)**<br/>~° German localization
-->

View file

@ -1,68 +0,0 @@
##############################################################################################################################
# # Cleanup:
#const sleep = ms => () => new Promise((resolve, reject) => window.setTimeout(resolve, ms));
#Promise.resolve()
#.then(() => { document.getElementsByClassName("details-overlay details-reset position-relative d-inline-block ")[3].children[0].click(); })
#.then(sleep(500))
#.then(() => { document.getElementsByClassName("dropdown-item btn-link menu-item-danger")[0].click(); })
#.then(sleep(1000))
#.then(() => { document.getElementsByClassName("btn btn-block btn-danger")[0].click();});
#
# while [ 1 ] ; do sleep 4; xdotool key Up; sleep 0.1; xdotool key Return; done
##############################################################################################################################
name: "CI"
on: [push, pull_request]
jobs:
build:
if: "!contains(github.event.head_commit.message, 'ci skip') && (!contains(github.event_name, 'pull_request') || (contains(github.event_name, 'pull_request') && github.event.pull_request.head.repo.full_name != github.repository))"
runs-on: ubuntu-latest
steps:
- name: "Checkout: Code"
uses: actions/checkout@v2
- name: "Checkout: Code (PR)"
uses: actions/checkout@v2
if: "contains(github.event_name, 'pull_request')"
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: "Setup: Java"
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: "Cache: Gradle"
uses: actions/cache@v2
with:
path: |
~/.gradle
.gradle
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('gradle/wrapper/gradle-wrapper.*') }}
- name: "Build: Project with make"
run: make clean all
- name: "Build: List dist files"
if: always()
run: find dist -type f -maxdepth 2
- name: "Artifacts: All"
if: always()
uses: actions/upload-artifact@v2.2.1
with:
name: "all"
path: dist
retention-days: 5
- name: "Artifacts: Android APK"
uses: actions/upload-artifact@v2.2.1
with:
name: "android-apk"
path: |
dist/*.apk

21
.gitignore vendored
View file

@ -1,3 +1,12 @@
##############
### Project ##
app/src/main/res/raw/changelog.md
app/src/main/res/raw/contributors.md
app/src/main/res/raw/license.md
app/src/main/res/raw/readme.md
app/src/main/res/raw/contributors.txt
app/src/main/res/raw/podlist.json
##############
### Common ###
*~*
@ -36,7 +45,6 @@ tmp/
### Gradle ###
.gradle
build/
dist/
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
@ -91,14 +99,3 @@ proguard/
# Android Studio Stuff
.navigation/
gen-external-apklibs
### Project ##
app/src/main/res/raw/changelog.*
app/src/main/res/raw/license.*
app/src/main/res/raw/readme.*
app/src/main/res/raw/contributors.*
app/flavor*
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

35
.travis.yml Normal file
View file

@ -0,0 +1,35 @@
language: android
jdk:
- oraclejdk8
android:
components:
- tools
- tools # TODO https://github.com/travis-ci/travis-ci/issues/6193
- platform-tools
- build-tools-24.0.3
- android-24
- extra-android-m2repository
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
script: "./gradlew $TASK"
env:
- TASK="lintDebug"
- TASK="build check --stacktrace"
branches:
except:
- l10n_master
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/e462044d3105a7bb4b4f
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: never # options: [always|never|change] default: always
after_success:
- bash <(curl -s https://codecov.io/bash)

View file

@ -1,141 +1,4 @@
### Recent changes
- See [Discussions](https://github.com/gsantner/dandelion/discussions), [Issues](https://github.com/gsantner/dandelion/issues) and [Project page](https://github.com/gsantner/dandelion#readme) to see what is going on.
### v1.4.0
- Add seconds to 'save picture' date format
- Updated translations
- Added german F-Droid description translation
- Update to Android SDK 29
### v1.3.0
- Add option to open youtube links external/in YouTube app (optional)
- Pull to refresh
### v1.2.3
**Improved:**
- More supported languages, more complete translations!
### v1.2.1
**App release: dandelior**
- Added an (rebranded) flavor of dandelion: dandelior
- Only differenties in use are other (black) icon and AMOLED colors by default enabled
- Already available on F-Droid
**New features:**
- All new Aspects and Tags, using a searchable dialog
**Fixed:**
- Sometimes the Stream went white, which is due an still (>3 years) unfixed Android Support library bug. It should not occur very often anymore due less use of fragments.
**Improved:**
- Various small tweaks
- Updated translation files
### v1.1.3
- Improve sharing *a lot*, add support for multiple filetypes
- Support for downloading GIFs ;)
- Rework screenshot saving and sharing; add new share options:
- Merge license and changelog dialog on first start
### v1.1.2
- Fix: loading non-pod links outside customtab/external browser
- Fix: webview-js dialog not dismissing correctly
### v1.1.0
- Added: App shortcuts (Android 7+)
- Updated: podlist
- More supported languages
- File sharing fixes
### v1.0.8
- Modified: Navigation - Merge bottom toolbar into top
- Updated: Build for Android O/27
- Updated: Language change preference
- Added: B/W coloring of toolbar popup
### v1.0.5
- Updated: Language preference
### v1.0.4
- Updated: README
- Added: Hide statusbar option
- Fixed: Language list
- Added: Sardinian,Malayalam,Turkish translation
### v1.0.3
- Update opoc
- Better visibility for counter badge
- Refactor DiasporaPod model
- Update PodList (many new pods!)
- Fix CustomTab bug
### v1.0.2 (2017-08-05)
- Improve build script
- Update translation file license
### v1.0.1 (2017-07-30)
- Update SimpleMarkdownParser
- Move untranslatable strings
### v1.0.0 (2017-06-14)
- Added AMOLED mode
- Improve NavDrawer
- Improve Shared by notice
- Use opoc/Helpers,AdBlock
### v0.2.7 (2017-05-26)
- Small improvements
### v0.2.6 (2017-05-03)
- Fixed #156 #158 #159
- Added chinese traditional language
- Added NavSlider option: Statistics
- Changed shared-by-notice text
- Fix bottom bar hint text background color (Fix #157)
- Color improvements
### v0.2.5 (2017-04-10)
- 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 translations: Danish, Korean, Galician
### v0.2.4 (2017-03-19)
- Different icon and color for secondlion
- Language switcher
- Handle dia.so links
- Improve security at internal browser decision
- More icons for notification dropdown
- Update gradle build scripts
- Added CircleCI
### 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
- Move "toggle mobile/deskop" to nav-slider
- Reduce messages sent via broadcast
- Allow to jump to last visited page on stream
- New language: Hungarian
- FIX NullPtr in shared text methods
- FIX #117 - Reset NavHeader on change account, reset web profile
- FIX #92 Roation settings
- FIX #111 Remove legacy code
### 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.0
- Added: Customizable Theme Colors!
- Improved account setup with easy tor hidden service configuration
- Eye candy for the settings activity
@ -144,7 +7,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!
@ -156,7 +19,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
@ -171,7 +34,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
@ -186,7 +49,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
@ -197,7 +60,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
@ -210,7 +73,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)
@ -220,8 +83,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,74 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <gsantner AT mailbox DOT org>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

6
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,6 @@
We are always open for any kind of contribution. (PR's, bug reports, feature requests, translations, ..)
If you got any questions feel free to join our XMPP/Jabber conference at `diaspora-android@conference.jabberhead.tk` or [Gitter](https://gitter.im/Diaspora-for-Android/diaspora-android).
Note that the main project members are mostly busy with their job/university/school and may not react or start coding immediately.
We use Crowdin to translate Diaspora for Android. Join our project here: <https://crowdin.com/project/diaspora-for-android/invite>
If your desired language is not listed please contact the maintainers/owner.

View file

@ -1,32 +0,0 @@
<!--
This file contains references to people who contributed to the app.
Schema: **[Name](Reference)**<br/>~° Text
Where:
* Name: username, first/lastname
* Reference: E-Mail, Webpage
* Text: Information about / kind of contribution
## LIST OF CONTRIBUTORS
-->
* **[Gregor Santner](http://github.com/gsantner)**<br/>~° Development of dandelion
* **[Paul Schaub](https://github.com/vanitasvitae)**<br/>~° Development of dandelion
* **[Martín Vukovic](martinvukovic AT protonmail DOT com)**<br/>~° Diaspora Native WebApp
* **[Gaukler Faun](https://github.com/scoute-dich)**<br/>~° Diaspora Native WebApp additions
* **[Airon90](https://diasp.eu/u/airon90)**<br/>~° Italian translation
* **[Nacho Fernández](nacho_f AT joindiaspora DOT com)**<br/>~° Spanish translation
* **[Naofumi Fukue](https://github.com/naofum)**<br/>~° Japanese translation
* **[pskosinski](email AT pskosinski DOT pl)**<br/>~° Polish translation
* **[SansPseudoFix](https://github.com/SansPseudoFix)**<br/>~° French translation
* **[Zsolt Szakács](maxigaz AT diaspora DOT zone)**<br/>~° Hungarian translation
* **[Luís F.S. Rosa](https://github.com/luisfsr)**<br/>~° Brazilian Portuguese translation
* **[Danilo Raffaelli](https://crowdin.com/profile/Daraf)**<br/>~° Italian translation
* **[Âng Iōngchun](https://pubpod.alqualonde.org/u/iongchun)**<br/>~° Chinese traditional translation
* **[Mikkel Kirkgaard Nielsen](http://www.mikini.dk)**<br/>~° Danish translation
* **[Jean Lucas](jean AT 4ray DOT co)**<br/>~° Spanish translation
* **[asereze](https://github.com/asereze)**<br/>~° Sardinian translation
* **[Xosé M. Lamas](http://xmgz.eu)**<br />~° Galician translation
* **[massimiliano](https://framagit.org/massimiliano)**<br />~° Contributor

17
CONTRIBUTORS.txt Normal file
View file

@ -0,0 +1,17 @@
00l>> This file contains references to people who contributed to the app.
01l>> If you helped by translating the app, please send a message on Crowdin.
02l>> You can also send a mail to [gdev AT live DOT de](https://gsantner.github.io/about/email/) to get included.
03l>>
04l>> Schemes:
05l>> Firstname Lastname (Link): Text
06l>> Firstname Lastname (E-Mail): Text
07l>> Username (Link): Text
08l>> Username (E-Mail): Text
## 99l CONTRIBUTORS
Abhijith Balan (abhijithb21 AT openmailbox DOT org): Malayalam translation
Airon90 (https://diasp.eu/u/airon90): Italian translation
Gaukler Faun (https://github.com/scoute-dich): Diaspora Native WebApp additions
Martín Vukovic (martinvukovic AT protonmail DOT com): Diaspora Native WebApp
Nacho Fernández (nacho_f AT joindiaspora DOT com): Spanish translation
pskosinski (email AT pskosinski DOT pl): Polish translation
SansPseudoFix (https://github.com/SansPseudoFix): French translation

View file

@ -1,25 +1,20 @@
# dandelion\*
`---------------`
<small>This program is free software: you can redistribute it and/or modify
# App
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/.</small>
`---------------`
along with this program. If not, see https://www.gnu.org/licenses/.
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,99 +0,0 @@
# License of Makefile: Public Domain / CC0
.PHONY: $(shell sed -n -e '/^$$/ { n ; /^[^ .\#][^ ]*:/ { s/:.*$$// ; p ; } ; }' $(MAKEFILE_LIST))
.NOTPARALLEL: clean
.DEFAULT_GOAL := all
env-%:
@: $(if ${${*}},,$(error Environment variable $* not set))
####################################################################################
DIST_DIR = dist
MOVE = mv
all: $(DIST_DIR) spellcheck lint deptree test build aapt_dump_badging
####################################################################################
$(DIST_DIR):
mkdir -p ${DIST_DIR}
ANDROID_BUILD_TOOLS := $(shell test -n "$ANDROID_SDK_ROOT" && find "${ANDROID_SDK_ROOT}/build-tools" -iname "aapt" | sort -r | head -n1 | xargs dirname)
TOOL_SPELLCHECKING_ISPELL := $(shell command -v ispell 2> /dev/null)
FLAVOR := $(or ${FLAVOR},${FLAVOR},Atest)
.NOTPARALLEL: gradle gradle-analyze-log
gradle: env-ANDROID_SDK_ROOT
mkdir -p $(DIST_DIR)/log/
chmod +x gradlew
./gradlew --no-daemon --parallel --stacktrace $A 2>&1 | tee "$(DIST_DIR)/log/gradle.log"
@echo "-----------------------------------------------------------------------------------"
gradle-analyze-log:
mv "$(DIST_DIR)/log/gradle.log" "$(DIST_DIR)/log/gradle$A.log"
cat "$(DIST_DIR)/log/gradle$A.log" | grep "BUILD " | tail -n1 | grep -q "BUILD SUCCESSFUL in"
adb: env-ANDROID_SDK_ROOT
"${ANDROID_SDK_ROOT}/platform-tools/adb" $A 2>&1 | tee "$(DIST_DIR)/log/adb-$L.log"
aapt: env-ANDROID_SDK_ROOT
"${ANDROID_BUILD_TOOLS}/aapt" $A 2>&1 | grep -v 'application-label-' | tee "$(DIST_DIR)/log/aapt$L.log"
build:
rm -f $(DIST_DIR)/*.apk
$(MAKE) A="clean assembleFlavor$(FLAVOR) -x lint" gradle
find app -type f -newermt '-300 seconds' -iname '*.apk' -not -iname '*unsigned.apk' | xargs cp -R -t $(DIST_DIR)/
$(MAKE) A="-build" gradle-analyze-log
lint:
rm -Rf $(DIST_DIR)/lint
mkdir -p $(DIST_DIR)/lint/
$(MAKE) A="lintFlavorDefaultDebug" gradle
find app -type f -iname 'lint-results-*' | grep -v 'intermediates' | xargs cp -R -t $(DIST_DIR)/lint
$(MAKE) A="-lint" gradle-analyze-log
test:
rm -Rf $(DIST_DIR)/tests
$(MAKE) A="testFlavorDefaultDebugUnitTest -x lint" gradle
mkdir -p app/build/test-results/testFlavorDefaultDebugUnitTest && echo 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHRlc3RzdWl0ZSBuYW1lPSJkdW1teSIgdGVzdHM9IjEiIHNraXBwZWQ9IjAiIGZhaWx1cmVzPSIwIiBlcnJvcnM9IjAiIHRpbWVzdGFtcD0iMjAyMC0xMi0wOFQwMDowMDowMCIgaG9zdG5hbWU9ImxvY2FsaG9zdCIgdGltZT0iMC4wMSI+CiAgPHByb3BlcnRpZXMvPgogIDx0ZXN0Y2FzZSBuYW1lPSJkdW1teSIgY2xhc3NuYW1lPSJkdW1teSIgdGltZT0iMC4wMSIvPgogIDxzeXN0ZW0tb3V0PjwhW0NEQVRBW11dPjwvc3lzdGVtLW91dD4KICA8c3lzdGVtLWVycj48IVtDREFUQVtdXT48L3N5c3RlbS1lcnI+CjwvdGVzdHN1aXRlPgo=' | base64 -d > 'app/build/test-results/testFlavorDefaultDebugUnitTest/TEST-dummy.xml'
find app -type d -iname 'testFlavorDefaultDebugUnitTest' | xargs cp -R -t $(DIST_DIR)/
mv ${DIST_DIR}/testFlavorDefaultDebugUnitTest $(DIST_DIR)/tests
$(MAKE) A="-test" gradle-analyze-log
deptree:
$(MAKE) A="app:dependencies --configuration flavor$(FLAVOR)DebugRuntimeClasspath" gradle
$(MAKE) A="-dependency-tree" gradle-analyze-log
clean:
$(MAKE) A="clean" gradle
rm -Rf $(DIST_DIR) app/build app/flavor* .idea dist
find . -type f -iname "*.iml" -delete
$(MAKE) $(DIST_DIR)
@echo "-----------------------------------------------------------------------------------"
install:
$(MAKE) A="install -r $(DIST_DIR)/*.apk" L="install" adb
run:
$(MAKE) A="shell monkey -p $$(aapt dump badging $(DIST_DIR)/*.apk | grep package: | sed 's@.* name=@@' | sed 's@ .*@@' | xargs | head -n1) -c android.intent.category.LAUNCHER 1" L="run" adb
aapt_dump_badging:
$(MAKE) A="dump badging $(DIST_DIR)/*.apk" aapt
@echo "-----------------------------------------------------------------------------------"
spellcheck:
mkdir -p "$(DIST_DIR)/lint/"
ifndef TOOL_SPELLCHECKING_ISPELL
@echo "Tool ispell (spellcheck) not found in PATH. Spellcheck skipped." > "$(DIST_DIR)/lint/stringsxml-spellcheck.txt"
else
@echo "Use ispell for spellchecking the original values/strings.xml"
find . -iname "strings.xml" -path "*/main*/values/*" | head -n1 | xargs cat \
| grep "<string name=" | sed 's@.*">@@' | sed 's@</string>@@' | sed 's@\\n@ @g' | sed 's@\\@@g' \
| ispell -W3 -a | grep ^\& | sed 's@[0-9]@@g' | sort | uniq | cut -d, -f1-4 \
| sed 's@^..@- @' | column -t -s: \
> "$(DIST_DIR)/lint/stringsxml-spellcheck.txt"
@echo "\nPotential words with bad spelling:"
endif
@cat "$(DIST_DIR)/lint/stringsxml-spellcheck.txt"
@echo "-----------------------------------------------------------------------------------"

96
NEWS.md
View file

@ -1,96 +0,0 @@
# dandelion - News
## General
### Installation
You can install and update from [F-Droid](https://f-droid.org/repository/browse/?fdid=com.github.dfa.diaspora_android) or [GitHub](https://github.com/gsantner/dandelion/releases/latest).
F-Droid is a store for free & open source apps.
The *.apk's available for download are signed by the F-Droid team and guaranteed to correspond to the (open source) source code of dandelion.
Generally this is the recommended way to install dandelion & keep it updated.
### Get informed
* Check the [project readme](https://github.com/gsantner/dandelion/tree/news#readme) for general project information.
* Check the [project news](https://github.com/gsantner/dandelion/blob/master/NEWS.md#readme) for more details on what is going on.
* Check the [project git history](https://github.com/gsantner/dandelion/commits/master) for most recent code changes.
### The right place to ask
If you have questions or found an issue please head to the [dandelion project](https://github.com/gsantner/dandelion/issues/new/choose) and ask there.
[Search](https://github.com/gsantner/dandelion/issues?q=#js-issues-search) for same/similar and related issues/questions before, it might be already answered or resolved.
### Navigation
* [dandelion v1.2 - Add dandelior - Searchable Tags and Aspects](#dandelion-v12---add-dandelior---searchable-tags-and-aspects)
* [dandelion v0.1.2 - Aspekte, Pod wechseln](#dandelion-v012---aspekte-pod-wechseln)
------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
# dandelion\* v1.2 - Add dandelior\* - Searchable Tags and Aspects
_12. August 2018_
## dandelior\* is a rebranded version of dandelion\*
dandelior\* is based 100% on the same code and resources as dandelion\*. Its from the same code repository, just a different build flavor.
The main purpose of dandelior\* is the most requested feature till date - to support multiple accounts / another account at dandelion\*.
- Added an (rebranded) flavor of dandelion: dandelior
- Only differenties in use are other (black) icon and AMOLED colors by default enabled
- Already available on F-Droid
**New features:**
- All new Aspects and Tags, using a searchable dialog
**Fixed:**
- Sometimes the Stream went white, which is due an still (3+ years) unfixed Android Support library bug. It should not occur very often anymore due less use of fragments.
**Improved:**
- Various small tweaks
- Updated translation files
------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------
# dandelion v0.1.2 - Aspekte, Pod wechseln
_05. Juni 2016_
In den letzten Tagen hat @gsantner viel Zeit in die inoffizielle diaspora\* Android App ([dandelion\*](https://github.com/gsantner/dandelion)) investiert.
Dabei wurden unter anderem folgende Änderungen beigesteuert:
- Allgemeines zur Usability
- Animationen für den Activity-Wechsel und Startup, WebView-Scroll-Top
- Podliste caching
- Aspekt-Liste und Aspekte hinzugefügt
- Verbessertes Sharing aus der App
- Material Progressbar
- Suche verbessert
- Collapsing top menu
- toolbar/actions/menu geändert, fab entfernt
- Refactoring layout & menu files, dialogs
- Überarbeitete Main,Splash,PodSelectionActivity
- Pod wechseln

View file

@ -1,81 +1,43 @@
[![GitHub releases](https://img.shields.io/github/tag/gsantner/dandelion.svg)](https://github.com/gsantner/dandelion/releases)
[![GitHub downloads](https://img.shields.io/github/downloads/gsantner/dandelion/total.svg?logo=github&logoColor=lime)](https://github.com/gsantner/dandelion/releases)
[![Translate on Crowdin](https://img.shields.io/badge/translate-crowdin-green.svg)](https://crowdin.com/project/diaspora-for-android/invite)
[![Chat on Matrix](https://img.shields.io/badge/chat-matrix-blue.svg)](https://matrix.to/#/#dandelion:matrix.org)
[![GitHub CI](https://github.com/gsantner/dandelion/workflows/CI/badge.svg)](https://github.com/gsantner/dandelion/actions)
[![Codacy code quality](https://img.shields.io/codacy/grade/aff869c440bc48b7bd64680e97cbc453)](https://www.codacy.com/app/gsantner/dandelion)
[![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)
# dandelion\*
<img src="/app/src/main/ic_launcher-web.png" align="left" width="100" hspace="10" vspace="10">
This is an unofficial webview based client for the community-run, distributed social network <b><a href="https://diasporafoundation.org/">diaspora*</a></b>.
<div style="display:flex;" >
<a href="https://f-droid.org/repository/browse/?fdid=com.github.dfa.diaspora_android">
<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80">
</a>
<!--<a href="https://play.google.com/store/apps/details?id=com.github.dfa.diaspora_android">
<img alt="Get it on Google Play" height="80" src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" />
</a>-->
</div></br>
<a name="badgers"></a>[![Build Status](https://travis-ci.org/Diaspora-for-Android/diaspora-android.svg?branch=master)](https://travis-ci.org/Diaspora-for-Android/diaspora-android)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/diaspora-for-android/localized.svg)](https://crowdin.com/project/diaspora-for-android)
[![Chat - FreeNode IRC](https://img.shields.io/badge/chat-on%20freenode-blue.svg)](https://kiwiirc.com/client/irc.freenode.net/?nick=user-dfa|?#diaspora-for-android)
[![Chat - Gitter](https://img.shields.io/badge/chat-on%20gitter-blue.svg)](https://gitter.im/Diaspora-for-Android/diaspora-android)
## Description
This is an unofficial webview based client for the community-run, distributed social network <b><a href="https://diasporafoundation.org/">diaspora*</a></b>.
It's currently under development and should be used with that in mind. Please submit any bugs you might find.
# Diaspora for Android
#### WebApp
The app is developed as a WebApp because currently diaspora\* doesn't have an functional 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 currently 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?
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
The minimum Android version supported is Jelly Bean, Android v4.2.0 / API 17
### Privacy & Permissions<a name="privacy"></a>
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.
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 ([F-Droid](https://f-droid.org/repository/browse/?fdid=com.github.dfa.diaspora_android), [Release Archive](https://github.com/Diaspora-for-Android/diaspora-android/releases))
- Watch [Changelog](https://github.com/Diaspora-for-Android/diaspora-android/blob/master/CHANGELOG.md)
- See [Screenshots](https://github.com/Diaspora-for-Android/diaspora-android/blob/master/SCREENSHOTS.md)
## Contributions
The project is always open for contributions and accepts pull requests.
The project uses [AOSP Java Code Style](https://source.android.com/source/code-style#follow-field-naming-conventions), with one exception: private members are `_camelCase` instead of `mBigCamel`. You may use Android Studios _auto reformat feature_ before sending a PR.
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.
Translations can be contributed on GitHub. You can use Stringlate ([![Translate - with Stringlate](https://img.shields.io/badge/stringlate-translate-green.svg)](https://lonamiwebs.github.io/stringlate/translate?git=https%3A%2F%2Fgithub.com%2Fgsantner%2Fdandelion.git)) to translate the project directly on your Android phone. It allows you to export as E-Mail attachement and to post on GitHub.
We use Crowdin to translate Diaspora for Android. Join our project here: <https://crowdin.com/project/diaspora-for-android/invite>. If your desired language is not listed please contact the maintainers/owner.
Join our Matrix channel and say hello! Don't be afraid to start talking. [![Chat - Matrix](https://img.shields.io/badge/chat-on%20matrix-blue.svg)](https://matrix.to/#/#dandelion:matrix.org)
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.
### License
Diaspora for Android is released under GNU GENERAL PUBLIC LICENSE (see [LICENCE](https://github.com/Diaspora-for-Android/diaspora-android/blob/master/LICENSE.md)).
#### Resources
* Project: [Changelog](/CHANGELOG.md) | [Issues level/beginner](https://github.com/gsantner/dandelion/issues?q=is%3Aissue+is%3Aopen+label%3Alevel%2Fbeginner) | [License](/LICENSE.txt) | [CoC](/CODE_OF_CONDUCT.md)
* Project diaspora\* account: [dandelion00@diasp.org](https://diasp.org/people/48b78420923501341ef3782bcb452bd5)
* diaspora\*: [GitHub](https://github.com/diaspora/diaspora) | [Web](https://diasporafoundation.org) | [d\* HQ account](https://pod.diaspora.software/people/7bca7c80311b01332d046c626dd55703)
* App on F-Droid: [Metadata](https://gitlab.com/fdroid/fdroiddata/blob/master/metadata/com.github.dfa.diaspora_android.txt) | [Page](https://f-droid.org/packages/com.github.dfa.diaspora_android/) | [Wiki](https://f-droid.org/wiki/page/com.github.dfa.diaspora_android) | [Build log](https://f-droid.org/wiki/page/com.github.dfa.diaspora_android/lastbuild)
### 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.
[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?
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 :)
## Licensing
dandelion\* is released under GNU GENERAL PUBLIC LICENSE (see [LICENCE](https://github.com/gsantner/dandelion/blob/master/LICENSE.md)).
The app is licensed GPL v3. Localization files and resources (strings\*.xml) are licensed CC0 1.0.
For more licensing informations, see [`3rd party licenses`](/app/src/main/res/raw/licenses_3rd_party.md).
### Device Requirements
The minimum Android version supported is Jelly Bean, Android v4.2.0 / API 17
## Screenshots
<div style="display:flex;" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/01.png" width="19%" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/02.png" width="19%" style="margin-left:10px;" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/03.png" width="19%" style="margin-left:10px;" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/04.png" width="19%" style="margin-left:10px;" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/05.png" width="19%" style="margin-left:10px;" >
</div>
### App Permissions
Diaspora for Android requires access to the Internet and to external storage to be able to upload photos when creating a new post and for taking screenshots.
<div style="display:flex;" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/06.png" width="19%" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/07.png" width="19%" style="margin-left:10px;" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/08.png" width="19%" style="margin-left:10px;" >
<img src="https://raw.githubusercontent.com/gsantner/dandelion/master/metadata/en-US/phoneScreenshots/09.png" width="19%" style="margin-left:10px;" >
</div>
### Notice
#### Maintainers
- gsantner ([GitHub](https://github.com/gsantner), [diaspora*](https://pod.geraspora.de/people/d1cbdd70095301341e834860008dbc6c))
- vanitasvitae ([GitHub](https://github.com/vanitasvitae), [diaspora*](https://pod.geraspora.de/people/bbd7af90fbec013213e34860008dbc6c))
## Maintainers
- gsantner ([GitHub](https://github.com/gsantner), [Web](https://gsantner.github.io), [diaspora*](https://pod.geraspora.de/people/d1cbdd70095301341e834860008dbc6c))
- vanitasvitae ([GitHub](https://github.com/vanitasvitae), [Diaspora](https://pod.geraspora.de/people/bbd7af90fbec013213e34860008dbc6c))

24
SCREENSHOTS.md Normal file
View file

@ -0,0 +1,24 @@
<table>
<tr>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/01.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/02.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/03.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/04.png" height="60%" width="60%"></td>
</tr>
<tr>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/05.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/06.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/07.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/08.png" height="60%" width="60%"></td>
</tr>
<tr>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/09.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/10.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/11.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/12.png" height="60%" width="60%"></td>
</tr>
<tr>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/13.png" height="60%" width="60%"></td>
<td><img src="https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/graphics/screens/0.1.6/14.png" height="60%" width="60%"></td>
</tr>
</table>

View file

@ -1,63 +1,20 @@
apply plugin: 'com.android.application'
if (enable_plugin_kotlin) {
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
}
apply plugin: 'android-apt'
android {
buildToolsVersion rootProject.ext.version_buildTools
compileSdkVersion rootProject.ext.version_compileSdk
compileSdkVersion 24
buildToolsVersion "24.0.3"
defaultConfig {
resValue "string", "manifest_package_id", "com.github.dfa.diaspora_android"
applicationId "com.github.dfa.diaspora_android"
versionName "1.3.5"
versionCode 46
minSdkVersion 17
targetSdkVersion 24
versionCode 9
versionName "0.2.0"
setProperty("archivesBaseName", "diasporaAndroid__${versionName}__")
vectorDrawables.useSupportLibrary = true
minSdkVersion rootProject.ext.version_minSdk
targetSdkVersion rootProject.ext.version_compileSdk
buildConfigField "boolean", "IS_TEST_BUILD", "false"
buildConfigField "boolean", "IS_GPLAY_BUILD", "false"
buildConfigField "String[]", "DETECTED_ANDROID_LOCALES", "${findUsedAndroidLocales()}"
buildConfigField "String", "BUILD_DATE", "\"${getBuildDate()}\""
buildConfigField "String", "GITHASH", "\"${getGitHash()}\""
setProperty("archivesBaseName", applicationId + "-v" + versionCode + "-" + versionName)
}
flavorDimensions "default"
productFlavors {
flavorDefault {
}
/*
flavorGplay {
buildConfigField "boolean", "IS_GPLAY_BUILD", "true"
}*/
flavorDandelior {
applicationId "net.gsantner.dandelior"
}
flavorAtest {
applicationId "net.gsantner.secondlion"
versionCode = Integer.parseInt(new Date().format('yyMMdd'))
versionName = new Date().format('yyMMdd')
buildConfigField "boolean", "IS_TEST_BUILD", "true"
}
}
sourceSets {
main { assets.srcDirs = ['src/main/assets'] }
if (enable_plugin_kotlin) {
main.java.srcDirs += 'src/main/kotlin'
}
main.java.srcDirs += 'thirdparty/java'
main.res.srcDirs += 'thirdparty/res'
main.assets.srcDirs += 'thirdparty/assets'
}
buildTypes {
release {
minifyEnabled false
@ -65,72 +22,88 @@ android {
}
}
configurations.all {
resolutionStrategy {
eachDependency { details ->
if (details.requested.group == 'com.android.support') {
if (details.requested.name != 'multidex' && details.requested.name != 'multidex-instrumentation') {
details.useVersion "${rootProject.ext.version_library_appcompat}"
}
}
}
}
}
packagingOptions {
exclude 'META-INF/LICENSE-LGPL-2.1.txt'
exclude 'META-INF/LICENSE-LGPL-3.txt'
exclude 'META-INF/LICENSE-W3C-TEST'
}
compileOptions {
encoding = 'UTF-8'
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
disable 'MissingTranslation', 'InvalidPackage', 'ObsoleteLintCustomCheck', 'DefaultLocale', 'UnusedAttribute', 'VectorRaster', 'InflateParams', 'IconLocation', 'UnusedResources', 'TypographyEllipsis'
abortOnError false
disable 'MissingTranslation'
}
}
// Additional repositories
repositories {
maven {
url "https://jitpack.io"
}
}
dependencies {
// Sub-Projects
//implementation project(':subprojectFromRoot')
//compile project(':subprojectFromRoot')
// Jars
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.13'
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
// Android standard libs
implementation "com.android.support:appcompat-v7:${version_library_appcompat}"
implementation "com.android.support:design:${version_library_appcompat}"
implementation "com.android.support:support-v4:${version_library_appcompat}"
implementation "com.android.support:customtabs:${version_library_appcompat}"
implementation "com.android.support:cardview-v7:${version_library_appcompat}"
implementation "com.android.support:preference-v7:${version_library_appcompat}"
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:design:24.1.0' //Don't update. Broken up to 25.0.0
compile 'com.android.support:support-v4:24.2.1'
compile 'com.android.support:customtabs:24.2.1'
// UI libraries
implementation "com.github.DASAR:ShiftColorPicker:v0.5"
// More libraries
compile 'com.jakewharton:butterknife:8.0.1'
compile 'info.guardianproject.netcipher:netcipher:2.0.0-alpha1'
compile 'info.guardianproject.netcipher:netcipher-webkit:2.0.0-alpha1'
compile 'com.github.DASAR:ShiftColorPicker:v0.5'
apt 'com.jakewharton:butterknife-compiler:8.0.1'
}
// Tool libraries
implementation 'commons-io:commons-io:2.6'
implementation "info.guardianproject.netcipher:netcipher:${version_library_netcipher}"
implementation "info.guardianproject.netcipher:netcipher-webkit:${version_library_netcipher}"
//noinspection AnnotationProcessorOnCompilePath
implementation "com.jakewharton:butterknife:${version_library_butterknife}"
if (enable_plugin_kotlin) {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${version_plugin_kotlin}"
// #####################
// Groovy Coding Area
// #####################
final String RAW_DIR = "app/src/main/res/raw"
final String[] ROOT_TO_RAW_COPYFILES = ["README.md", "LICENSE.md", "CHANGELOG.md", "CONTRIBUTORS.txt"]
final String PODLIST_URL = 'https://raw.githubusercontent.com/Diaspora-for-Android/diaspora-android-extras/master/podList/podlist.json'
final String PODLIST_PATH = "${RAW_DIR}/podlist.json"
// Called before building
task copyRepoFiles(type: Copy) {
// Copy files over to raw dir
from rootProject.files(ROOT_TO_RAW_COPYFILES)
into RAW_DIR.replaceFirst("app/", "")
rename { String fileName ->
fileName.replace(fileName, fileName.toLowerCase())
}
// Processors
def anpros = ["com.jakewharton:butterknife-compiler:${version_library_butterknife}"]
for (anpro in anpros) {
if (enable_plugin_kotlin) {
kapt anpro
} else {
annotationProcessor anpro
// Filter Contributors file
from(rootProject.file("CONTRIBUTORS.txt")) {
into '.' // Target already changed to 'src/main/res/raw'
rename { String fileName ->
fileName.replace(fileName, fileName.toLowerCase())
}
filter { line ->
(line.toString().matches("..l>>.*") || line.toString().startsWith("## 99l CONTRIBUTORS")) ? null : line.toString().trim().replaceAll(" \\(.*\\)", "")
}
}
// Download PodList
downloadFile(PODLIST_PATH, PODLIST_URL, false)
// Application variants
android.applicationVariants.all { v ->
// Do if we build in release (signed apk) mode
if (v.buildType.name == "release") {
downloadFile(PODLIST_PATH, PODLIST_URL, true)
}
}
}
// Downloads a file
def downloadFile(filePath, url, downloadIfExists) {
def f = new File(filePath)
f.exists() && downloadIfExists && f.delete();
if (!f.exists()) {
new URL(url).withInputStream { i -> f.withOutputStream { it << i } }
}
}
tasks.copyRepoFiles.execute()

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M0.025,-0.07h19.95v20.14H0.025z"
android:fillColor="#492600"/>
</vector>

View file

@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="36.363636"
android:viewportHeight="36.363636">
<group android:translateX="8.181818"
android:translateY="8.181818">
<path
android:pathData="M11.337,14.123l-0.963,-1.345c-0.257,-0.36 -0.466,-0.64 -0.477,-0.64 -0.012,0 -0.416,0.544 -0.958,1.287a83.9,83.9 0,0 1,-0.947 1.287c-0.015,0 -1.86,-1.3 -1.865,-1.313 -0.002,-0.007 0.415,-0.62 0.927,-1.361 0.512,-0.742 0.931,-1.36 0.931,-1.375 0,-0.023 -0.166,-0.081 -1.468,-0.515l-1.485,-0.496c-0.013,-0.005 0.063,-0.263 0.327,-1.094 0.19,-0.599 0.349,-1.093 0.354,-1.099 0.005,-0.006 0.707,0.219 1.56,0.5 0.852,0.28 1.556,0.509 1.565,0.509 0.008,0 0.018,-0.013 0.022,-0.03 0.003,-0.015 0.01,-0.74 0.016,-1.612 0.006,-0.87 0.015,-1.59 0.02,-1.6 0.009,-0.012 0.248,-0.015 1.127,-0.015 0.614,0 1.123,0.004 1.13,0.01 0.01,0.006 0.027,0.485 0.056,1.56 0.046,1.766 0.047,1.79 0.075,1.79 0.01,0 0.686,-0.226 1.501,-0.503a50.795,50.795 0,0 1,1.49 -0.492c0.016,0.019 0.685,2.194 0.676,2.202 -0.004,0.005 -0.684,0.237 -1.51,0.517 -1.137,0.386 -1.504,0.515 -1.507,0.531 -0.003,0.012 0.388,0.597 0.886,1.324 0.49,0.716 0.888,1.308 0.886,1.314a96.945,96.945 0,0 1,-1.852 1.364c-0.006,0 -0.239,-0.317 -0.517,-0.705z"
android:fillColor="#fafafa"/>
</group>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">secondlion*</string>
</resources>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M0.025,-0.07h19.95v20.14H0.025z"
android:fillColor="#000000"/>
</vector>

View file

@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="36.363636"
android:viewportHeight="36.363636">
<group android:translateX="8.181818"
android:translateY="8.181818">
<path
android:pathData="M11.337,14.123l-0.963,-1.345c-0.257,-0.36 -0.466,-0.64 -0.477,-0.64 -0.012,0 -0.416,0.544 -0.958,1.287a83.9,83.9 0,0 1,-0.947 1.287c-0.015,0 -1.86,-1.3 -1.865,-1.313 -0.002,-0.007 0.415,-0.62 0.927,-1.361 0.512,-0.742 0.931,-1.36 0.931,-1.375 0,-0.023 -0.166,-0.081 -1.468,-0.515l-1.485,-0.496c-0.013,-0.005 0.063,-0.263 0.327,-1.094 0.19,-0.599 0.349,-1.093 0.354,-1.099 0.005,-0.006 0.707,0.219 1.56,0.5 0.852,0.28 1.556,0.509 1.565,0.509 0.008,0 0.018,-0.013 0.022,-0.03 0.003,-0.015 0.01,-0.74 0.016,-1.612 0.006,-0.87 0.015,-1.59 0.02,-1.6 0.009,-0.012 0.248,-0.015 1.127,-0.015 0.614,0 1.123,0.004 1.13,0.01 0.01,0.006 0.027,0.485 0.056,1.56 0.046,1.766 0.047,1.79 0.075,1.79 0.01,0 0.686,-0.226 1.501,-0.503a50.795,50.795 0,0 1,1.49 -0.492c0.016,0.019 0.685,2.194 0.676,2.202 -0.004,0.005 -0.684,0.237 -1.51,0.517 -1.137,0.386 -1.504,0.515 -1.507,0.531 -0.003,0.012 0.388,0.597 0.886,1.324 0.49,0.716 0.888,1.308 0.886,1.314a96.945,96.945 0,0 1,-1.852 1.364c-0.006,0 -0.239,-0.317 -0.517,-0.705z"
android:fillColor="#fafafa"/>
</group>
</vector>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">dandelior*</string>
</resources>

View file

@ -7,70 +7,45 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<application
android:name="com.github.dfa.diaspora_android.App"
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:name="com.github.dfa.diaspora_android.App"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:theme="@style/DiasporaLight">
android:theme="@style/DiasporaLight" >
<provider
android:name="com.github.dfa.diaspora_android.service.HashtagContentProvider"
android:authorities="${applicationId}.mainactivity"
android:exported="false" />
android:authorities="com.github.dfa.diaspora_android.mainactivity"
android:exported="false"/>
<!--File provider for sharing files-->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
<service
android:name="com.github.dfa.diaspora_android.service.FetchPodsService"
android:enabled="true"
android:exported="false" />
<activity
android:name="com.github.dfa.diaspora_android.activity.SettingsActivity"
android:configChanges="keyboardHidden|locale|orientation|screenSize"
android:label="@string/settings"
android:name=".activity.SettingsActivity"
android:launchMode="singleInstance"
android:theme="@style/DiasporaLight.NoActionBar" />
<activity
android:name="com.github.dfa.diaspora_android.activity.AboutActivity"
android:configChanges="locale"
android:label="@string/about"
android:theme="@style/DiasporaLight.NoActionBar" />
<activity
android:name="com.github.dfa.diaspora_android.activity.MainActivity"
android:configChanges="keyboardHidden|locale|orientation|screenSize"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/DiasporaLight.NoActionBar"
android:windowSoftInputMode="adjustResize">
android:label="@string/settings" />
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
<activity
android:name=".activity.AboutActivity"
android:label="@string/about_activity__title_about_app"
android:theme="@style/DiasporaLight.NoActionBar"/>
<activity
android:name=".activity.MainActivity"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/DiasporaLight.NoActionBar"
android:label="@string/diaspora">
<intent-filter>
<action android:name="sc_new_post" />
<action android:name="sc_nav_followed_tags" />
<action android:name="sc_aspects" />
<action android:name="sc_activities" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
@ -81,7 +56,7 @@
</intent-filter>
<!-- Hashtag click intent from HtmlTextViews -->
<intent-filter tools:ignore="AppLinkUrlError">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.cc.tag" />
@ -90,716 +65,150 @@
<!-- Intent from Web Browser / Mail / IM / Clickable Link -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Additional allowed services -->
<data
android:host="dia.so"
android:scheme="https" />
<!--@@@ PODLIST START-->
<data
android:host="joindiaspora.com"
android:scheme="https" />
<data
android:host="diasporaaqmjixh5.onion"
android:scheme="http" />
<data
android:host="pod.geraspora.de"
android:scheme="https" />
<data
android:host="diasp.org"
android:scheme="https" />
<data
android:host="diasporgc3d32vv4.onion"
android:scheme="https" />
<data
android:host="framasphere.org"
android:scheme="https" />
<data
android:host="nerdpol.ch"
android:scheme="https" />
<data
android:host="despora.de"
android:scheme="https" />
<data
android:host="sechat.org"
android:scheme="https" />
<data
android:host="sechatqpscuj2npx.onion"
android:scheme="http" />
<data
android:host="berdaguermontes.eu"
android:scheme="https" />
<data
android:host="berlinspora.de"
android:scheme="https" />
<data
android:host="community.kanalinseln.de"
android:scheme="https" />
<data
android:host="d.consumium.org"
android:scheme="https" />
<data
android:host="dia.manuelbichler.at"
android:scheme="https" />
<data
android:host="dia.myocastor.de"
android:scheme="https" />
<data
android:host="diapod.net"
android:scheme="https" />
<data
android:host="diapod.org"
android:scheme="https" />
<data
android:host="diasp.ca"
android:scheme="https" />
<data
android:host="diasp.cz"
android:scheme="https" />
<data
android:host="diasp.de"
android:scheme="https" />
<data
android:host="diasp.eu"
android:scheme="https" />
<data
android:host="diasp.eu.com"
android:scheme="https" />
<data
android:host="diasp.nl"
android:scheme="https" />
<data
android:host="diaspod.de"
android:scheme="https" />
<data
android:host="diaspora-fr.org"
android:scheme="https" />
<data
android:host="diaspora.alfter.us"
android:scheme="https" />
<data
android:host="diaspora.bohramt.de"
android:scheme="https" />
<data
android:host="diaspora.com.ar"
android:scheme="https" />
<data
android:host="diaspora.deadhexagon.com"
android:scheme="https" />
<data
android:host="diaspora.digi-merc.org"
android:scheme="https" />
<data
android:host="diaspora.dorf-post.de"
android:scheme="https" />
<data
android:host="diaspora.espiritolivre.org"
android:scheme="https" />
<data
android:host="diaspora.horwood.biz"
android:scheme="https" />
<data
android:host="diaspora.hzsogood.net"
android:scheme="https" />
<data
android:host="diaspora.kapper.net"
android:scheme="https" />
<data
android:host="diaspora.koehn.com"
android:scheme="https" />
<data
android:host="diaspora.kosebamse.com"
android:scheme="https" />
<data
android:host="diaspora.lebarjack.com"
android:scheme="https" />
<data
android:host="diaspora.microdata.co.uk"
android:scheme="https" />
<data
android:host="diaspora.moosje.nl"
android:scheme="https" />
<data
android:host="diaspora.net.gr"
android:scheme="https" />
<data
android:host="diaspora.permutationsofchaos.com"
android:scheme="https" />
<data
android:host="diaspora.pimpmypony.eu"
android:scheme="https" />
<data
android:host="diaspora.pingupod.de"
android:scheme="https" />
<data
android:host="diaspora.podzimek.org"
android:scheme="https" />
<data
android:host="diaspora.poleni.com"
android:scheme="https" />
<data
android:host="diaspora.psyco.fr"
android:scheme="https" />
<data
android:host="diaspora.raven-ip.com"
android:scheme="https" />
<data
android:host="diaspora.retrodigital.net"
android:scheme="https" />
<data
android:host="diaspora.soh.re"
android:scheme="https" />
<data
android:host="diaspora.subsignal.org"
android:scheme="https" />
<data
android:host="diaspora.trash-talk.de"
android:scheme="https" />
<data
android:host="diaspora.u4u.org"
android:scheme="https" />
<data
android:host="diaspora.unixcorn.org"
android:scheme="https" />
<data
android:host="diasporabr.com.br"
android:scheme="https" />
<data
android:host="diasporabrazil.org"
android:scheme="https" />
<data
android:host="diasporapr.tk"
android:scheme="https" />
<data
android:host="diasporing.ch"
android:scheme="https" />
<data
android:host="distributed.chat"
android:scheme="https" />
<data
android:host="espora.com.es"
android:scheme="https" />
<data
android:host="espora.social"
android:scheme="https" />
<data
android:host="failure.net"
android:scheme="https" />
<data
android:host="flokk.no"
android:scheme="https" />
<data
android:host="freehuman.fr"
android:scheme="https" />
<data
android:host="iliketoast.net"
android:scheme="https" />
<data
android:host="jons.gr"
android:scheme="https" />
<data
android:host="kapok.se"
android:scheme="https" />
<data
android:host="karmasphe.re"
android:scheme="https" />
<data
android:host="laba.mba"
android:scheme="https" />
<data
android:host="liberdade.digital"
android:scheme="https" />
<data
android:host="librenet.co.za"
android:scheme="https" />
<data
android:host="librenet.gr"
android:scheme="https" />
<data
android:host="misamigos.online"
android:scheme="https" />
<data
android:host="mondiaspora.net"
android:scheme="https" />
<data
android:host="networkwizard.de"
android:scheme="https" />
<data
android:host="nx-pod.de"
android:scheme="https" />
<data
android:host="pe.spbstu.ru"
android:scheme="https" />
<data
android:host="pod.4ray.co"
android:scheme="https" />
<data
android:host="pod.8n1.org"
android:scheme="https" />
<data
android:host="pod.alterworld.info"
android:scheme="https" />
<data
android:host="pod.asap-soft.com"
android:scheme="https" />
<data
android:host="pod.cannyfoxx.me"
android:scheme="https" />
<data
android:host="pod.cyberdungeon.de"
android:scheme="https" />
<data
android:host="pod.dapor.net"
android:scheme="https" />
<data
android:host="pod.datenknoten.me"
android:scheme="https" />
<data
android:host="pod.diaspora.software"
android:scheme="https" />
<data
android:host="pod.dirkomatik.de"
android:scheme="https" />
<data
android:host="pod.disroot.org"
android:scheme="https" />
<data
android:host="pod.gedankenausbruch.com"
android:scheme="https" />
<data
android:host="pod.gleisnetze.de"
android:scheme="https" />
<data
android:host="pod.goodsharing.at"
android:scheme="https" />
<data
android:host="pod.hashtagueule.fr"
android:scheme="https" />
<data
android:host="pod.hoizi.net"
android:scheme="https" />
<data
android:host="pod.itabs.nl"
android:scheme="https" />
<data
android:host="pod.jpope.org"
android:scheme="https" />
<data
android:host="pod.liebeleu.de"
android:scheme="https" />
<data
android:host="pod.nomorestars.com"
android:scheme="https" />
<data
android:host="pod.orkz.net"
android:scheme="https" />
<data
android:host="pod.ponk.pink"
android:scheme="https" />
<data
android:host="pod.promedol.com"
android:scheme="https" />
<data
android:host="pod.psynet.su"
android:scheme="https" />
<data
android:host="pod.roocita.com"
android:scheme="https" />
<data
android:host="pod.sertelon.fr"
android:scheme="https" />
<data
android:host="pod.storel.li"
android:scheme="https" />
<data
android:host="pod.tchncs.de"
android:scheme="https" />
<data
android:host="pod.thomasdalichow.de"
android:scheme="https" />
<data
android:host="pod.volt.io"
android:scheme="https" />
<data
android:host="podbay.net"
android:scheme="https" />
<data
android:host="poddery.com"
android:scheme="https" />
<data
android:host="podricing.pw"
android:scheme="https" />
<data
android:host="pubpod.alqualonde.org"
android:scheme="https" />
<data
android:host="revreso.de"
android:scheme="https" />
<data
android:host="ruhrspora.de"
android:scheme="https" />
<data
android:host="russiandiaspora.org"
android:scheme="https" />
<data
android:host="shrekislove.us"
android:scheme="https" />
<data
android:host="social.acclaro.digital"
android:scheme="https" />
<data
android:host="social.baldr.io"
android:scheme="https" />
<data
android:host="social.daxbau.net"
android:scheme="https" />
<data
android:host="social.elaon.de"
android:scheme="https" />
<data
android:host="social.lanham.id.au"
android:scheme="https" />
<data
android:host="social.mbuto.me"
android:scheme="https" />
<data
android:host="socializer.cc"
android:scheme="https" />
<data
android:host="spora.zone"
android:scheme="https" />
<data
android:host="subvillage.de"
android:scheme="https" />
<data
android:host="sysad.org"
android:scheme="https" />
<data
android:host="teki.be"
android:scheme="https" />
<data
android:host="therealtalk.org"
android:scheme="https" />
<data
android:host="thinkopen.net"
android:scheme="https" />
<data
android:host="tippentappen.de"
android:scheme="https" />
<data
android:host="whatsnewz.com"
android:scheme="https" />
<data
android:host="wk3.org"
android:scheme="https" />
<data
android:host="www.datataffel.dk"
android:scheme="https" />
<data
android:host="www.diasporaix.de"
android:scheme="https" />
<data
android:host="diaspora.hofud.com"
android:scheme="https" />
<data
android:host="diaspora.softwarelivre.org"
android:scheme="https" />
<data
android:host="confetticake.club"
android:scheme="https" />
<data
android:host="diaspote.org"
android:scheme="https" />
<data
android:host="diaspora.zone"
android:scheme="https" />
<data
android:host="pod.userzap.de"
android:scheme="https" />
<data
android:host="www.vodeoo.com"
android:scheme="https" />
<data
android:host="diaspora.punkbeer.me"
android:scheme="https" />
<data
android:host="ingtech.net"
android:scheme="https" />
<data
android:host="mmkr.co"
android:scheme="https" />
<data
android:host="pod.kneedrag.org"
android:scheme="https" />
<data
android:host="spyurk.am"
android:scheme="https" />
<data
android:host="pod.mew.cat"
android:scheme="https" />
<data
android:host="dfhz.tk"
android:scheme="https" />
<data
android:host="netiz.in"
android:scheme="https" />
<data
android:host="pod1.orobouros.net"
android:scheme="https" />
<data
android:host="witchcraft.ml"
android:scheme="https" />
<data
android:host="libellula.criptica.org"
android:scheme="https" />
<data
android:host="pod.datamol.org"
android:scheme="https" />
<data
android:host="social.berdaguermontes.eu"
android:scheme="https" />
<data
android:host="mh8.lat-clan.fr"
android:scheme="https" />
<data
android:host="dp.lumy.me"
android:scheme="https" />
<data
android:host="social.souvenirfromlife.fr"
android:scheme="https" />
<data
android:host="diaspora.mokrynskyi.com"
android:scheme="https" />
<data
android:host="hub.transition-regensburg.de"
android:scheme="https" />
<data
android:host="co.zy.lc"
android:scheme="https" />
<data
android:host="diaspora.treefish.org"
android:scheme="https" />
<data
android:host="diaspora.bke.ro"
android:scheme="https" />
<data
android:host="pod.sd.vc"
android:scheme="https" />
<data
android:host="diaspora.cxx.rocks"
android:scheme="https" />
<data
android:host="social.homenet.org"
android:scheme="https" />
<data
android:host="social.cigliola.com"
android:scheme="https" />
<data
android:host="friaspora.tk"
android:scheme="https" />
<data
android:host="pod.lasserh.dk"
android:scheme="https" />
<data
android:host="hubz.tk"
android:scheme="https" />
<data
android:host="hubzilla.kosebamse.com"
android:scheme="https" />
<data
android:host="driaans.nl"
android:scheme="https" />
<data
android:host="dispersio.us"
android:scheme="https" />
<data
android:host="go.lookbehind.eu"
android:scheme="https" />
<data
android:host="diasp.ot-si.com"
android:scheme="https" />
<data
android:host="diaspora.crossfamilyweb.com"
android:scheme="https" />
<data
android:host="hub.aoeu.me"
android:scheme="https" />
<data
android:host="dia.pwn.ninja"
android:scheme="https" />
<data
android:host="3ogsbs3vuvapgg37.onion.to"
android:scheme="https" />
<data
android:host="hubz.secretlair.me"
android:scheme="https" />
<data
android:host="got.noip.me"
android:scheme="https" />
<data
android:host="pod.bitcast.info"
android:scheme="https" />
<data
android:host="f.tschlotfeldt.de"
android:scheme="https" />
<data
android:host="hubloq.net"
android:scheme="https" />
<data
android:host="hubzilla.kneedrag.org"
android:scheme="https" />
<data
android:host="gesichtsbu.ch"
android:scheme="https" />
<data
android:host="hubzi.fraengii.de"
android:scheme="https" />
<data
android:host="friendica.narf.ssji.net"
android:scheme="https" />
<data
android:host="durohr.de"
android:scheme="https" />
<data
android:host="0kcg.com"
android:scheme="https" />
<data
android:host="aegibson.me"
android:scheme="https" />
<data
android:host="redmatrix.us"
android:scheme="https" />
<data
android:host="15o2.de"
android:scheme="https" />
<data
android:host="upt.social"
android:scheme="https" />
<data
android:host="friendica.bohrshouse.com"
android:scheme="https" />
<data
android:host="hubzilla.site"
android:scheme="https" />
<data
android:host="hubzilla.zavb.de"
android:scheme="https" />
<data
android:host="diaspora.aeriesguard.com"
android:scheme="https" />
<data
android:host="pod.cornify.de"
android:scheme="https" />
<data
android:host="hochminuseins.net"
android:scheme="https" />
<data
android:host="thecrimsontint.com"
android:scheme="https" />
<data
android:host="diaspora.clubelek.fr"
android:scheme="https" />
<data
android:host="teamhubzilla.org"
android:scheme="https" />
<data
android:host="diaspora.schlimme.net"
android:scheme="https" />
<data
android:host="www.wiwiec.com"
android:scheme="https" />
<data
android:host="diasp.danletard.de"
android:scheme="https" />
<data
android:host="libertypod.com"
android:scheme="https" />
<data
android:host="hubzilla.pskosinski.pl"
android:scheme="https" />
<data
android:host="pod.juvenesco.eu"
android:scheme="https" />
<data
android:host="pirati.ca"
android:scheme="https" />
<data
android:host="diasp.sk"
android:scheme="https" />
<data
android:host="f.libreden.net"
android:scheme="https" />
<data
android:host="pod.mausdompteur.de"
android:scheme="https" />
<data
android:host="diaspora.raitisoja.com"
android:scheme="https" />
<data
android:host="squeet.me"
android:scheme="https" />
<data
android:host="pod.kakise.xyz"
android:scheme="https" />
<data
android:host="pod.diasporacaribe.org"
android:scheme="https" />
<data
android:host="hub.feder8.ru"
android:scheme="https" />
<data
android:host="hubzilla.a-zwenkau.de"
android:scheme="https" />
<data
android:host="social.punkbeer.me"
android:scheme="https" />
<data
android:host="pod.sapient.fun"
android:scheme="https" />
<data
android:host="pod.phantasie.cc"
android:scheme="https" />
<data
android:host="diaspora.masharih.me"
android:scheme="https" />
<data
android:host="hub.mariovavti.com"
android:scheme="https" />
<data
android:host="social.patur.in"
android:scheme="https" />
<data
android:host="jeroenpraat.nl"
android:scheme="https" />
<data
android:host="grindcore.ch"
android:scheme="https" />
<data
android:host="pod.vixiv.net"
android:scheme="https" />
<data
android:host="social.deuxfleurs.fr"
android:scheme="https" />
<data
android:host="parlementum.net"
android:scheme="https" />
<data
android:host="villianbook.com"
android:scheme="https" />
<data
android:host="frolix8.asia"
android:scheme="https" />
<data
android:host="hub.vilarejo.pro.br"
android:scheme="https" />
<data
android:host="social.vixiv.net"
android:scheme="https" />
<data android:host="joindiaspora.com" android:scheme="https" />
<data android:host="diasporaaqmjixh5.onion" android:scheme="http" />
<data android:host="pod.geraspora.de" android:scheme="https" />
<data android:host="diasp.org" android:scheme="https" />
<data android:host="framasphere.org" android:scheme="https" />
<data android:host="nerdpol.ch" android:scheme="https" />
<data android:host="despora.de" android:scheme="https" />
<data android:host="sechat.org" android:scheme="https" />
<data android:host="sechatqpscuj2npx.onion" android:scheme="http" />
<data android:host="berdaguermontes.eu" android:scheme="https" />
<data android:host="berlinspora.de" android:scheme="https" />
<data android:host="community.kanalinseln.de" android:scheme="https" />
<data android:host="d.consumium.org" android:scheme="https" />
<data android:host="dia.manuelbichler.at" android:scheme="https" />
<data android:host="dia.myocastor.de" android:scheme="https" />
<data android:host="diapod.net" android:scheme="https" />
<data android:host="diapod.org" android:scheme="https" />
<data android:host="diasp.ca" android:scheme="https" />
<data android:host="diasp.cz" android:scheme="https" />
<data android:host="diasp.de" android:scheme="https" />
<data android:host="diasp.eu" android:scheme="https" />
<data android:host="diasp.eu.com" android:scheme="https" />
<data android:host="diasp.nl" android:scheme="https" />
<data android:host="diaspod.de" android:scheme="https" />
<data android:host="diaspora-fr.org" android:scheme="https" />
<data android:host="diaspora.alfter.us" android:scheme="https" />
<data android:host="diaspora.bohramt.de" android:scheme="https" />
<data android:host="diaspora.com.ar" android:scheme="https" />
<data android:host="diaspora.deadhexagon.com" android:scheme="https" />
<data android:host="diaspora.digi-merc.org" android:scheme="https" />
<data android:host="diaspora.dorf-post.de" android:scheme="https" />
<data android:host="diaspora.espiritolivre.org" android:scheme="https" />
<data android:host="diaspora.horwood.biz" android:scheme="https" />
<data android:host="diaspora.hzsogood.net" android:scheme="https" />
<data android:host="diaspora.kapper.net" android:scheme="https" />
<data android:host="diaspora.koehn.com" android:scheme="https" />
<data android:host="diaspora.kosebamse.com" android:scheme="https" />
<data android:host="diaspora.lebarjack.com" android:scheme="https" />
<data android:host="diaspora.microdata.co.uk" android:scheme="https" />
<data android:host="diaspora.moosje.nl" android:scheme="https" />
<data android:host="diaspora.net.gr" android:scheme="https" />
<data android:host="diaspora.permutationsofchaos.com" android:scheme="https" />
<data android:host="diaspora.pimpmypony.eu" android:scheme="https" />
<data android:host="diaspora.pingupod.de" android:scheme="https" />
<data android:host="diaspora.podzimek.org" android:scheme="https" />
<data android:host="diaspora.poleni.com" android:scheme="https" />
<data android:host="diaspora.psyco.fr" android:scheme="https" />
<data android:host="diaspora.punkbeer.me" android:scheme="https" />
<data android:host="diaspora.raven-ip.com" android:scheme="https" />
<data android:host="diaspora.retrodigital.net" android:scheme="https" />
<data android:host="diaspora.soh.re" android:scheme="https" />
<data android:host="diaspora.subsignal.org" android:scheme="https" />
<data android:host="diaspora.trash-talk.de" android:scheme="https" />
<data android:host="diaspora.u4u.org" android:scheme="https" />
<data android:host="diaspora.unixcorn.org" android:scheme="https" />
<data android:host="diasporabr.com.br" android:scheme="https" />
<data android:host="diasporabrazil.org" android:scheme="https" />
<data android:host="diasporapr.tk" android:scheme="https" />
<data android:host="diasporing.ch" android:scheme="https" />
<data android:host="distributed.chat" android:scheme="https" />
<data android:host="espora.com.es" android:scheme="https" />
<data android:host="espora.social" android:scheme="https" />
<data android:host="failure.net" android:scheme="https" />
<data android:host="flokk.no" android:scheme="https" />
<data android:host="freehuman.fr" android:scheme="https" />
<data android:host="iliketoast.net" android:scheme="https" />
<data android:host="jons.gr" android:scheme="https" />
<data android:host="kapok.se" android:scheme="https" />
<data android:host="karmasphe.re" android:scheme="https" />
<data android:host="laba.mba" android:scheme="https" />
<data android:host="liberdade.digital" android:scheme="https" />
<data android:host="librenet.co.za" android:scheme="https" />
<data android:host="librenet.gr" android:scheme="https" />
<data android:host="misamigos.online" android:scheme="https" />
<data android:host="mondiaspora.net" android:scheme="https" />
<data android:host="networkwizard.de" android:scheme="https" />
<data android:host="nx-pod.de" android:scheme="https" />
<data android:host="pe.spbstu.ru" android:scheme="https" />
<data android:host="pod.4ray.co" android:scheme="https" />
<data android:host="pod.8n1.org" android:scheme="https" />
<data android:host="pod.alterworld.info" android:scheme="https" />
<data android:host="pod.asap-soft.com" android:scheme="https" />
<data android:host="pod.cannyfoxx.me" android:scheme="https" />
<data android:host="pod.cyberdungeon.de" android:scheme="https" />
<data android:host="pod.dapor.net" android:scheme="https" />
<data android:host="pod.datenknoten.me" android:scheme="https" />
<data android:host="pod.diaspora.software" android:scheme="https" />
<data android:host="pod.dirkomatik.de" android:scheme="https" />
<data android:host="pod.disroot.org" android:scheme="https" />
<data android:host="pod.gedankenausbruch.com" android:scheme="https" />
<data android:host="pod.gleisnetze.de" android:scheme="https" />
<data android:host="pod.goodsharing.at" android:scheme="https" />
<data android:host="pod.hashtagueule.fr" android:scheme="https" />
<data android:host="pod.hoizi.net" android:scheme="https" />
<data android:host="pod.itabs.nl" android:scheme="https" />
<data android:host="pod.jpope.org" android:scheme="https" />
<data android:host="pod.liebeleu.de" android:scheme="https" />
<data android:host="pod.nomorestars.com" android:scheme="https" />
<data android:host="pod.orkz.net" android:scheme="https" />
<data android:host="pod.ponk.pink" android:scheme="https" />
<data android:host="pod.promedol.com" android:scheme="https" />
<data android:host="pod.psynet.su" android:scheme="https" />
<data android:host="pod.roocita.com" android:scheme="https" />
<data android:host="pod.sertelon.fr" android:scheme="https" />
<data android:host="pod.storel.li" android:scheme="https" />
<data android:host="pod.tchncs.de" android:scheme="https" />
<data android:host="pod.thomasdalichow.de" android:scheme="https" />
<data android:host="pod.volt.io" android:scheme="https" />
<data android:host="podbay.net" android:scheme="https" />
<data android:host="poddery.com" android:scheme="https" />
<data android:host="podricing.pw" android:scheme="https" />
<data android:host="pubpod.alqualonde.org" android:scheme="https" />
<data android:host="revreso.de" android:scheme="https" />
<data android:host="ruhrspora.de" android:scheme="https" />
<data android:host="russiandiaspora.org" android:scheme="https" />
<data android:host="shrekislove.us" android:scheme="https" />
<data android:host="social.acclaro.digital" android:scheme="https" />
<data android:host="social.baldr.io" android:scheme="https" />
<data android:host="social.daxbau.net" android:scheme="https" />
<data android:host="social.elaon.de" android:scheme="https" />
<data android:host="social.lanham.id.au" android:scheme="https" />
<data android:host="social.mbuto.me" android:scheme="https" />
<data android:host="socializer.cc" android:scheme="https" />
<data android:host="spora.zone" android:scheme="https" />
<data android:host="subvillage.de" android:scheme="https" />
<data android:host="sysad.org" android:scheme="https" />
<data android:host="teki.be" android:scheme="https" />
<data android:host="therealtalk.org" android:scheme="https" />
<data android:host="thinkopen.net" android:scheme="https" />
<data android:host="tippentappen.de" android:scheme="https" />
<data android:host="whatsnewz.com" android:scheme="https" />
<data android:host="wk3.org" android:scheme="https" />
<data android:host="www.datataffel.dk" android:scheme="https" />
<data android:host="www.diasporaix.de" android:scheme="https" />
<data android:host="diaspora.hofud.com" android:scheme="https" />
<data android:host="diaspora.softwarelivre.org" android:scheme="https" />
<data android:host="confetticake.club" android:scheme="https" />
<data android:host="diaspote.org" android:scheme="https" />
<data android:host="diaspora.zone" android:scheme="https" />
<data android:host="pod.userzap.de" android:scheme="https" />
<!--@@@ PODLIST END-->
</intent-filter>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -34,35 +34,18 @@ 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 net.gsantner.opoc.util.AdBlock;
import net.gsantner.opoc.util.ContextUtils;
import net.gsantner.opoc.util.ShareUtil;
public class App extends Application {
private volatile static App app;
private AppSettings appSettings;
private AvatarImageLoader avatarImageLoader;
private CookieManager cookieManager;
private DiasporaUserProfile diasporaUserProfile;
public static App get() {
return app;
}
@Override
public void onCreate() {
super.onCreate();
ShareUtil.setFileProviderAuthority(BuildConfig.APPLICATION_ID);
app = this;
final Context c = getApplicationContext();
appSettings = AppSettings.get();
String a = new ContextUtils(this).bcstr("FLAVOR", "");
a += "__";
if (appSettings.isAppFirstStart() && "flavorDandelior".equals(new ContextUtils(this).bcstr("FLAVOR", ""))) {
appSettings.setAmoledColorMode(true);
}
appSettings = new AppSettings(c);
// Init app log
AppLog.setLoggingEnabled(appSettings.isLoggingEnabled());
@ -81,7 +64,6 @@ public class App extends Application {
}
cookieManager.setAcceptCookie(true);
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
AdBlock.getInstance().loadHostsFromRawAssetsAsync(this);
}
public void resetPodData(@Nullable WebView webView) {
@ -97,10 +79,7 @@ public class App extends Application {
new AvatarImageLoader(this).clearAvatarImage();
// Clear preferences__master
appSettings.resetPodSettings();
// Clear User profile - reload empty AppSettingsBase data
diasporaUserProfile.loadFromAppSettings();
appSettings.clearPodSettings();
// Clear cookies
//noinspection deprecation

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -20,13 +20,11 @@ package com.github.dfa.diaspora_android.activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
@ -35,9 +33,10 @@ import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@ -51,14 +50,14 @@ import com.github.dfa.diaspora_android.ui.theme.ThemedActivity;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
import com.github.dfa.diaspora_android.util.AppLog;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
import com.github.dfa.diaspora_android.util.DiasporaUrlHelper;
import com.github.dfa.diaspora_android.util.Helpers;
import java.util.Observable;
import java.util.Observer;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* Activity that holds some fragments that show information about the app in a tab layout
@ -66,17 +65,20 @@ import butterknife.OnClick;
public class AboutActivity extends ThemedActivity
implements IntellihideToolbarActivityListener {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
@BindView(R.id.about__appbar)
protected AppBarLayout _appBarLayout;
AppBarLayout appBarLayout;
@BindView(R.id.main__topbar)
protected Toolbar _toolbar;
protected Toolbar toolbar;
@BindView(R.id.appbar_linear_layout)
protected LinearLayout _linearLayout;
protected LinearLayout linearLayout;
@BindView(R.id.tabs)
protected TabLayout _tabLayout;
protected TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -84,9 +86,9 @@ public class AboutActivity extends ThemedActivity
setContentView(R.layout.about__activity);
ButterKnife.bind(this);
setSupportActionBar(_toolbar);
_toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24px));
_toolbar.setNavigationOnClickListener(new View.OnClickListener() {
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24px));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AboutActivity.this.onBackPressed();
@ -94,39 +96,47 @@ public class AboutActivity extends ThemedActivity
});
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
ViewPager mViewPager = ButterKnife.findById(this, R.id.container);
mViewPager = ButterKnife.findById(this, R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
_tabLayout.setupWithViewPager(mViewPager);
tabLayout.setupWithViewPager(mViewPager);
}
@Override
public void onResume() {
super.onResume();
setToolbarIntellihide(getAppSettings().isIntellihideToolbars());
if (getAppSettings().isIntellihideToolbars()) {
this.enableToolbarHiding();
} else {
this.disableToolbarHiding();
}
}
@Override
protected void applyColorToViews() {
ThemeHelper.updateToolbarColor(_toolbar);
ThemeHelper.updateTabLayoutColor(_tabLayout);
ThemeHelper.setPrimaryColorAsBackground(_linearLayout);
ThemeHelper.updateToolbarColor(toolbar);
ThemeHelper.updateTabLayoutColor(tabLayout);
ThemeHelper.setPrimaryColorAsBackground(linearLayout);
}
public void setToolbarIntellihide(boolean enable) {
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) _linearLayout.getLayoutParams();
if (enable) {
AppLog.d(this, "Enable Intellihide");
params.setScrollFlags(toolbarDefaultScrollFlags);
@Override
public void enableToolbarHiding() {
AppLog.d(this, "Enable Intellihide");
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) linearLayout.getLayoutParams();
//scroll|enterAlways|snap
params.setScrollFlags(toolbarDefaultScrollFlags);
appBarLayout.setExpanded(true, true);
}
} else {
AppLog.d(this, "Disable Intellihide");
params.setScrollFlags(0); // clear all scroll flags
}
_appBarLayout.setExpanded(true, true);
@Override
public void disableToolbarHiding() {
AppLog.d(this, "Disable Intellihide");
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) linearLayout.getLayoutParams();
params.setScrollFlags(0); // clear all scroll flags
appBarLayout.setExpanded(true, true);
}
/**
@ -136,55 +146,35 @@ public class AboutActivity extends ThemedActivity
public static final String TAG = "com.github.dfa.diaspora_android.AboutActivity.AboutFragment";
@BindView(R.id.fragment_about__about_text)
TextView aboutText;
@BindView(R.id.fragment_about__app_version)
TextView appVersion;
@BindView(R.id.fragment_about__spread_the_word_text)
HtmlTextView spreadText;
@BindView(R.id.fragment_about__contribute_button)
Button contributeBtn;
@BindView(R.id.fragment_about__translate_button)
Button translateBtn;
@BindView(R.id.fragment_about__feedback_button)
Button feedbackBtn;
@BindView(R.id.fragment_about__spread_the_word_button)
Button spreadBtn;
public AboutFragment() {
}
@Override
protected int getLayoutResId() {
return R.layout.about__fragment_about;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.about__fragment_about, container, false);
ButterKnife.bind(this, rootView);
if (isAdded()) {
try {
PackageInfo pInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
appVersion.setText(getString(R.string.app_version_with_arg, pInfo.versionName + " (" + pInfo.versionCode + ")"));
appVersion.setText(getString(R.string.fragment_debug__app_version, pInfo.versionName + " (" + pInfo.versionCode + ")"));
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
return rootView;
}
@Override
protected void applyColorToViews() {
ThemeHelper.getInstance(getAppSettings());
ThemeHelper.updateTextViewLinkColor(spreadText);
ThemeHelper.updateButtonTextColor(contributeBtn);
ThemeHelper.updateButtonTextColor(feedbackBtn);
ThemeHelper.updateButtonTextColor(spreadBtn);
ThemeHelper.updateButtonTextColor(translateBtn);
ThemeHelper.updateTextViewLinkColor(aboutText);
}
@Override
@ -193,30 +183,13 @@ public class AboutActivity extends ThemedActivity
}
@Override
public boolean onBackPressed() {
return false;
public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) {
/* Nothing to do */
}
@OnClick({R.id.fragment_about__contribute_button, R.id.fragment_about__translate_button, R.id.fragment_about__feedback_button, R.id.fragment_about__spread_the_word_button})
public void buttonClicked(View view) {
switch (view.getId()) {
case R.id.fragment_about__contribute_button:
ContextUtils.get().openWebpageInExternalBrowser(getString(R.string.fragment_about__contribute_link));
break;
case R.id.fragment_about__translate_button:
ContextUtils.get().openWebpageInExternalBrowser(getString(R.string.fragment_about__translate_link));
break;
case R.id.fragment_about__feedback_button:
ContextUtils.get().openWebpageInExternalBrowser(getString(R.string.fragment_About__feedback_link));
break;
case R.id.fragment_about__spread_the_word_button:
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(R.string.app_name));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, getString(R.string.hey_checkout_dandelion_tag__appspecific, getString(R.string.fragment_about__fdroid_link)));
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.share_dotdotdot)));
break;
}
@Override
public boolean onBackPressed() {
return false;
}
}
@ -226,20 +199,11 @@ public class AboutActivity extends ThemedActivity
public static class LicenseFragment extends ThemedFragment {
public static final String TAG = "com.github.dfa.diaspora_android.AboutActivity.LicenseFragment";
@BindView(R.id.fragment_license__maintainers_text)
HtmlTextView maintainers;
@BindView(R.id.fragment_license__licensetext)
HtmlTextView textLicenseBox;
@BindView(R.id.fragment_license__contributors_text)
HtmlTextView contributors;
@BindView(R.id.fragment_license__thirdparty_libs_text)
HtmlTextView thirdPartyLibs;
@BindView(R.id.fragment_license__license_button)
Button licenseBtn;
@BindView(R.id.fragment_license__leafpic_button)
Button leafpicBtn;
@BindView(R.id.fragment_license__3rdparty)
HtmlTextView textLicense3partyBox;
private String accentColor;
@ -248,43 +212,54 @@ public class AboutActivity extends ThemedActivity
}
@Override
protected int getLayoutResId() {
return R.layout.about__fragment_license;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.about__fragment_license, container, false);
ButterKnife.bind(this, rootView);
final Context context = rootView.getContext();
accentColor = Helpers.colorToHex(ThemeHelper.getAccentColor());
textLicenseBox.setTextFormatted(getString(R.string.fragment_license__license_content,
getMaintainersHtml(context),
getContributorsHtml(context),
getLicenseHtml(context)
));
textLicense3partyBox.setTextFormatted(
getLicense3dPartyHtml(context)
);
return rootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
accentColor = ContextUtils.get().colorToHexString(ThemeHelper.getAccentColor());
maintainers.setTextFormatted(getString(R.string.this_app_is_currently_developed_and_maintained_by_witharg,
ContextUtils.get().loadMarkdownForTextViewFromRaw(R.raw.maintainers, "")));
contributors.setTextFormatted(getString(R.string.thank_you_witharg,
ContextUtils.get().loadMarkdownForTextViewFromRaw(R.raw.contributors, "")));
thirdPartyLibs.setTextFormatted(
ContextUtils.get().loadMarkdownForTextViewFromRaw(R.raw.licenses_3rd_party, ""));
public String getContributorsHtml(Context context) {
String text = Helpers.readTextfileFromRawRessource(context, R.raw.contributors,
"<font color='" + accentColor + "'><b>*</b></font> ", "<br>");
return text;
}
@OnClick({R.id.fragment_license__leafpic_button, R.id.fragment_license__license_button})
public void buttonClicked(View v) {
switch (v.getId()) {
case R.id.fragment_license__leafpic_button:
ContextUtils.get().openWebpageInExternalBrowser(getString(R.string.fragment_licesen__misc_leafpic_link));
break;
case R.id.fragment_license__license_button:
ContextUtils.get().openWebpageInExternalBrowser(getString(R.string.fragment_license__license_gpl_link));
break;
}
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 getLicenseHtml(Context context) {
String text = Helpers.readTextfileFromRawRessource(context, R.raw.license,
"", "").replace("\n\n", "<br><br>");
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());
ThemeHelper.updateButtonTextColor(leafpicBtn);
ThemeHelper.updateButtonTextColor(licenseBtn);
ThemeHelper.updateTextViewLinkColor(maintainers);
ThemeHelper.updateTextViewLinkColor(thirdPartyLibs);
ThemeHelper.updateTextViewLinkColor(textLicense3partyBox);
ThemeHelper.updateTextViewLinkColor(textLicenseBox);
}
@Override
@ -292,6 +267,11 @@ public class AboutActivity extends ThemedActivity
return TAG;
}
@Override
public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) {
/* Nothing to do */
}
@Override
public boolean onBackPressed() {
return false;
@ -341,7 +321,7 @@ public class AboutActivity extends ThemedActivity
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("DEBUG_LOG", AppLog.Log.getLogBuffer());
clipboard.setPrimaryClip(clip);
Toast.makeText(DebugFragment.this.getActivity(), R.string.debug_log_copied_to_clipboard, Toast.LENGTH_SHORT).show();
Toast.makeText(DebugFragment.this.getActivity(), R.string.fragment_debug__toast_log_copied, Toast.LENGTH_SHORT).show();
} else {
AppLog.d(this, "Not Added!");
}
@ -355,14 +335,15 @@ public class AboutActivity extends ThemedActivity
try {
PackageInfo pInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
AppSettings appSettings = ((App) getActivity().getApplication()).getSettings();
DiasporaUrlHelper urls = new DiasporaUrlHelper(appSettings);
packageName.setText(pInfo.packageName);
appVersion.setText(getString(R.string.app_version_with_arg, pInfo.versionName + " (" + pInfo.versionCode + ")"));
appVersion.setText(getString(R.string.fragment_debug__app_version, pInfo.versionName + " (" + pInfo.versionCode + ")"));
osVersion.setText(getString(R.string.android_version_witharg, Build.VERSION.RELEASE));
deviceName.setText(getString(R.string.device_name_witharg, Build.MANUFACTURER + " " + Build.MODEL));
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));
if (app.getSettings().getPod() != null) {
podDomain.setText(getString(R.string.pod_domain_witharg__appspecific, app.getSettings().getPod().getPodUrl()));
podName.setText(getString(R.string.pod_profile_name_witharg__appspecific, app.getSettings().getPod().getName()));
podDomain.setText(getString(R.string.fragment_debug__pod_profile_url, app.getSettings().getPod().getPodUrl()));
podName.setText(getString(R.string.fragment_debug__pod_profile_name, app.getSettings().getPod().getName()));
}
} catch (PackageManager.NameNotFoundException e) {
@ -404,7 +385,7 @@ public class AboutActivity extends ThemedActivity
return new AboutFragment();
case 1: //License
return new LicenseFragment();
case 2: //Debug
case 3: //Debug
default:
return new DebugFragment();
}
@ -420,11 +401,11 @@ public class AboutActivity extends ThemedActivity
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.about);
return getString(R.string.about_activity__title_about_app);
case 1:
return getString(R.string.license);
return getString(R.string.about_activity__title_about_license);
case 2:
return getString(R.string.debugging);
return getString(R.string.about_activity__title_debug_info);
}
return null;
}

View file

@ -0,0 +1,197 @@
/*
This file is part of the Diaspora for Android.
Diaspora for Android 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.
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.activity;
import android.content.Context;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaAspect;
import com.github.dfa.diaspora_android.listener.OnSomethingClickListener;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Fragment that shows a list of the Aspects
*/
public class AspectListFragment extends ThemedFragment implements OnSomethingClickListener<Object> {
public static final String TAG = "com.github.dfa.diaspora_android.AspectListFragment";
protected RecyclerView aspectsRecyclerView;
protected App app;
protected DiasporaUrlHelper urls;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
AppLog.d(this, "onCreateView()");
return inflater.inflate(R.layout.recycler_list__fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
aspectsRecyclerView = (RecyclerView) view.findViewById(R.id.fragment_list__recycler_view);
app = (App) getActivity().getApplication();
AppSettings appSettings = app.getSettings();
urls = new DiasporaUrlHelper(appSettings);
aspectsRecyclerView.setHasFixedSize(true);
aspectsRecyclerView.setNestedScrollingEnabled(false);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
aspectsRecyclerView.setLayoutManager(layoutManager);
final AspectAdapter adapter = new AspectAdapter(appSettings, this);
aspectsRecyclerView.setAdapter(adapter);
//Set window title
getActivity().setTitle(R.string.nav_aspects);
}
@Override
public String getFragmentTag() {
return TAG;
}
@Override
public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) {
/* Nothing to do */
}
@Override
public boolean onBackPressed() {
return false;
}
@Override
public void onSomethingClicked(Object null1, Integer null2, String aspectId) {
((MainActivity) getActivity()).openDiasporaUrl(urls.getAspectUrl(aspectId));
}
@Override
protected void applyColorToViews() {
aspectsRecyclerView.invalidate();
}
public static class AspectAdapter extends RecyclerView.Adapter<AspectAdapter.ViewHolder> {
private AppSettings appSettings;
private DiasporaAspect[] aspectList;
private List<String> aspectFavsList;
private OnSomethingClickListener<Object> aspectClickedListener;
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.recycler_view__list_item__text)
public TextView title;
@BindView(R.id.recycler_view__list_item__favourite)
AppCompatImageView favouriteImage;
@BindView(R.id.recycler_view__list_item__root)
RelativeLayout root;
ViewHolder(View v) {
super(v);
ButterKnife.bind(this, v);
}
}
AspectAdapter(AppSettings appSettings, OnSomethingClickListener<Object> aspectClickedListener) {
this.appSettings = appSettings;
this.aspectList = appSettings.getAspects();
this.aspectFavsList = new ArrayList<>(Arrays.asList(appSettings.getAspectFavs()));
this.aspectClickedListener = aspectClickedListener;
}
@Override
public int getItemCount() {
return aspectList.length;
}
@Override
public AspectAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_list__list_item_with_fav, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// Alternating colors
final Context c = holder.root.getContext();
final DiasporaAspect aspect = aspectList[position];
holder.title.setText(aspect.name);
if (position % 2 == 1) {
holder.root.setBackgroundColor(Helpers.getColorFromRessource(c, R.color.alternate_row_color));
}
// Favourite (Star) Image
applyFavouriteImage(holder.favouriteImage, isAspectFaved(aspect.name));
// Click on fav button
holder.favouriteImage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (isAspectFaved(aspect.name)) {
aspectFavsList.remove(aspectFavsList.indexOf(aspect.name));
} else {
aspectFavsList.add(aspect.name);
}
appSettings.setAspectFavs(aspectFavsList);
applyFavouriteImage(holder.favouriteImage, isAspectFaved(aspect.name));
}
});
holder.root.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
aspectClickedListener.onSomethingClicked(null, null, aspect.id + "");
}
});
}
private boolean isAspectFaved(String tag) {
return aspectFavsList.contains(tag);
}
private void applyFavouriteImage(AppCompatImageView imageView, boolean isFaved) {
imageView.setImageResource(isFaved ? R.drawable.ic_star_filled_48px : R.drawable.ic_star_border_black_48px);
imageView.setColorFilter(isFaved ? appSettings.getAccentColor() : 0, PorterDuff.Mode.SRC_ATOP);
}
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -25,13 +25,12 @@ import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -40,30 +39,22 @@ import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.Toast;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.BuildConfig;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaUserProfile;
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.ContextUtils;
import com.github.dfa.diaspora_android.util.DiasporaUrlHelper;
import com.github.dfa.diaspora_android.util.Helpers;
import com.github.dfa.diaspora_android.web.BrowserFragment;
import com.github.dfa.diaspora_android.web.DiasporaStreamWebChromeClient;
import com.github.dfa.diaspora_android.web.FileUploadWebChromeClient;
import com.github.dfa.diaspora_android.web.WebHelper;
import net.gsantner.opoc.util.PermissionChecker;
import net.gsantner.opoc.util.ShareUtil;
import org.json.JSONException;
import java.io.File;
import java.io.IOException;
import java.util.Date;
/**
* Fragment that displays the Stream of the diaspora* user
@ -101,15 +92,13 @@ public class DiasporaStreamFragment extends BrowserFragment {
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.stream__menu_top, menu);
super.onCreateOptionsMenu(menu, inflater);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
menu.findItem(R.id.action_share_pdf).setVisible(true);
}
final boolean darkBg = ContextUtils.get().shouldColorOnTopBeLight(AppSettings.get().getPrimaryColor());
ContextUtils.get().tintMenuItems(menu, true, ContextCompat.getColor(getActivity(), darkBg ? R.color.white : R.color.black));
@Override
public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.stream__menu_bottom, menu);
}
@Override
@ -128,8 +117,6 @@ public class DiasporaStreamFragment extends BrowserFragment {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
AppLog.d(this, "StreamFragment.onOptionsItemSelected()");
ShareUtil shu = new ShareUtil(getContext());
PermissionChecker permc = new PermissionChecker(getActivity());
switch (item.getItemId()) {
case R.id.action_reload: {
if (WebHelper.isOnline(getContext())) {
@ -140,6 +127,11 @@ public class DiasporaStreamFragment extends BrowserFragment {
}
}
case R.id.action_toggle_desktop_page: {
loadUrl(urls.getToggleMobileUrl());
return true;
}
case R.id.action_go_to_top: {
ObjectAnimator anim = ObjectAnimator.ofInt(webView, "scrollY", webView.getScrollY(), 0);
anim.setDuration(400);
@ -152,51 +144,17 @@ public class DiasporaStreamFragment extends BrowserFragment {
sharingIntent.setType("text/plain");
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, webView.getTitle());
sharingIntent.putExtra(Intent.EXTRA_TEXT, webView.getUrl());
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.share_dotdotdot)));
return true;
}
case R.id.action_share_pdf: {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
shu.createPdf(webView, "dandelion-" + ShareUtil.SDF_SHORT.format(new Date()));
}
return true;
}
case R.id.action_share_link_to_clipboard: {
shu.setClipboard(webView.getUrl());
Toast.makeText(getContext(), R.string.link_adress_copied, Toast.LENGTH_SHORT).show();
return true;
}
case R.id.action_create_launcher_shortcut: {
if (webView.getUrl() != null) {
Intent intent = new Intent(getContext(), MainActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(webView.getUrl()));
shu.createLauncherDesktopShortcut(intent, R.drawable.ic_launcher, webView.getTitle());
}
startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.action_share_dotdotdot)));
return true;
}
case R.id.action_take_screenshot: {
if (permc.doIfExtStoragePermissionGranted(getString(R.string.screenshot_permission__appspecific))) {
File fileSaveDirectory = appSettings.getAppSaveDirectory();
if (permc.mkdirIfStoragePermissionGranted(fileSaveDirectory)) {
Bitmap bmp = ShareUtil.getBitmapFromWebView(webView);
String filename = "dandelion-" + ShareUtil.SDF_SHORT.format(new Date()) + ".jpg";
_cu.writeImageToFile(new File(fileSaveDirectory, filename), bmp);
Snackbar.make(webView, getString(R.string.saving_screenshot_as)
+ " " + filename, Snackbar.LENGTH_LONG).show();
}
}
makeScreenshotOfWebView(false);
return true;
}
case R.id.action_share_screenshot: {
if (permc.doIfExtStoragePermissionGranted(getString(R.string.screenshot_permission__appspecific))) {
shu.shareImage(ShareUtil.getBitmapFromWebView(webView));
}
makeScreenshotOfWebView(true);
return true;
}
}
@ -273,10 +231,7 @@ public class DiasporaStreamFragment extends BrowserFragment {
protected DiasporaStreamWebChromeClient.SharedTextCallback sharedTextCallback = new DiasporaStreamWebChromeClient.SharedTextCallback() {
@Override
public String getSharedText() {
if (getActivity() != null) {
return ((MainActivity) getActivity()).getTextToBeShared();
}
return "";
return ((MainActivity) getActivity()).getTextToBeShared();
}
@Override
@ -292,8 +247,8 @@ public class DiasporaStreamFragment extends BrowserFragment {
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)) {
new ThemedAlertDialogBuilder(getContext(), appSettings)
.setMessage(R.string.image_permission_description__appspecific)
new AlertDialog.Builder(getContext())
.setMessage(R.string.permissions_image)
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override
@ -312,13 +267,15 @@ public class DiasporaStreamFragment extends BrowserFragment {
}
}
AppLog.v(this, "onOpenFileChooser");
if (imageUploadFilePathCallbackNew != null)
imageUploadFilePathCallbackNew.onReceiveValue(null);
imageUploadFilePathCallbackNew = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getContext().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile;
try {
photoFile = ContextUtils.get().createImageFile();
photoFile = Helpers.createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
AppLog.e(this, "ERROR creating temp file: " + ex.toString());
@ -371,41 +328,20 @@ public class DiasporaStreamFragment extends BrowserFragment {
@SuppressWarnings("unused")
@JavascriptInterface
public void setUserProfile(final String webMessage) throws JSONException {
final Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
App app = ((App) activity.getApplication());
final DiasporaUserProfile pup = app.getDiasporaUserProfile();
if (pup.isRefreshNeeded()) {
try {
// Try to very fail-safe check if user information gets really loaded from correct pod
if (!webView.getUrl().startsWith(app.getSettings().getPod().getPodUrl().getBaseUrl())) {
return;
}
} catch (Exception ignored) {
return;
}
AppLog.v(this, "DiasporaUserProfile needs refresh; Try to parse JSON");
pup.parseJson(webMessage);
getActivity().runOnUiThread(new Runnable() {
public void run() {
pup.analyzeUrl(webView.getUrl());
}
});
}
}
});
DiasporaUserProfile pup = ((App) getActivity().getApplication()).getDiasporaUserProfile();
AppLog.spam(this, "StreamFragment.JavaScriptInterface.setUserProfile()");
if (pup.isRefreshNeeded()) {
AppLog.v(this, "DiasporaUserProfile needs refresh; Try to parse JSON");
pup.parseJson(webMessage);
} else {
AppLog.spam(this, "No DiasporaUserProfile refresh needed");
}
}
@SuppressWarnings("unused")
@JavascriptInterface
public void contentHasBeenShared() {
if (getActivity() != null) {
((MainActivity) getActivity()).setTextToBeShared(null);
}
((MainActivity) getActivity()).setTextToBeShared(null);
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -25,8 +25,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Bundle;
@ -36,15 +34,12 @@ import android.support.customtabs.CustomTabsSession;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import android.view.KeyEvent;
import android.view.Menu;
@ -63,7 +58,6 @@ import android.widget.Toast;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaAspect;
import com.github.dfa.diaspora_android.data.DiasporaPodList;
import com.github.dfa.diaspora_android.data.DiasporaUserProfile;
import com.github.dfa.diaspora_android.listener.DiasporaUserProfileChangedListener;
@ -72,16 +66,11 @@ import com.github.dfa.diaspora_android.receiver.OpenExternalLinkReceiver;
import com.github.dfa.diaspora_android.receiver.UpdateTitleReceiver;
import com.github.dfa.diaspora_android.ui.BadgeDrawable;
import com.github.dfa.diaspora_android.ui.PodSelectionDialog;
import com.github.dfa.diaspora_android.ui.SearchOrCustomTextDialogCreator;
import com.github.dfa.diaspora_android.ui.theme.CustomFragment;
import com.github.dfa.diaspora_android.ui.theme.ThemeHelper;
import com.github.dfa.diaspora_android.ui.theme.ThemedActivity;
import com.github.dfa.diaspora_android.ui.theme.ThemedAlertDialogBuilder;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
import com.github.dfa.diaspora_android.util.ActivityUtils;
import com.github.dfa.diaspora_android.util.AndroidBug5497Workaround;
import com.github.dfa.diaspora_android.util.AppLog;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
import com.github.dfa.diaspora_android.util.DiasporaUrlHelper;
import com.github.dfa.diaspora_android.web.BrowserFragment;
import com.github.dfa.diaspora_android.web.ContextMenuWebView;
@ -89,13 +78,8 @@ 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 net.gsantner.opoc.format.markdown.SimpleMarkdownParser;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends ThemedActivity
implements NavigationView.OnNavigationItemSelectedListener,
@ -121,13 +105,14 @@ public class MainActivity extends ThemedActivity
private App app;
private CustomTabActivityHelper customTabActivityHelper;
private AppSettings _appSettings;
private AppSettings appSettings;
private DiasporaUrlHelper urls;
private DiasporaUserProfile diasporaUserProfile;
private final Handler uiHandler = new Handler();
private OpenExternalLinkReceiver brOpenExternalLink;
private BroadcastReceiver brSetTitle;
private Snackbar snackbarExitApp, snackbarNoInternet, snackbarLastVisitedTimestampInStream;
private Snackbar snackbarExitApp;
private Snackbar snackbarNoInternet;
private FragmentManager fm;
private CustomTabsSession customTabsSession;
@ -140,6 +125,9 @@ public class MainActivity extends ThemedActivity
@BindView(R.id.main__topbar)
Toolbar toolbarTop;
@BindView(R.id.main__bottombar)
ActionMenuView toolbarBottom;
@BindView(R.id.fragment_container)
FrameLayout fragmentContainer;
@ -171,26 +159,17 @@ public class MainActivity extends ThemedActivity
super.onCreate(savedInstanceState);
AppLog.v(this, "onCreate()");
// Pre UI
ContextUtils.get().setAppLanguage(AppSettings.get().getLanguage());
if (AppSettings.get().isEditorStatusBarHidden()) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
// Bind UI
setContentView(R.layout.main__activity);
ButterKnife.bind(this);
if (AppSettings.get().isEditorStatusBarHidden()) {
AndroidBug5497Workaround.assistActivity(this);
}
app = (App) getApplication();
_appSettings = app.getSettings();
diasporaUserProfile = app.getDiasporaUserProfile();
if ((app = (App) getApplication()) == null) AppLog.e(this, "App is null!");
if ((appSettings = app.getSettings()) == null) AppLog.e(this, "AppSettings is null!");
if ((diasporaUserProfile = app.getDiasporaUserProfile()) == null)
AppLog.e(this, "DiasporaUserProfile is null!");
diasporaUserProfile.setCallbackHandler(uiHandler);
diasporaUserProfile.setListener(this);
urls = new DiasporaUrlHelper(_appSettings);
urls = new DiasporaUrlHelper(appSettings);
customTabActivityHelper = new CustomTabActivityHelper();
customTabActivityHelper.setConnectionCallback(this);
ProxyHandler.getInstance().updateProxySettings(this);
@ -200,23 +179,24 @@ public class MainActivity extends ThemedActivity
brOpenExternalLink = new OpenExternalLinkReceiver(this);
brSetTitle = new UpdateTitleReceiver(app, urls, new UpdateTitleReceiver.TitleCallback() {
public void setTitle(String url, int resId) {
ThemedFragment top = getTopFragment();
@Override
public void setTitle(int rId) {
CustomFragment top = getTopFragment();
if (top != null && top.getFragmentTag().equals(DiasporaStreamFragment.TAG)) {
MainActivity.this.setTitle(resId);
showLastVisitedTimestampMessageIfNeeded(url);
MainActivity.this.setTitle(rId);
}
}
public void setTitle(String url, String title) {
ThemedFragment top = getTopFragment();
@Override
public void setTitle(String title) {
CustomFragment top = getTopFragment();
if (top != null && top.getFragmentTag().equals(DiasporaStreamFragment.TAG)) {
MainActivity.this.setTitle(title);
}
}
});
if (!_appSettings.hasPod()) {
if (!appSettings.hasPod()) {
AppLog.d(this, "We have no pod. Show PodSelectionFragment");
updateNavigationViewEntryVisibilities();
showFragment(getFragment(PodSelectionFragment.TAG));
@ -230,21 +210,6 @@ public class MainActivity extends ThemedActivity
openDiasporaUrl(urls.getStreamUrl());
}
}
// Show first start / update dialog
try {
if (_appSettings.isAppCurrentVersionFirstStart(true)) {
SimpleMarkdownParser smp = SimpleMarkdownParser.get().setDefaultSmpFilter(SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW);
String html = "";
html += smp.parse(getString(R.string.copyright_license_text_official).replace("\n", " \n"), "").getHtml();
html += "<br/><br/><br/><big><big>" + getString(R.string.changelog) + "</big></big><br/>" + smp.parse(getResources().openRawResource(R.raw.changelog), "", SimpleMarkdownParser.FILTER_ANDROID_TEXTVIEW, SimpleMarkdownParser.FILTER_CHANGELOG).getHtml();
html += "<br/><br/><br/><big><big>" + getString(R.string.licenses) + "</big></big><br/>" + smp.parse(getResources().openRawResource(R.raw.licenses_3rd_party), "").getHtml();
ActivityUtils _au = new ActivityUtils(this);
_au.showDialogWithHtmlTextView(R.string.licenses, html);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
@ -254,32 +219,27 @@ public class MainActivity extends ThemedActivity
private void setupUI() {
AppLog.i(this, "setupUI()");
// Setup _toolbar
// Setup toolbar
setSupportActionBar(toolbarTop);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
toolbarBottom.setOnMenuItemClickListener(new ActionMenuView.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
CustomFragment top = getTopFragment();
return MainActivity.this.onOptionsItemSelected(item) || (top != null && top.onOptionsItemSelected(item));
}
});
setTitle(R.string.app_name);
//Setup snackbar
snackbarExitApp = Snackbar
.make(fragmentContainer, R.string.do_you_want_to_exit, Snackbar.LENGTH_LONG)
.make(fragmentContainer, R.string.confirm_exit, Snackbar.LENGTH_LONG)
.setAction(android.R.string.yes, new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
moveTaskToBack(true);
}
});
snackbarLastVisitedTimestampInStream =
Snackbar.make(fragmentContainer,
R.string.jump_to_last_visited_page_in_stream__appspecific, 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.sorry_need_to_be_connected_to_internet, Snackbar.LENGTH_LONG);
snackbarNoInternet = Snackbar.make(fragmentContainer, R.string.no_internet, Snackbar.LENGTH_LONG);
// Load app settings
setupNavigationSlider();
@ -287,15 +247,27 @@ public class MainActivity extends ThemedActivity
}
/**
* Get an instance of the ThemedFragment with the tag fragmentTag.
* Show DiasporaStreamFragment if necessary and load URL url
*
* @param url URL to load in the DiasporaStreamFragment
*/
public void openDiasporaUrl(String url) {
AppLog.v(this, "openDiasporaUrl()");
DiasporaStreamFragment streamFragment = (DiasporaStreamFragment) getFragment(DiasporaStreamFragment.TAG);
showFragment(streamFragment);
streamFragment.loadUrl(url);
}
/**
* 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
*/
protected ThemedFragment getFragment(String fragmentTag) {
ThemedFragment fragment = (ThemedFragment) fm.findFragmentByTag(fragmentTag);
protected CustomFragment getFragment(String fragmentTag) {
CustomFragment fragment = (CustomFragment) fm.findFragmentByTag(fragmentTag);
if (fragment != null) {
return fragment;
} else {
@ -308,6 +280,14 @@ public class MainActivity extends ThemedActivity
BrowserFragment bf = new BrowserFragment();
fm.beginTransaction().add(bf, fragmentTag).commit();
return bf;
case TagListFragment.TAG:
TagListFragment hlf = new TagListFragment();
fm.beginTransaction().add(hlf, fragmentTag).commit();
return hlf;
case AspectListFragment.TAG:
AspectListFragment alf = new AspectListFragment();
fm.beginTransaction().add(alf, fragmentTag).commit();
return alf;
case PodSelectionFragment.TAG:
PodSelectionFragment psf = new PodSelectionFragment();
fm.beginTransaction().add(psf, fragmentTag).commit();
@ -320,64 +300,23 @@ public class MainActivity extends ThemedActivity
}
}
/**
* Show DiasporaStreamFragment if necessary and load URL url
*
* @param url URL to load in the DiasporaStreamFragment
*/
public void openDiasporaUrl(final String url) {
AppLog.v(this, "openDiasporaUrl()");
if (url != null && url.startsWith("http://127.0.0.1")) {
// This URL seems to be called somehow, but it doesn't make sense ;)
toolbarTop.postDelayed(() -> {
Intent i = new Intent(ACTION_OPEN_EXTERNAL_URL);
i.putExtra(EXTRA_URL, "https://github.com/gsantner/dandelion/blob/master/README.md");
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
}, 1000);
return;
}
if (_appSettings.getPod() != null && _appSettings.getPod().getPodUrl() != null && _appSettings.getPod().getPodUrl().getBaseUrl() != null
&& url.startsWith(_appSettings.getPod().getPodUrl().getBaseUrl()) && !url.startsWith("https://dia.so/")) {
DiasporaStreamFragment streamFragment = (DiasporaStreamFragment) getFragment(DiasporaStreamFragment.TAG);
showFragment(streamFragment);
showLastVisitedTimestampMessageIfNeeded(url);
streamFragment.loadUrl(url);
} else {
toolbarTop.postDelayed(() -> {
Intent i = new Intent(ACTION_OPEN_EXTERNAL_URL);
i.putExtra(EXTRA_URL, url);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
}, 1000);
}
}
public void showLastVisitedTimestampMessageIfNeeded(String url) {
if (url.equals(urls.getStreamUrl()) && diasporaUserProfile.hasLastVisitedTimestampInStream()) {
snackbarLastVisitedTimestampInStream.show();
diasporaUserProfile.resetLastVisitedPositionInStream();
}
}
/**
* 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(ThemedFragment fragment) {
if (PodSelectionFragment.TAG.equals(fragment.getTag())) {
Fragment fragment1 = fm.findFragmentByTag(DiasporaStreamFragment.TAG);
if (fragment1 != null) {
new net.gsantner.opoc.util.ContextUtils(this).restartApp(MainActivity.class);
}
}
protected void showFragment(CustomFragment fragment) {
AppLog.v(this, "showFragment()");
ThemedFragment currentTop = (ThemedFragment) fm.findFragmentById(R.id.fragment_container);
CustomFragment currentTop = (CustomFragment) fm.findFragmentById(R.id.fragment_container);
if (currentTop == null || !currentTop.getFragmentTag().equals(fragment.getFragmentTag())) {
AppLog.v(this, "Fragment was not visible. Replace it.");
fm.beginTransaction().addToBackStack(null).replace(R.id.fragment_container, fragment, fragment.getFragmentTag()).commit();
invalidateOptionsMenu();
setToolbarIntellihide(_appSettings.isIntellihideToolbars() && fragment.isAllowedIntellihide());
if (appSettings.isIntellihideToolbars() && fragment.isAllowedIntellihide()) {
this.enableToolbarHiding();
} else {
this.disableToolbarHiding();
}
} else {
AppLog.v(this, "Fragment was already visible. Do nothing.");
}
@ -388,7 +327,7 @@ public class MainActivity extends ThemedActivity
*/
private void setupNavigationSlider() {
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, navDrawer, toolbarTop, R.string.open_navdrawer, R.string.close_navdrawer);
this, navDrawer, toolbarTop, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
navDrawer.addDrawerListener(toggle);
toggle.syncState();
@ -400,10 +339,13 @@ public class MainActivity extends ThemedActivity
navDrawerLayout = ButterKnife.findById(navHeader, R.id.nav_drawer);
//Handle clicks on profile picture
navProfilePictureArea.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
navDrawer.closeDrawer(GravityCompat.START);
if (!_appSettings.getProfileId().equals("")) {
if (WebHelper.isOnline(MainActivity.this)) {
openDiasporaUrl(urls.getProfileUrl());
} else {
snackbarNoInternet.show();
}
}
});
@ -411,13 +353,13 @@ public class MainActivity extends ThemedActivity
navheaderDescription = ButterKnife.findById(navHeader, R.id.podselection__podupti_notice);
navheaderImage = ButterKnife.findById(navHeader, R.id.navheader_user_image);
if (!_appSettings.getName().equals("")) {
navheaderTitle.setText(_appSettings.getName());
if (!appSettings.getName().equals("")) {
navheaderTitle.setText(appSettings.getName());
}
if (_appSettings.getPod() != null) {
navheaderDescription.setText(_appSettings.getPod().getName());
if (appSettings.getPod() != null) {
navheaderDescription.setText(appSettings.getPod().getName());
}
String avatarUrl = _appSettings.getAvatarUrl();
String avatarUrl = appSettings.getAvatarUrl();
if (!avatarUrl.equals("")) {
//Display app launcher icon instead of default avatar asset
//(Which would by the way not load because of missing pod domain prefix in the url)
@ -443,43 +385,26 @@ public class MainActivity extends ThemedActivity
navMenu.setGroupVisible(navMenu.findItem(R.id.nav_exit).getGroupId(), true);
// Hide by app settings
navMenu.findItem(R.id.nav_exit).setVisible(_appSettings.isVisibleInNavExit());
navMenu.findItem(R.id.nav_activities).setVisible(_appSettings.isVisibleInNavActivities());
navMenu.findItem(R.id.nav_aspects).setVisible(_appSettings.isVisibleInNavAspects());
navMenu.findItem(R.id.nav_contacts).setVisible(_appSettings.isVisibleInNavContacts());
navMenu.findItem(R.id.nav_commented).setVisible(_appSettings.isVisibleInNavCommented());
navMenu.findItem(R.id.nav_followed_tags).setVisible(_appSettings.isVisibleInNavFollowed_tags());
navMenu.findItem(R.id.nav_about).setVisible(_appSettings.isVisibleInNavHelp_license());
navMenu.findItem(R.id.nav_liked).setVisible(_appSettings.isVisibleInNavLiked());
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());
navMenu.findItem(R.id.nav_exit).setVisible(appSettings.isVisibleInNavExit());
navMenu.findItem(R.id.nav_activities).setVisible(appSettings.isVisibleInNavActivities());
navMenu.findItem(R.id.nav_aspects).setVisible(appSettings.isVisibleInNavAspects());
navMenu.findItem(R.id.nav_contacts).setVisible(appSettings.isVisibleInNavContacts());
navMenu.findItem(R.id.nav_commented).setVisible(appSettings.isVisibleInNavCommented());
navMenu.findItem(R.id.nav_followed_tags).setVisible(appSettings.isVisibleInNavFollowed_tags());
navMenu.findItem(R.id.nav_about).setVisible(appSettings.isVisibleInNavHelp_license());
navMenu.findItem(R.id.nav_liked).setVisible(appSettings.isVisibleInNavLiked());
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());
navMenu.findItem(R.id.nav_stream).setVisible(true);
navMenu.findItem(R.id.nav_statistics).setVisible(_appSettings.isVisibleInNavStatistics());
navMenu.findItem(R.id.nav_reports).setVisible(_appSettings.isVisibleInNavReports());
navMenu.findItem(R.id.nav_toggle_desktop_page).setVisible(_appSettings.isVisibleInNavToggleMobileDesktop());
navMenu.findItem(R.id.nav_product_support).setVisible(_appSettings.isVisibleInNavGsantnerAccount());
// Hide whole group (for logged in use) if no pod was selected
if (!_appSettings.hasPod()) {
if (!appSettings.hasPod()) {
navMenu.setGroupVisible(navMenu.findItem(R.id.nav_exit).getGroupId(), false);
}
}
/**
* Open Stream when clicked on top _toolbar AND preference stream shortcut is true
*
* @param view selected view
*/
@OnClick(R.id.main__topbar)
public void onToolBarClicked(View view) {
AppLog.i(this, "onToolBarClicked()");
if (_appSettings.isTopbarStreamShortcutEnabled() && _appSettings.hasPod()) {
onNavigationItemSelected(navView.getMenu().findItem(R.id.nav_stream));
}
}
/**
* Forward incoming intents to handleIntent()
*
@ -522,12 +447,10 @@ public class MainActivity extends ThemedActivity
}
} else if (ACTION_CHANGE_ACCOUNT.equals(action)) {
AppLog.v(this, "Reset pod data and show PodSelectionFragment");
_appSettings.setPod(null);
appSettings.setPod(null);
runOnUiThread(new Runnable() {
@Override
public void run() {
navheaderTitle.setText(R.string.app_name);
navheaderDescription.setText(R.string.app_subtitle);
navheaderImage.setImageResource(R.drawable.ic_launcher);
app.resetPodData(((DiasporaStreamFragment) getFragment(DiasporaStreamFragment.TAG)).getWebView());
}
});
@ -535,6 +458,7 @@ public class MainActivity extends ThemedActivity
} else if (ACTION_CLEAR_CACHE.equals(action)) {
AppLog.v(this, "Clear WebView cache");
runOnUiThread(new Runnable() {
@Override
public void run() {
ContextMenuWebView wv = ((DiasporaStreamFragment) getFragment(DiasporaStreamFragment.TAG)).getWebView();
if (wv != null) {
@ -559,21 +483,9 @@ public class MainActivity extends ThemedActivity
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
/* TODO: Implement and add filter to manifest */
return;
} else if ("sc_new_post".equals(action)) {
openDiasporaUrl(urls.getNewPostUrl());
return;
} else if ("sc_activities".equals(action)) {
openDiasporaUrl(urls.getActivityUrl());
return;
} else if ("sc_contacts".equals(action)) {
onNavigationItemSelected(navView.getMenu().findItem(R.id.nav_aspects));
return;
} else if ("sc_tags".equals(action)) {
onNavigationItemSelected(navView.getMenu().findItem(R.id.nav_followed_tags));
return;
}
//Catch split screen recreation
if (action != null && action.equals(Intent.ACTION_MAIN) && getTopFragment() != null) {
if (action.equals(Intent.ACTION_MAIN) && getTopFragment() != null) {
return;
}
@ -601,8 +513,8 @@ public class MainActivity extends ThemedActivity
*
* @return top fragment or null if there is none displayed
*/
private ThemedFragment getTopFragment() {
return (ThemedFragment) fm.findFragmentById(R.id.fragment_container);
private CustomFragment getTopFragment() {
return (CustomFragment) fm.findFragmentById(R.id.fragment_container);
}
/**
@ -615,7 +527,7 @@ public class MainActivity extends ThemedActivity
navDrawer.closeDrawer(navView);
return;
}
ThemedFragment top = getTopFragment();
CustomFragment top = getTopFragment();
if (top != null) {
AppLog.v(this, "Top Fragment is not null");
if (!top.onBackPressed()) {
@ -667,52 +579,48 @@ public class MainActivity extends ThemedActivity
LocalBroadcastManager.getInstance(this).registerReceiver(brSetTitle, new IntentFilter(ACTION_UPDATE_TITLE_FROM_URL));
LocalBroadcastManager.getInstance(this).registerReceiver(brOpenExternalLink, new IntentFilter(ACTION_OPEN_EXTERNAL_URL));
invalidateOptionsMenu();
_appSettings = getAppSettings();
if (_appSettings.isRecreateMainActivity()) {
recreate();
}
setToolbarIntellihide(_appSettings.isIntellihideToolbars());
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayShowTitleEnabled(AppSettings.get().isShowTitleInMainView());
this.appSettings = getAppSettings();
if (appSettings.isIntellihideToolbars()) {
enableToolbarHiding();
} else {
disableToolbarHiding();
}
updateNavigationViewEntryVisibilities();
}
/**
* Clear and repopulate top and bottom _toolbar.
* Clear and repopulate top and bottom toolbar.
* Also add menu items of the displayed fragment
*
* @param menu top _toolbar
* @param menu top toolbar
* @return boolean
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
AppLog.v(this, "onCreateOptionsMenu()");
boolean cache;
//Clear the menus
menu.clear();
toolbarBottom.getMenu().clear();
toolbarBottom.setVisibility(View.VISIBLE);
ThemedFragment top = getTopFragment();
CustomFragment top = getTopFragment();
if (top != null) {
if (!top.getFragmentTag().equals(PodSelectionFragment.TAG)) {
cache = _appSettings.isExtendedNotificationsActivated();
getMenuInflater().inflate(R.menu.main__menu_top, menu);
menu.findItem(R.id.action_notifications).setVisible(!cache);
menu.findItem(R.id.action_notifications_extended).setVisible(cache);
//PodSelectionFragment?
if (top.getFragmentTag().equals(PodSelectionFragment.TAG)) {
///Hide bottom toolbar
toolbarBottom.setVisibility(View.GONE);
} else {
getMenuInflater().inflate(appSettings.isExtendedNotificationsActivated() ?
R.menu.main__menu_top__notifications_dropdown : R.menu.main__menu_top, menu);
getMenuInflater().inflate(R.menu.main__menu_bottom, toolbarBottom.getMenu());
top.onCreateBottomOptionsMenu(toolbarBottom.getMenu(), getMenuInflater());
}
}
ContextUtils cu = ContextUtils.get();
final boolean darkBg = cu.get().shouldColorOnTopBeLight(AppSettings.get().getPrimaryColor());
cu.tintMenuItems(menu, true, ContextCompat.getColor(this, darkBg ? R.color.white : R.color.black));
cu.setSubMenuIconsVisiblity(menu, true);
return true;
}
/**
* Set the notification and messages counter in the top _toolbar
* Set the notification and messages counter in the top toolbar
*
* @param menu menu
* @return boolean
@ -745,7 +653,7 @@ public class MainActivity extends ThemedActivity
AppLog.i(this, "onOptionsItemSelected()");
switch (item.getItemId()) {
case R.id.action_notifications: {
if (_appSettings.isExtendedNotificationsActivated()) {
if (appSettings.isExtendedNotificationsActivated()) {
return true;
}
//Otherwise we execute the action of action_notifications_all
@ -831,6 +739,12 @@ public class MainActivity extends ThemedActivity
}
}
case R.id.action_exit: {
moveTaskToBack(true);
finish();
return true;
}
case R.id.action_compose: {
if (WebHelper.isOnline(MainActivity.this)) {
openDiasporaUrl(urls.getNewPostUrl());
@ -844,17 +758,14 @@ public class MainActivity extends ThemedActivity
if (WebHelper.isOnline(MainActivity.this)) {
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
@SuppressLint("InflateParams") View layout = getLayoutInflater().inflate(R.layout.ui__dialog_search__people_tags, null, false);
final EditText input = layout.findViewById(R.id.dialog_search__input);
input.setMaxLines(1);
input.setSingleLine(true);
ThemeHelper.updateEditTextColor(input);
View layout = getLayoutInflater().inflate(R.layout.ui__dialog_search__people_tags, null, false);
final EditText input = (EditText) layout.findViewById(R.id.dialog_search__input);
final DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int which) {
String query = input.getText().toString().trim().replaceAll((which == DialogInterface.BUTTON_NEGATIVE ? "\\*" : "\\#"), "");
if (query.equals("")) {
Snackbar.make(fragmentContainer, R.string.please_add_a_name, Snackbar.LENGTH_LONG).show();
Snackbar.make(fragmentContainer, R.string.search_alert_bypeople_validate_needsomedata, Snackbar.LENGTH_LONG).show();
} else {
openDiasporaUrl(which == DialogInterface.BUTTON_NEGATIVE ? urls.getSearchPeopleUrl(query) : urls.getSearchTagsUrl(query));
}
@ -863,11 +774,11 @@ public class MainActivity extends ThemedActivity
}
};
final AlertDialog dialog = new ThemedAlertDialogBuilder(this, _appSettings)
final android.support.v7.app.AlertDialog dialog = new android.support.v7.app.AlertDialog.Builder(this)
.setView(layout).setTitle(R.string.search_alert_title)
.setCancelable(true)
.setPositiveButton(R.string.by_tags, clickListener)
.setNegativeButton(R.string.by_people, clickListener)
.setPositiveButton(R.string.search_alert_tag, clickListener)
.setNegativeButton(R.string.search_alert_people, clickListener)
.create();
input.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@ -969,9 +880,9 @@ public class MainActivity extends ThemedActivity
private void setSharedTexts(String sharedSubject, String sharedBody) {
AppLog.i(this, "setSharedTexts()");
String body = WebHelper.replaceUrlWithMarkdown(sharedBody);
if (_appSettings.isAppendSharedViaApp()) {
if (appSettings.isAppendSharedViaApp()) {
AppLog.v(this, "Append app reference to shared text");
body = body + "\n\n" + getString(R.string.shared_via_app);
body = body + "\n\n" + getString(R.string.shared_by_diaspora_android);
}
final String escapedBody = WebHelper.escapeHtmlText(body);
if (sharedSubject != null) {
@ -980,7 +891,7 @@ public class MainActivity extends ThemedActivity
AppLog.v(this, "Set shared text; Subject: \"" + escapedSubject + "\" Body: \"" + escapedBody + "\"");
textToBeShared = "**" + escapedSubject + "** " + escapedBody;
} else {
AppLog.v(this, "Set shared text; Subject: \"null\" Body: \"" + sharedBody + "\"");
AppLog.v(this, "Set shared text; Subject: \"" + sharedSubject + "\" Body: \"" + sharedBody + "\"");
textToBeShared = escapedBody;
}
}
@ -1006,7 +917,7 @@ public class MainActivity extends ThemedActivity
public void onNotificationCountChanged(DiasporaUserProfile diasporaUserProfile, int notificationCount) {
AppLog.i(this, "onNotificationCountChanged()");
// Count saved in DiasporaUserProfile
// Invalidate the top _toolbar to update the unread messages counter
// Invalidate the top toolbar to update the unread messages counter
invalidateOptionsMenu();
}
@ -1015,7 +926,7 @@ public class MainActivity extends ThemedActivity
public void onUnreadMessageCountChanged(DiasporaUserProfile diasporaUserProfile, int unreadMessageCount) {
AppLog.i(this, "onUnreadMessageCountChanged()");
// Count saved in DiasporaUserProfile
// Invalidate the top _toolbar to update the unread messages counter
// Invalidate the top toolbar to update the unread messages counter
invalidateOptionsMenu();
}
@ -1056,58 +967,33 @@ public class MainActivity extends ThemedActivity
break;
case R.id.nav_profile: {
if (!_appSettings.getProfileId().equals("")) {
openDiasporaUrl(urls.getProfileUrl());
}
}
break;
case R.id.nav_followed_tags: {
SearchOrCustomTextDialogCreator.showDiasporaTagsDialog(this, arg -> {
if (arg.startsWith(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX)) {
arg = arg.replace(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX, "").trim();
if (arg.equals(getString(R.string.manage_hashtags))) {
openDiasporaUrl(urls.getManageTagsUrl());
} else {
openDiasporaUrl(urls.getAllFollowedTagsUrl());
}
} else {
openDiasporaUrl(urls.getSearchTagsUrl(arg));
}
});
}
break;
case R.id.nav_aspects: {
SearchOrCustomTextDialogCreator.showDiasporaAspectsDialog(this, arg -> {
if (arg.startsWith(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX)) {
arg = arg.replace(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX, "").trim();
if (arg.equals(getString(R.string.manage_your_contact_list))) {
openDiasporaUrl(urls.getContactsUrl());
} else if (arg.equals(getString(R.string.nav_profile))) {
openDiasporaUrl(urls.getProfileUrl());
}
} else {
for (DiasporaAspect daspect : _appSettings.getAspects()) {
if (arg.equals(daspect.name)) {
openDiasporaUrl(urls.getAspectUrl(Long.toString(daspect.id)));
break;
}
}
}
});
}
break;
case R.id.nav_contacts: {
if (WebHelper.isOnline(MainActivity.this)) {
openDiasporaUrl(urls.getContactsUrl());
openDiasporaUrl(urls.getProfileUrl());
} else {
snackbarNoInternet.show();
}
}
break;
case R.id.nav_followed_tags: {
showFragment(getFragment(TagListFragment.TAG));
}
break;
//TODO: Replace with fragment
case R.id.nav_aspects: {
showFragment(getFragment(AspectListFragment.TAG));
}
break;
case R.id.nav_contacts: {
if (WebHelper.isOnline(MainActivity.this)) {
openDiasporaUrl(urls.getManageContactsUrl());
} else {
snackbarNoInternet.show();
}
}
case R.id.nav_activities: {
if (WebHelper.isOnline(MainActivity.this)) {
openDiasporaUrl(urls.getActivityUrl());
@ -1141,8 +1027,8 @@ public class MainActivity extends ThemedActivity
} else {
snackbarNoInternet.show();
}
break;
}
break;
case R.id.nav_public: {
if (WebHelper.isOnline(MainActivity.this)) {
@ -1150,42 +1036,14 @@ public class MainActivity extends ThemedActivity
} else {
snackbarNoInternet.show();
}
break;
}
break;
case R.id.nav_reports: {
if (WebHelper.isOnline(MainActivity.this)) {
openDiasporaUrl(urls.getReportsUrl());
} else {
snackbarNoInternet.show();
}
}
break;
case R.id.nav_statistics: {
if (WebHelper.isOnline(MainActivity.this)) {
openDiasporaUrl(urls.getStatisticsUrl());
} else {
snackbarNoInternet.show();
}
}
break;
case R.id.nav_toggle_desktop_page: {
openDiasporaUrl(urls.getToggleMobileUrl());
}
break;
case R.id.nav_product_support: {
openDiasporaUrl(urls.getProfileUrl("d1cbdd70095301341e834860008dbc6c"));
}
break;
case R.id.nav_exit: {
moveTaskToBack(true);
finish();
break;
}
break;
case R.id.nav_settings: {
startActivity(new Intent(this, SettingsActivity.class));
@ -1240,7 +1098,7 @@ public class MainActivity extends ThemedActivity
/**
* Set the string that will be shared into the new-post-editor
*
* @param textToBeShared text that will be shared into the post-editor
* @param textToBeShared
*/
public void setTextToBeShared(String textToBeShared) {
this.textToBeShared = textToBeShared;
@ -1249,31 +1107,25 @@ public class MainActivity extends ThemedActivity
@Override
protected void applyColorToViews() {
ThemeHelper.updateToolbarColor(toolbarTop);
navDrawerLayout.setBackgroundColor(_appSettings.getPrimaryColor());
navProfilePictureArea.setBackgroundColor(_appSettings.getPrimaryColor());
if (_appSettings.isAmoledColorMode()) {
navView.setItemTextColor(ColorStateList.valueOf(Color.GRAY));
navView.setItemIconTintList(ColorStateList.valueOf(Color.GRAY));
navView.setBackgroundColor(Color.BLACK);
navheaderTitle.setTextColor(Color.GRAY);
navheaderDescription.setTextColor(Color.DKGRAY);
}
int popupTheme = ContextUtils.get().shouldColorOnTopBeLight(AppSettings.get().getPrimaryColor())
? R.style.AppTheme_PopupOverlay_Dark : R.style.AppTheme_PopupOverlay_Light;
toolbarTop.setPopupTheme(popupTheme);
ThemeHelper.updateActionMenuViewColor(toolbarBottom);
navDrawerLayout.setBackgroundColor(appSettings.getPrimaryColor());
navProfilePictureArea.setBackgroundColor(appSettings.getPrimaryColor());
}
public void setToolbarIntellihide(boolean enable) {
@Override
public void enableToolbarHiding() {
AppLog.d(this, "Enable Intellihide");
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) toolbarTop.getLayoutParams();
if (enable) {
AppLog.d(this, "Enable Intellihide");
params.setScrollFlags(toolbarDefaultScrollFlags);
} else {
AppLog.d(this, "Disable Intellihide");
params.setScrollFlags(0); // clear all scroll flags
}
//scroll|enterAlways|snap
params.setScrollFlags(toolbarDefaultScrollFlags);
appBarLayout.setExpanded(true, true);
}
}
@Override
public void disableToolbarHiding() {
AppLog.d(this, "Disable Intellihide");
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) toolbarTop.getLayoutParams();
params.setScrollFlags(0); // clear all scroll flags
appBarLayout.setExpanded(true, true);
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -22,16 +22,13 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -41,7 +38,6 @@ import android.webkit.CookieManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.github.dfa.diaspora_android.App;
@ -51,10 +47,10 @@ import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod;
import com.github.dfa.diaspora_android.service.FetchPodsService;
import com.github.dfa.diaspora_android.ui.PodSelectionDialog;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
import com.github.dfa.diaspora_android.util.ActivityUtils;
import com.github.dfa.diaspora_android.util.AppLog;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
import com.github.dfa.diaspora_android.util.DiasporaUrlHelper;
import com.github.dfa.diaspora_android.util.Helpers;
import org.json.JSONException;
import org.json.JSONObject;
@ -76,13 +72,6 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
@BindView(R.id.podselection__fragment__listpods)
protected ListView listViewPod;
@BindView(R.id.podselection__fragment__root)
RelativeLayout rootView;
@BindView(R.id.podselection__fragment__button_use_custom_pod)
AppCompatButton buttonUseCustomPod;
protected App app;
protected AppSettings appSettings;
private DiasporaPodList podList;
@ -90,14 +79,16 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
private String filterString = "";
@Override
protected int getLayoutResId() {
return R.layout.podselection__fragment;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
AppLog.d(this, "onCreateView()");
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);
ButterKnife.bind(this, view);
app = (App) getActivity().getApplication();
appSettings = app.getSettings();
@ -125,11 +116,11 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
}
});
LocalBroadcastManager.getInstance(getContext()).registerReceiver(podListReceiver, new IntentFilter(FetchPodsService.MESSAGE_PODS_RECEIVED));
ActivityUtils.get(getActivity()).showInfoIfUserNotConnectedToInternet(listViewPod);
Helpers.showInfoIfUserNotConnectedToInternet(getContext(), listViewPod);
}
public void mergePodlistWithRessources(DiasporaPodList podlist) {
String sPodlist = ContextUtils.get().readTextfileFromRawRes(R.raw.podlist, "", "");
String sPodlist = Helpers.readTextfileFromRawRessource(getContext(), R.raw.podlist, "", "");
try {
JSONObject jPodlist = new JSONObject(sPodlist);
podlist.mergeWithNewerEntries(new DiasporaPodList().fromJson(jPodlist));
@ -161,7 +152,7 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
} catch (JSONException ignored) {
}
} else {
Snackbar.make(listViewPod, R.string.could_not_retrieve_list_of_pods__appspecific, Snackbar.LENGTH_SHORT).show();
Snackbar.make(listViewPod, R.string.podlist_error, Snackbar.LENGTH_SHORT).show();
}
}
}
@ -169,14 +160,7 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
@Override
protected void applyColorToViews() {
int dividerHeight = listViewPod.getDividerHeight();
rootView.setBackgroundColor(appSettings.isAmoledColorMode() ? Color.BLACK : Color.WHITE);
listViewPod.setDivider(new ColorDrawable(Color.GRAY));
listViewPod.setDividerHeight(dividerHeight);
int bgcolor = appSettings.isAmoledColorMode() ? Color.DKGRAY : appSettings.getAccentColor();
buttonUseCustomPod.setBackgroundColor(bgcolor);
buttonUseCustomPod.setTextColor(_cu.shouldColorOnTopBeLight(bgcolor) ? Color.WHITE : Color.BLACK);
/* Not really anything to do. Maybe later */
}
@Override
@ -192,18 +176,10 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
listedPodsList.add(pod.getPodUrl().getHost());
}
listViewPodAdapter = new ArrayAdapter<String>(
listViewPodAdapter = new ArrayAdapter<>(
getContext(),
android.R.layout.simple_list_item_1,
listedPodsList) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView textView = view.findViewById(android.R.id.text1);
textView.setTextColor(appSettings.isAmoledColorMode() ? Color.GRAY : Color.BLACK);
return view;
}
};
listedPodsList);
// save index and top position
int index = listViewPod.getFirstVisiblePosition();
@ -228,7 +204,6 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.podselection__menu, menu);
MenuItem searchItem = menu.findItem(R.id.podselection__action_search);
@ -237,15 +212,14 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
searchView.setOnQueryTextListener(this);
}
final boolean darkBg = ContextUtils.get().shouldColorOnTopBeLight(AppSettings.get().getPrimaryColor());
ContextUtils.get().tintMenuItems(menu, true, ContextCompat.getColor(getActivity(), darkBg ? R.color.white : R.color.black));
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_reload: {
if (!ActivityUtils.get(getActivity()).showInfoIfUserNotConnectedToInternet(listViewPod)) {
if (!Helpers.showInfoIfUserNotConnectedToInternet(getContext(), listViewPod)) {
Intent i = new Intent(getContext(), FetchPodsService.class);
getContext().startService(i);
return true;
@ -294,6 +268,11 @@ public class PodSelectionFragment extends ThemedFragment implements SearchView.O
/*
* Dummy implementations
*/
@Override
public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) {
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;

View file

@ -2,6 +2,7 @@ package com.github.dfa.diaspora_android.activity;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.app.PendingIntent;
import android.content.Context;
@ -26,7 +27,6 @@ import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.ui.theme.ColorPalette;
import com.github.dfa.diaspora_android.ui.theme.ThemeHelper;
import com.github.dfa.diaspora_android.ui.theme.ThemedActivity;
import com.github.dfa.diaspora_android.ui.theme.ThemedAlertDialogBuilder;
import com.github.dfa.diaspora_android.ui.theme.ThemedPreferenceFragment;
import com.github.dfa.diaspora_android.util.AppLog;
import com.github.dfa.diaspora_android.util.AppSettings;
@ -38,7 +38,12 @@ import butterknife.ButterKnife;
import uz.shift.colorpicker.LineColorPicker;
import uz.shift.colorpicker.OnColorChangedListener;
public class SettingsActivity extends ThemedActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
/**
* SettingsActivity
* Created by vanitas on 24.10.16.
*/
public class SettingsActivity extends ThemedActivity {
//Toolbar
@BindView(R.id.settings__appbar)
@ -63,7 +68,7 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
SettingsActivity.this.onBackPressed();
}
});
getAppSettings().registerPreferenceChangedListener(this);
oldProxySettings = getAppSettings().getProxySettings();
showFragment(SettingsFragmentMaster.TAG, false);
}
@ -121,7 +126,6 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
ProxyHandler.getInstance().updateProxySettings(this);
}
}
getAppSettings().unregisterPreferenceChangedListener(this);
super.onStop();
}
@ -131,7 +135,7 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
if (top != null && top.getFragmentTag().equals(SettingsFragmentProxy.TAG)) {
ProxyHandler.ProxySettings newProxySettings = getAppSettings().getProxySettings();
if (oldProxySettings.isEnabled() && !newProxySettings.isEnabled()) {
Toast.makeText(this, R.string.app_needs_restart_to_disable_proxy_usage, Toast.LENGTH_LONG).show();
Toast.makeText(this, R.string.toast__proxy_disabled__restart_required, Toast.LENGTH_LONG).show();
}
}
super.onBackPressed();
@ -146,13 +150,6 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
return (ThemedPreferenceFragment) getFragmentManager().findFragmentById(R.id.settings__fragment_container);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(getString(R.string.pref_key__screen_rotation))) {
this.updateScreenRotation();
}
}
public static class SettingsFragmentMaster extends ThemedPreferenceFragment {
public static final String TAG = "com.github.dfa.diaspora_android.settings.SettingsFragmentMaster";
@ -187,12 +184,6 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
((SettingsActivity) getActivity()).showFragment(SettingsFragmentDebugging.TAG, true);
return true;
}
/** Usability */
else if (settings.isKeyEqual(key, R.string.pref_key__is_overview_statusbar_hidden)) {
AppSettings.get().setRecreateMainActivity(true);
} else if (settings.isKeyEqual(key, R.string.pref_key__language)) {
AppSettings.get().setRecreateMainActivity(true);
}
/** Network */
else if (settings.isKeyEqual(key, R.string.pref_key__clear_cache)) {
Intent intent = new Intent(getActivity(), MainActivity.class);
@ -219,14 +210,14 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
} else if (settings.isKeyEqual(key, R.string.pref_key__manage_contacts)) {
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.setAction(MainActivity.ACTION_OPEN_URL);
intent.putExtra(MainActivity.URL_MESSAGE, diasporaUrlHelper.getContactsUrl());
intent.putExtra(MainActivity.URL_MESSAGE, diasporaUrlHelper.getManageContactsUrl());
startActivity(intent);
getActivity().finish();
return true;
} else if (settings.isKeyEqual(key, R.string.pref_key__change_account)) {
new ThemedAlertDialogBuilder(getActivity(), AppSettings.get())
new AlertDialog.Builder(getActivity())
.setTitle(getString(R.string.confirmation))
.setMessage(getString(R.string.logout_warning_description))
.setMessage(getString(R.string.pref_warning__change_account))
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
@ -271,8 +262,6 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
@Override
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
AppSettings settings = ((App) getActivity().getApplication()).getSettings();
DiasporaUrlHelper diasporaUrlHelper = new DiasporaUrlHelper(settings);
if (isAdded() && preference.hasKey()) {
String key = preference.getKey();
if (key.equals(getString(R.string.pref_key__primary_color__preference_click))) {
@ -281,13 +270,6 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
} else if (key.equals(getString(R.string.pref_key__accent_color__preference_click))) {
showColorPickerDialog(2);
return true;
} else if (key.equals(getString(R.string.pref_key__manage_theme))) {
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.setAction(MainActivity.ACTION_OPEN_URL);
intent.putExtra(MainActivity.URL_MESSAGE, diasporaUrlHelper.getThemeUrl());
startActivity(intent);
getActivity().finish();
return true;
}
}
return super.onPreferenceTreeClick(screen, preference);
@ -311,15 +293,15 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
//Inflate dialog layout
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialogLayout = inflater.inflate(R.layout.ui__dialog__color_picker, null);
final ThemedAlertDialogBuilder builder = new ThemedAlertDialogBuilder(context, appSettings);
final android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(context);
builder.setView(dialogLayout);
final FrameLayout titleBackground = dialogLayout.findViewById(R.id.color_picker_dialog__title_background);
final TextView title = dialogLayout.findViewById(R.id.color_picker_dialog__title);
final LineColorPicker base = dialogLayout.findViewById(R.id.color_picker_dialog__base_picker);
final LineColorPicker shade = dialogLayout.findViewById(R.id.color_picker_dialog__shade_picker);
final FrameLayout titleBackground = (FrameLayout) dialogLayout.findViewById(R.id.color_picker_dialog__title_background);
final TextView title = (TextView) dialogLayout.findViewById(R.id.color_picker_dialog__title);
final LineColorPicker base = (LineColorPicker) dialogLayout.findViewById(R.id.color_picker_dialog__base_picker);
final LineColorPicker shade = (LineColorPicker) dialogLayout.findViewById(R.id.color_picker_dialog__shade_picker);
title.setText(type == 1 ? R.string.primary_colors : R.string.accent_color);
title.setText(type == 1 ? R.string.pref_title__primary_color : R.string.pref_title__accent_color);
title.setTextColor(getResources().getColor(R.color.white));
final int[] current = (type == 1 ? appSettings.getPrimaryColorSettings() : appSettings.getAccentColorSettings());
base.setColors((type == 1 ? ColorPalette.getBaseColors(context) : ColorPalette.getAccentColors(context)));
@ -408,8 +390,8 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
public void updateSummaries() {
if (isAdded()) {
AppSettings settings = ((App) getActivity().getApplication()).getSettings();
findPreference(settings.rstr(R.string.pref_key__http_proxy_host)).setSummary(settings.getProxyHttpHost());
findPreference(settings.rstr(R.string.pref_key__http_proxy_port)).setSummary(Integer.toString(settings.getProxyHttpPort()));
findPreference(settings.getKey(R.string.pref_key__http_proxy_host)).setSummary(settings.getProxyHttpHost());
findPreference(settings.getKey(R.string.pref_key__http_proxy_port)).setSummary(Integer.toString(settings.getProxyHttpPort()));
}
}
@ -421,7 +403,7 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
if (appSettings.isKeyEqual(key, R.string.pref_key__http_proxy_load_tor_preset)) {
appSettings.setProxyHttpHost("127.0.0.1");
appSettings.setProxyHttpPort(8118);
Toast.makeText(screen.getContext(), R.string.orbot_proxy_preset_loaded, Toast.LENGTH_SHORT).show();
Toast.makeText(screen.getContext(), R.string.toast__proxy_orbot_preset_loaded, Toast.LENGTH_SHORT).show();
return true;
}
}
@ -467,35 +449,5 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
public String getFragmentTag() {
return TAG;
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
if (isAdded() && preference.hasKey()) {
AppSettings appSettings = ((App) getActivity().getApplication()).getSettings();
String key = preference.getKey();
if (appSettings.isKeyEqual(key, R.string.pref_key__wipe_settings)) {
showWipeSettingsDialog();
return true;
}
}
return super.onPreferenceTreeClick(screen, preference);
}
private void showWipeSettingsDialog() {
final AppSettings appSettings = AppSettings.get();
ThemedAlertDialogBuilder builder = new ThemedAlertDialogBuilder(getActivity(), appSettings);
builder.setTitle(R.string.confirmation)
.setMessage(R.string.wipe_settings_warning__appspecific)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
appSettings.resetAppSettings();
appSettings.resetPodSettings();
new net.gsantner.opoc.util.ContextUtils(appSettings.getContext()).restartApp(MainActivity.class);
}
}).setNegativeButton(android.R.string.cancel, null)
.create().show();
}
}
}

View file

@ -0,0 +1,196 @@
/*
This file is part of the Diaspora for Android.
Diaspora for Android 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.
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.activity;
import android.content.Context;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.listener.OnSomethingClickListener;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Fragment that shows a list of the HashTags the user follows
*/
public class TagListFragment extends ThemedFragment implements OnSomethingClickListener<Object> {
public static final String TAG = "com.github.dfa.diaspora_android.TagListFragment";
protected RecyclerView followedTagsRecyclerView;
protected App app;
protected DiasporaUrlHelper urls;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
AppLog.d(this, "onCreateView()");
return inflater.inflate(R.layout.recycler_list__fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
followedTagsRecyclerView = (RecyclerView) view.findViewById(R.id.fragment_list__recycler_view);
app = (App) getActivity().getApplication();
AppSettings appSettings = app.getSettings();
urls = new DiasporaUrlHelper(appSettings);
followedTagsRecyclerView.setHasFixedSize(true);
followedTagsRecyclerView.setNestedScrollingEnabled(false);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
followedTagsRecyclerView.setLayoutManager(layoutManager);
final FollowedTagsAdapter adapter = new FollowedTagsAdapter(appSettings, this);
followedTagsRecyclerView.setAdapter(adapter);
//Set window title
getActivity().setTitle(R.string.nav_followed_tags);
}
@Override
public String getFragmentTag() {
return TAG;
}
@Override
public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) {
/* Nothing to do */
}
@Override
public boolean onBackPressed() {
return false;
}
@Override
public void onSomethingClicked(Object null1, Integer null2, String tag) {
((MainActivity) getActivity()).openDiasporaUrl(urls.getSearchTagsUrl(tag));
}
@Override
protected void applyColorToViews() {
followedTagsRecyclerView.invalidate();
}
public static class FollowedTagsAdapter extends RecyclerView.Adapter<FollowedTagsAdapter.ViewHolder> {
private AppSettings appSettings;
private String[] followedTagsList;
private List<String> followedTagsFavsList;
private OnSomethingClickListener<Object> tagClickedListener;
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.recycler_view__list_item__text)
public TextView title;
@BindView(R.id.recycler_view__list_item__favourite)
AppCompatImageView favouriteImage;
@BindView(R.id.recycler_view__list_item__root)
RelativeLayout root;
ViewHolder(View v) {
super(v);
ButterKnife.bind(this, v);
}
}
FollowedTagsAdapter(AppSettings appSettings, OnSomethingClickListener<Object> tagClickedListener) {
this.appSettings = appSettings;
this.followedTagsList = appSettings.getFollowedTags();
this.followedTagsFavsList = new ArrayList<>(Arrays.asList(appSettings.getFollowedTagsFavs()));
this.tagClickedListener = tagClickedListener;
}
@Override
public int getItemCount() {
return followedTagsList.length;
}
@Override
public FollowedTagsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_list__list_item_with_fav, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// Alternating colors
final Context c = holder.root.getContext();
final String tag = followedTagsList[position];
holder.title.setText(tag);
if (position % 2 == 1) {
holder.root.setBackgroundColor(Helpers.getColorFromRessource(c, R.color.alternate_row_color));
}
// Favourite (Star) Image
applyFavouriteImage(holder.favouriteImage, isFollowedTagFaved(tag));
// Click on fav button
holder.favouriteImage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (isFollowedTagFaved(tag)) {
followedTagsFavsList.remove(followedTagsFavsList.indexOf(tag));
} else {
followedTagsFavsList.add(tag);
}
appSettings.setFollowedTagsFavs(followedTagsFavsList);
applyFavouriteImage(holder.favouriteImage, isFollowedTagFaved(tag));
}
});
holder.root.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tagClickedListener.onSomethingClicked(null, null, tag);
}
});
}
private boolean isFollowedTagFaved(String tag) {
return followedTagsFavsList.contains(tag);
}
private void applyFavouriteImage(AppCompatImageView imageView, boolean isFaved) {
imageView.setImageResource(isFaved ? R.drawable.ic_star_filled_48px : R.drawable.ic_star_border_black_48px);
imageView.setColorFilter(isFaved ? appSettings.getAccentColor() : 0, PorterDuff.Mode.SRC_ATOP);
}
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/

View file

@ -6,22 +6,20 @@ import org.json.JSONObject;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* Created by gsantner (gsantner AT mailbox DOT org on 30.09.16.
* 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
*/
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue", "SpellCheckingInspection", "UnusedReturnValue", "JavaDoc", "FieldCanBeLocal"})
public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, Serializable {
private static final boolean EXPORT_TOJSON_POST_COUNT_LOCAL = true;
private static final boolean EXPORT_TOJSON_ACTIVE6 = false;
private List<DiasporaPod> pods = new ArrayList<>();
private boolean trackMergeChanges = false;
private Integer trackAddedIndexStart = -1;
@ -90,8 +88,8 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
if (updatePodBak.getId() != 0 && updatePod.getId() == 0) {
updatePod.setId(updatePodBak.getId());
}
if (updatePodBak.getPostCountLocal() != 0 && updatePod.getPostCountLocal() == 0) {
updatePod.setPostCountLocal(updatePodBak.getPostCountLocal());
if (updatePodBak.getActive6() != 0 && updatePod.getActive6() == 0) {
updatePod.setActive6(updatePodBak.getActive6());
}
if (updatePodBak.getScore() != 0 && updatePod.getScore() == 0) {
updatePod.setScore(updatePodBak.getScore());
@ -181,12 +179,12 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
*
*/
public static class DiasporaPod implements Iterable<DiasporaPodList.DiasporaPod.DiasporaPodUrl>, Comparable<DiasporaPod>, Serializable {
private List<DiasporaPodUrl> _podUrls = new ArrayList<>();
private List<String> _mainLangs = new ArrayList<>();
private String _name = "";
private int _score = 0;
private int _id = 0;
private long _postCountLocal = 0;
private List<DiasporaPodUrl> podUrls = new ArrayList<>();
private List<String> mainLangs = new ArrayList<>();
private String name = "";
private int score = 0;
private int id = 0;
private long active6 = 0;
public DiasporaPod() {
@ -201,14 +199,14 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
JSONArray jarr;
if (json.has("name")) {
_name = json.getString("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 (!mainLangs.contains(val)) {
mainLangs.add(val);
}
}
}
@ -216,19 +214,19 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
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 (!podUrls.contains(podUrl)) {
podUrls.add(podUrl);
}
}
}
if (json.has("score")) {
_score = json.getInt("score");
score = json.getInt("score");
}
if (json.has("postCountLocal")) {
_postCountLocal = json.getLong("postCountLocal");
if (json.has("active6")) {
active6 = json.getLong("active6");
}
if (json.has("id")) {
_id = json.getInt("id");
id = json.getInt("id");
}
return this;
}
@ -238,28 +236,25 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
*/
public JSONObject toJson() throws JSONException {
JSONObject json = new JSONObject();
json.put("name", _name);
json.put("id", _id);
if (_score != 0) {
json.put("score", _score);
}
json.put("name", name);
json.put("score", score);
json.put("id", id);
// Only export active6 (frequently changing if told to do)
if (EXPORT_TOJSON_POST_COUNT_LOCAL && _postCountLocal > 0) {
json.put("postCountLocal", _postCountLocal);
if (EXPORT_TOJSON_ACTIVE6) {
json.put("active6", active6);
}
// Pod urls
JSONArray jarr = new JSONArray();
for (DiasporaPodUrl value : _podUrls) {
for (DiasporaPodUrl value : podUrls) {
jarr.put(value.toJson());
}
json.put("podUrls", jarr);
// main langs
jarr = new JSONArray();
for (String value : _mainLangs) {
for (String value : mainLangs) {
jarr.put(value);
}
json.put("mainLangs", jarr);
@ -273,11 +268,11 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
DiasporaPod otherPod = (DiasporaPod) o;
// Check if id is equal
ret = _id != 0 && _id == otherPod._id;
ret = this.id != 0 && this.id == otherPod.id;
// Check if _host is the same (fallback if id is 0)
// Check if host is the same (fallback if id is 0)
if (!ret) {
for (DiasporaPodUrl podUrl : _podUrls) {
for (DiasporaPodUrl podUrl : podUrls) {
for (DiasporaPodUrl otherPodUrl : otherPod.getPodUrls()) {
if (podUrl.getBaseUrl().equals(otherPodUrl.getBaseUrl())) {
ret = true;
@ -297,46 +292,47 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
if (!myPodUrls.isEmpty() && !otherPodUrls.isEmpty()) {
return myPodUrls.get(0).getHost().compareTo(otherPodUrls.get(0).getHost());
}
return _name.compareTo(otherPod.getName());
}
return _name.compareTo("");
return name.compareTo(otherPod.getName());
}
@Override
public String toString() {
return _name + "(" + _id + ")";
return name + "(" + id + ")";
}
/**
* Iterator for Iterable interface (forEach, ..)
*/
public Iterator<DiasporaPodUrl> iterator() {
return _podUrls.iterator();
return podUrls.iterator();
}
/*
* Getter & Setter
*/
* Getter & Setter
*/
public List<DiasporaPodUrl> getPodUrls() {
return _podUrls;
return podUrls;
}
public DiasporaPod setPodUrls(List<DiasporaPodUrl> podUrls) {
_podUrls = podUrls;
this.podUrls = podUrls;
return this;
}
public List<String> getMainLangs() {
return _mainLangs;
return mainLangs;
}
public DiasporaPod setMainLangs(List<String> mainLangs) {
_mainLangs = mainLangs;
this.mainLangs = mainLangs;
return this;
}
public DiasporaPod appendMainLangs(String... values) {
_mainLangs.addAll(Arrays.asList(values));
for (String mainLang : values) {
this.mainLangs.add(mainLang);
}
return this;
}
@ -344,50 +340,52 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
* Returns the first DiasporaPodUrl in the list
*/
public DiasporaPodUrl getPodUrl() {
if (_podUrls.size() > 0) {
return _podUrls.get(0);
if (podUrls.size() > 0) {
return podUrls.get(0);
}
return null;
}
public DiasporaPod appendPodUrls(DiasporaPodUrl... values) {
_podUrls.addAll(Arrays.asList(values));
for (DiasporaPodUrl value : values) {
this.podUrls.add(value);
}
return this;
}
public String getName() {
return _name;
return name;
}
public DiasporaPod setName(String name) {
_name = name;
this.name = name;
return this;
}
public int getScore() {
return _score;
return score;
}
public DiasporaPod setScore(int score) {
_score = score;
this.score = score;
return this;
}
public long getPostCountLocal() {
return _postCountLocal;
public long getActive6() {
return active6;
}
public DiasporaPod setPostCountLocal(long postCountLocal) {
_postCountLocal = postCountLocal;
public DiasporaPod setActive6(long active6) {
this.active6 = active6;
return this;
}
public int getId() {
return _id;
return id;
}
public DiasporaPod setId(int id) {
_id = id;
this.id = id;
return this;
}
@ -399,9 +397,9 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
*
*/
public static class DiasporaPodUrl implements Serializable {
private String _host = "";
private String _protocol = "https";
private Integer _port = 443;
private String host = "";
private String protocol = "https";
private Integer port = 443;
public DiasporaPodUrl() {
}
@ -416,7 +414,7 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
* @return
*/
public String getBaseUrl() {
return _protocol + "://" + _host + (isPortNeeded() ? _port : "");
return protocol + "://" + host + (isPortNeeded() ? port : "");
}
/**
@ -426,13 +424,13 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
*/
public DiasporaPodUrl fromJson(JSONObject json) throws JSONException {
if (json.has("host")) {
_host = json.getString("host");
host = json.getString("host");
}
if (json.has("protocol")) {
_protocol = json.getString("protocol");
protocol = json.getString("protocol");
}
if (json.has("port")) {
_port = json.getInt("port");
port = json.getInt("port");
}
return this;
}
@ -442,12 +440,12 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
*/
public JSONObject toJson() throws JSONException {
JSONObject json = new JSONObject();
json.put("host", _host);
if (!_protocol.equals("https")) {
json.put("protocol", _protocol);
json.put("host", host);
if (!protocol.equals("https")) {
json.put("protocol", protocol);
}
if (_port != 443) {
json.put("port", _port);
if (port != 443) {
json.put("port", port);
}
return json;
}
@ -473,7 +471,7 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
* Tells if the ports needs to shown
*/
public boolean isPortNeeded() {
return !((_port == 80 && _protocol.equals("http")) || (_port == 443 && _protocol.equals("https")));
return !((port == 80 && protocol.equals("http")) || (port == 443 && protocol.equals("https")));
}
@Override
@ -482,7 +480,6 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
}
@Override
@SuppressWarnings("SimplifiableIfStatement")
public boolean equals(Object o) {
if (o instanceof DiasporaPodUrl) {
return getBaseUrl().equals(((DiasporaPodUrl) o).getBaseUrl());
@ -494,29 +491,29 @@ public class DiasporaPodList implements Iterable<DiasporaPodList.DiasporaPod>, S
* GETTER & SETTER
*/
public String getHost() {
return _host;
return host;
}
public DiasporaPodUrl setHost(String host) {
_host = host;
this.host = host;
return this;
}
public String getProtocol() {
return _protocol;
return protocol;
}
public DiasporaPodUrl setProtocol(String protocol) {
_protocol = protocol;
this.protocol = protocol;
return this;
}
public Integer getPort() {
return _port;
return port;
}
public DiasporaPodUrl setPort(Integer port) {
_port = port;
this.port = port;
return this;
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -24,7 +24,6 @@ import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.listener.DiasporaUserProfileChangedListener;
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 org.json.JSONArray;
import org.json.JSONException;
@ -32,7 +31,7 @@ import org.json.JSONObject;
/**
* User profile
* Created by gsantner (gsantner AT mailbox DOT org) on 24.03.16. Part of dandelion*.
* Created by gsantner (https://gsantner.github.io/) on 24.03.16. Part of Diaspora for Android.
*/
public class DiasporaUserProfile {
private static final int MINIMUM_USERPROFILE_LOAD_TIMEDIFF = 5000;
@ -41,7 +40,6 @@ public class DiasporaUserProfile {
private DiasporaUserProfileChangedListener listener;
private final App app;
private final AppSettings appSettings;
DiasporaUrlHelper urls;
private JSONObject json;
private long userProfileLastLoadedTimestamp;
private boolean isWebUserProfileLoaded;
@ -53,17 +51,12 @@ public class DiasporaUserProfile {
private String[] followedTags;
private int notificationCount;
private int unreadMessagesCount;
private long lastVisitedPositionInStream = -1;
public DiasporaUserProfile(App app) {
this.app = app;
appSettings = app.getSettings();
urls = new DiasporaUrlHelper(appSettings);
loadFromAppSettings();
}
public void loadFromAppSettings() {
avatarUrl = appSettings.getAvatarUrl();
guid = appSettings.getProfileId();
name = appSettings.getName();
@ -71,7 +64,6 @@ public class DiasporaUserProfile {
followedTags = appSettings.getFollowedTags();
notificationCount = appSettings.getNotificationCount();
unreadMessagesCount = appSettings.getUnreadMessageCount();
lastVisitedPositionInStream = appSettings.getLastVisitedPositionInStream();
}
public DiasporaUserProfile(App app, Handler callbackHandler, DiasporaUserProfileChangedListener listener) {
@ -103,7 +95,7 @@ public class DiasporaUserProfile {
}
// GUID (User id)
if (json.has("guid") && loadGuid(json.getString("guid")) && !guid.isEmpty()) {
if (json.has("guid") && loadGuid(json.getString("guid"))) {
appSettings.setProfileId(guid);
}
@ -142,16 +134,6 @@ public class DiasporaUserProfile {
return isWebUserProfileLoaded;
}
public void analyzeUrl(String url) {
String prefix = urls.getPodUrl() + DiasporaUrlHelper.SUBURL_STREAM_WITH_TIMESTAMP;
if (url.startsWith(prefix)) {
try {
setLastVisitedPositionInStream(Long.parseLong(url.replace(prefix, "")));
} catch (NumberFormatException ignored) {
}
}
}
/*
// Getters & Setters
*/
@ -184,23 +166,6 @@ public class DiasporaUserProfile {
return followedTags;
}
public long getLastVisitedPositionInStream() {
return lastVisitedPositionInStream;
}
public void setLastVisitedPositionInStream(long lastVisitedPositionInStream) {
this.lastVisitedPositionInStream = lastVisitedPositionInStream;
appSettings.setLastVisitedPositionInStream(lastVisitedPositionInStream);
}
public boolean hasLastVisitedTimestampInStream() {
return appSettings.getLastVisitedPositionInStream() != -1;
}
public void resetLastVisitedPositionInStream() {
appSettings.setLastVisitedPositionInStream(-1);
}
/*
* Private property setters
*/

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -21,7 +21,7 @@ package com.github.dfa.diaspora_android.listener;
import com.github.dfa.diaspora_android.data.DiasporaUserProfile;
/**
* Created by gsantner (gsantner AT mailbox DOT org) on 26.03.16.
* Created by gsantner (https://gsantner.github.io/) on 26.03.16.
* Interface that needs to be implemented by classes that listen for Profile related changes
*/
public interface DiasporaUserProfileChangedListener {

View file

@ -10,5 +10,7 @@ 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 setToolbarIntellihide(boolean enable);
void enableToolbarHiding();
void disableToolbarHiding();
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -48,12 +48,12 @@ public class OpenExternalLinkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context c, Intent receiveIntent) {
AppSettings appSettings = AppSettings.get();
AppSettings appSettings = new AppSettings(c);
ThemeHelper.getInstance(appSettings);
AppLog.v(this, "OpenExternalLinkReceiver.onReceive(): url");
Uri url;
Uri url = null;
try {
String sUrl = receiveIntent.getStringExtra(MainActivity.EXTRA_URL);
url = Uri.parse(sUrl);

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -38,7 +38,6 @@ public class UpdateTitleReceiver extends BroadcastReceiver {
private AppSettings appSettings;
private App app;
private TitleCallback callback;
private String lastUrl;
public UpdateTitleReceiver(App app, DiasporaUrlHelper urls, TitleCallback callback) {
this.urls = urls;
@ -49,24 +48,20 @@ public class UpdateTitleReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
lastUrl = intent.getStringExtra(MainActivity.EXTRA_URL);
if (lastUrl != null && lastUrl.startsWith(urls.getPodUrl())) {
String subUrl = lastUrl.substring((urls.getPodUrl()).length());
String url = intent.getStringExtra(MainActivity.EXTRA_URL);
if (url != null && url.startsWith(urls.getPodUrl())) {
String subUrl = url.substring((urls.getPodUrl()).length());
AppLog.spam(this, "onReceive()- Set title for subUrl " + subUrl);
if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_STREAM)) {
setTitle(R.string.nav_stream);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_POSTS)) {
setTitle(R.string.app_name);
setTitle(R.string.diaspora);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_NOTIFICATIONS)) {
setTitle(R.string.notifications);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_CONVERSATIONS)) {
setTitle(R.string.conversations);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_NEW_POST)) {
setTitle(R.string.new_post);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_STATISTICS)) {
setTitle(R.string.statistics);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_CONTACTS)) {
setTitle(R.string.contacts);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_PEOPLE + appSettings.getProfileId())) {
setTitle(R.string.nav_profile);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_ACTIVITY)) {
@ -79,25 +74,25 @@ public class UpdateTitleReceiver extends BroadcastReceiver {
setTitle(R.string.nav_mentions);
} else if (subUrl.startsWith(DiasporaUrlHelper.SUBURL_PUBLIC)) {
setTitle(R.string.public_);
} else if (urls.isAspectUrl(lastUrl)) {
setTitle(urls.getAspectNameFromUrl(lastUrl, app));
} else if (urls.isAspectUrl(url)) {
setTitle(urls.getAspectNameFromUrl(url, app));
}
} else {
AppLog.spam(this, "onReceive()- Invalid url: " + lastUrl);
AppLog.spam(this, "onReceive()- Invalid url: " + url);
}
}
private void setTitle(int rId) {
callback.setTitle(lastUrl, rId);
callback.setTitle(rId);
}
private void setTitle(String title) {
callback.setTitle(lastUrl, title);
callback.setTitle(title);
}
public interface TitleCallback {
void setTitle(String url, int resId);
void setTitle(int Rid);
void setTitle(String url, String title);
void setTitle(String title);
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -24,8 +24,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
import net.gsantner.opoc.util.DownloadTask;
import java.io.File;
public class AvatarImageLoader {
@ -54,9 +52,7 @@ public class AvatarImageLoader {
public void startImageDownload(ImageView imageView, String avatarUrl) {
if (!avatarUrl.equals("")) {
new DownloadTask(new File(avatarFile.getAbsolutePath()), (ok, file) -> {
loadToImageView(imageView);
}).execute(avatarUrl);
new ImageDownloadTask(imageView, avatarFile.getAbsolutePath()).execute(avatarUrl);
}
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -39,76 +39,73 @@ import javax.net.ssl.HttpsURLConnection;
import info.guardianproject.netcipher.NetCipher;
public class FetchPodsService extends Service {
public static final String MESSAGE_PODS_RECEIVED = "com.github.dfa.diaspora.podsreceived";
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 FetchPodsService() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new GetPodsTask(this).execute();
getPods();
return super.onStartCommand(intent, flags, startId);
}
private void getPods() {
AsyncTask<Void, Void, DiasporaPodList> getPodsAsync = new AsyncTask<Void, Void, DiasporaPodList>() {
@Override
protected DiasporaPodList doInBackground(Void... params) {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
HttpsURLConnection con = NetCipher.getHttpsURLConnection(PODDY_PODLIST_URL);
if (con.getResponseCode() == HttpsURLConnection.HTTP_OK) {
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
// 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 | JSONException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
// Could not fetch list of pods :(
return new DiasporaPodList();
}
@Override
protected void onPostExecute(DiasporaPodList pods) {
if (pods == null) {
pods = new DiasporaPodList();
}
Intent broadcastIntent = new Intent(MESSAGE_PODS_RECEIVED);
broadcastIntent.putExtra(EXTRA_PODLIST, pods);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(broadcastIntent);
stopSelf();
}
};
getPodsAsync.execute();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
class GetPodsTask extends AsyncTask<Void, Void, DiasporaPodList> {
private static final String PODDY_PODLIST_URL = "https://raw.githubusercontent.com/gsantner/dandelion/master/app/src/main/res/raw/podlist.json";
private final Service service;
GetPodsTask(Service service) {
this.service = service;
}
@Override
protected DiasporaPodList doInBackground(Void... params) {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
HttpsURLConnection con = NetCipher.getHttpsURLConnection(PODDY_PODLIST_URL);
if (con.getResponseCode() == HttpsURLConnection.HTTP_OK) {
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
// 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 | JSONException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
// Could not fetch list of pods :(
return new DiasporaPodList();
}
@Override
protected void onPostExecute(DiasporaPodList pods) {
if (pods == null) {
pods = new DiasporaPodList();
}
Intent broadcastIntent = new Intent(FetchPodsService.MESSAGE_PODS_RECEIVED);
broadcastIntent.putExtra(FetchPodsService.EXTRA_PODLIST, pods);
LocalBroadcastManager.getInstance(service.getApplicationContext()).sendBroadcast(broadcastIntent);
service.stopSelf();
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.

View file

@ -0,0 +1,98 @@
/*
This file is part of the Diaspora for Android.
Diaspora for Android 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.
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.service;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.widget.ImageView;
import com.github.dfa.diaspora_android.util.AppLog;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.net.ssl.HttpsURLConnection;
import info.guardianproject.netcipher.NetCipher;
/**
* Task that can be used to download images from URLs and store them in storage
* Created by gsantner (https://gsantner.github.io/) on 24.03.16.
*/
public class ImageDownloadTask extends AsyncTask<String, Void, Bitmap> {
private final ImageView imageView;
private String savePath;
/**
* Download image from URL
*
* @param imageView ImageView to set image to (null = don't set)
* @param savePath Save image to file (null = don't save)
*/
public ImageDownloadTask(@Nullable ImageView imageView, @Nullable String savePath) {
this.imageView = imageView;
this.savePath = savePath;
}
protected Bitmap doInBackground(String... urls) {
String url = urls[0];
Bitmap bitmap = null;
FileOutputStream out = null;
InputStream inStream;
HttpsURLConnection connection;
try {
connection = NetCipher.getHttpsURLConnection(url);
inStream = connection.getInputStream();
bitmap = BitmapFactory.decodeStream(inStream);
// Save to file if not null
if (savePath != null) {
out = new FileOutputStream(savePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
}
try {
inStream.close();
} catch (IOException e) {/*Nothing*/}
connection.disconnect();
} catch (Exception e) {
AppLog.e(this, e.getMessage());
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException ignored) {
}
}
return bitmap;
}
protected void onPostExecute(Bitmap result) {
// Display on imageview if not null
if (imageView != null) {
imageView.setImageBitmap(result);
}
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/

View file

@ -0,0 +1,95 @@
/*
This file is part of the Diaspora for Android.
Diaspora for Android 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.
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.service;
import android.content.Context;
import android.os.AsyncTask;
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;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import info.guardianproject.netcipher.NetCipher;
/**
* AsyncTask to fetch a users profile
*/
public class StatisticsFetchTask extends AsyncTask<Void, Void, Void> {
// Code for getting the profile async without any UI/WebView
// TODO: This is an early version,needs to be converted to Service
private final App app;
private final Context context;
private final DiasporaUrlHelper urls;
public StatisticsFetchTask(final App app) {
this.context = app.getApplicationContext();
this.app = app;
this.urls = new DiasporaUrlHelper(app.getSettings());
}
@Override
protected Void doInBackground(Void... params) {
String extractedProfileData = null;
final CookieManager cookieManager = app.getCookieManager();
String cookies = cookieManager.getCookie(urls.getPodUrl());
HttpsURLConnection connection;
InputStream inStream;
try {
URL url = new URL(urls.getStatisticsUrl());
connection = NetCipher.getHttpsURLConnection(url);
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.setRequestMethod("GET");
if (cookies != null) {
connection.setRequestProperty("Cookie", cookies);
}
connection.connect();
inStream = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inStream));
String line;
while ((line = br.readLine()) != null) {
AppLog.d(this, "STATS: " + line);
}
try {
br.close();
inStream.close();
} catch (IOException e) {/*Nothing*/}
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -28,80 +28,95 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
@SuppressWarnings("WeakerAccess")
public class BadgeDrawable extends Drawable {
// Source: http://mobikul.com/adding-badge-count-on-menu-items-like-cart-notification-etc/
private static final String BADGE_VALUE_OVERFLOW = "*";
private Paint _badgeBackground;
private Paint _badgeText;
private Rect _textRect = new Rect();
private Paint badgeBackground;
private Paint badgeStroke;
private Paint badgeText;
private Rect textRect = new Rect();
private String _badgeValue = "";
private boolean _shouldDraw;
private String badgeValue = "";
private boolean shouldDraw;
public BadgeDrawable(Context context) {
float textSize = context.getResources().getDimension(R.dimen.textsize_badge_count);
AppSettings settings = AppSettings.get();
_badgeBackground = new Paint();
_badgeBackground.setColor(settings.getAccentColor());
_badgeBackground.setAntiAlias(true);
_badgeBackground.setStyle(Paint.Style.FILL);
AppSettings settings = new AppSettings(context);
badgeBackground = new Paint();
badgeBackground.setColor(settings.getAccentColor());
badgeBackground.setAntiAlias(true);
badgeBackground.setStyle(Paint.Style.FILL);
badgeStroke = new Paint();
badgeStroke.setColor(ContextCompat.getColor(context.getApplicationContext(), R.color.colorPrimaryDark));
badgeStroke.setAntiAlias(true);
badgeStroke.setStyle(Paint.Style.FILL);
_badgeText = new Paint();
_badgeText.setColor(ContextUtils.get().shouldColorOnTopBeLight(settings.getAccentColor()) ? Color.WHITE : Color.BLACK);
_badgeText.setTypeface(Typeface.DEFAULT);
_badgeText.setTextSize(textSize);
_badgeText.setAntiAlias(true);
_badgeText.setTextAlign(Paint.Align.CENTER);
badgeText = new Paint();
badgeText.setColor(Color.WHITE);
badgeText.setTypeface(Typeface.DEFAULT);
badgeText.setTextSize(textSize);
badgeText.setAntiAlias(true);
badgeText.setTextAlign(Paint.Align.CENTER);
}
@Override
public void draw(@NonNull Canvas canvas) {
if (!_shouldDraw) {
public void draw(Canvas canvas) {
if (!shouldDraw) {
return;
}
Rect bounds = getBounds();
float width = bounds.right - bounds.left;
float height = bounds.bottom - bounds.top;
float oneDp = ContextUtils.get().convertDpToPx(1);
// Position the badge in the top-right quadrant of the icon.
float radius = ((Math.max(width, height) / 2)) / 2;
float centerX = (width - radius - 1) + oneDp * 2;
float centerY = radius - 2 * oneDp;
canvas.drawCircle(centerX, centerY, (int) (radius + oneDp * 5), _badgeBackground);
// Draw badge count message inside the circle.
_badgeText.getTextBounds(_badgeValue, 0, _badgeValue.length(), _textRect);
float textHeight = _textRect.bottom - _textRect.top;
float centerX = (width - radius - 1) + 5;
float centerY = radius - 5;
if (badgeValue.length() <= 2) {
// Draw badge circle.
canvas.drawCircle(centerX, centerY, (int) (radius + 7.5), badgeStroke);
canvas.drawCircle(centerX, centerY, (int) (radius + 5.5), badgeBackground);
} else {
canvas.drawCircle(centerX, centerY, (int) (radius + 8.5), badgeStroke);
canvas.drawCircle(centerX, centerY, (int) (radius + 6.5), badgeBackground);
//canvas.drawRoundRect(radius, radius, radius, radius, 10, 10, badgeBackground);
}
// Draw badge count text inside the circle.
badgeText.getTextBounds(badgeValue, 0, badgeValue.length(), textRect);
float textHeight = textRect.bottom - textRect.top;
float textY = centerY + (textHeight / 2f);
canvas.drawText(_badgeValue.length() > 2 ? BADGE_VALUE_OVERFLOW : _badgeValue,
centerX, textY, _badgeText);
if (badgeValue.length() > 2)
canvas.drawText(BADGE_VALUE_OVERFLOW, centerX, textY, badgeText);
else
canvas.drawText(badgeValue, centerX, textY, badgeText);
}
// Sets the text to display. Badge displays a '*' if more than 2 characters
private void setBadgeText(String text) {
_badgeValue = text;
/*
Sets the count (i.e notifications) to display.
*/
public void setCount(String count) {
badgeValue = count;
// Only draw a badge if the value isn't a zero
_shouldDraw = !text.equalsIgnoreCase("0");
// Only draw a badge if there are notifications.
shouldDraw = !count.equalsIgnoreCase("0");
invalidateSelf();
}
@Override
public void setAlpha(int alpha) {
// do nothing
}
@Override
public void setColorFilter(ColorFilter cf) {
// do nothing
}
@Override
@ -110,11 +125,11 @@ public class BadgeDrawable extends Drawable {
}
public static void setBadgeCount(Context context, LayerDrawable icon, Integer count) {
setBadgeText(context, icon, count.toString());
setBadgeCount(context, icon, count.toString());
}
// Max of 2 characters
public static void setBadgeText(Context context, LayerDrawable icon, String text) {
public static void setBadgeCount(Context context, LayerDrawable icon, String count) {
BadgeDrawable badge;
// Reuse drawable if possible
@ -125,7 +140,7 @@ public class BadgeDrawable extends Drawable {
badge = new BadgeDrawable(context);
}
badge.setBadgeText(text);
badge.setCount(count);
icon.mutate();
icon.setDrawableByLayerId(R.id.ic_badge, badge);
}

View file

@ -1,30 +1,31 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.ui;
import android.annotation.TargetApi;
import android.content.Context;
import android.support.v7.widget.AppCompatTextView;
import android.text.Html;
import android.text.SpannableString;
import android.text.util.Linkify;
import android.util.AttributeSet;
import android.util.Patterns;
import android.widget.TextView;
import com.github.dfa.diaspora_android.activity.MainActivity;
@ -37,7 +38,7 @@ import java.util.regex.Pattern;
* Hashtags open the MainActivity, load the new-post site of the selected pod and insert the
* hashtag into the post editor. See data/HashtagContentProvider.
*/
public class HtmlTextView extends AppCompatTextView {
public class HtmlTextView extends TextView {
public HtmlTextView(Context context) {
super(context);
@ -54,8 +55,14 @@ public class HtmlTextView extends AppCompatTextView {
init();
}
@TargetApi(21)
public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
/**
* Linkify, format markdown and escape the displayed message.
* Linkify, format markdown and escape the displayed text.
*/
private void init() {
formatHtmlAndCustomTags();

View file

@ -36,13 +36,12 @@ import butterknife.OnClick;
import butterknife.OnItemSelected;
/**
* Dialog that helps the user configure a pod
* Created by gsantner on 06.10.16.
* Created by gsantner (https://gsantner.github.io) on 06.10.16.
*/
public class PodSelectionDialog extends ThemedAppCompatDialogFragment {
public static final String TAG = "com.github.dfa.diaspora_android.ui.PodSelectionDialog";
public interface PodSelectionDialogResultListener {
public static interface PodSelectionDialogResultListener {
void onPodSelectionDialogResult(DiasporaPod pod, boolean accepted);
}
@ -128,7 +127,7 @@ public class PodSelectionDialog extends ThemedAppCompatDialogFragment {
spinnerProfile.setVisibility(View.VISIBLE);
String[] podUrlss = new String[podUrls.size()];
for (int i = 0; i < podUrls.size(); podUrlss[i] = podUrls.get(i++).getBaseUrl()) ;
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, podUrlss);
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, podUrlss);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProfile.setAdapter(spinnerAdapter);
}
@ -159,7 +158,7 @@ public class PodSelectionDialog extends ThemedAppCompatDialogFragment {
if (isAdded()) {
return ((App) getActivity().getApplication()).getSettings();
} else {
return AppSettings.get();
return new AppSettings(getContext().getApplicationContext());
}
}

View file

@ -1,85 +0,0 @@
package com.github.dfa.diaspora_android.ui;
import android.app.Activity;
import android.support.v4.content.ContextCompat;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaAspect;
import com.github.dfa.diaspora_android.util.AppSettings;
import net.gsantner.opoc.ui.SearchOrCustomTextDialog;
import net.gsantner.opoc.util.Callback;
import java.util.ArrayList;
import java.util.Arrays;
public class SearchOrCustomTextDialogCreator {
public static final String SPECIAL_PREFIX = "\uD83D\uDCA0";
public static void showDiasporaTagsDialog(final Activity activity, final Callback.a1<String> callback) {
SearchOrCustomTextDialog.DialogOptions dopt = new SearchOrCustomTextDialog.DialogOptions();
baseConf(activity, dopt);
dopt.callback = callback;
dopt.isSearchEnabled = true;
dopt.searchHintText = R.string.search;
dopt.titleText = R.string.tags;
new Thread(() -> {
AppSettings appSettings = AppSettings.get();
ArrayList<String> hl = new ArrayList<>();
ArrayList<String> data = new ArrayList<>(Arrays.asList(appSettings.getFollowedTags()));
if (data.size() > 0) {
String highlighted = surroundString(data.remove(0));
data.add(0, highlighted);
hl.add(highlighted);
}
for (int strid : new int[]{R.string.manage_hashtags}) {
String special = surroundString(appSettings.rstr(strid));
data.add(0, special);
hl.add(special);
}
dopt.data = data;
dopt.highlightData = hl;
activity.runOnUiThread(() -> SearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt));
}).start();
}
private static String surroundString(String text) {
return SPECIAL_PREFIX + " " + text + " ";
}
public static void showDiasporaAspectsDialog(final Activity activity, final Callback.a1<String> callback) {
SearchOrCustomTextDialog.DialogOptions dopt = new SearchOrCustomTextDialog.DialogOptions();
baseConf(activity, dopt);
dopt.callback = callback;
dopt.isSearchEnabled = false;
dopt.titleText = R.string.contacts;
new Thread(() -> {
AppSettings appSettings = AppSettings.get();
ArrayList<String> hl = new ArrayList<>();
ArrayList<String> data = new ArrayList<>();
for (DiasporaAspect aspect : AppSettings.get().getAspects()) {
data.add(aspect.name);
}
for (int strid : new int[]{R.string.nav_profile, R.string.manage_your_contact_list}) {
String special = surroundString(appSettings.rstr(strid));
data.add(0, special);
hl.add(special);
}
dopt.data = data;
dopt.highlightData = hl;
activity.runOnUiThread(() -> SearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt));
}).start();
}
private static void baseConf(Activity activity, SearchOrCustomTextDialog.DialogOptions dopt) {
AppSettings as = new AppSettings(activity);
dopt.isDarkDialog = as.isAmoledColorMode();
dopt.textColor = ContextCompat.getColor(activity, dopt.isDarkDialog ? R.color.white : R.color.primary_text);
dopt.highlightColor = as.getAccentColor();
}
}

View file

@ -8,7 +8,6 @@ import android.support.v4.graphics.ColorUtils;
import com.github.dfa.diaspora_android.R;
/**
* Class that handles Colors
* Created by dnld on 24/02/16.
*/
public class ColorPalette {

View file

@ -0,0 +1,73 @@
/*
This file is part of the Diaspora for Android.
Diaspora for Android 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.
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.ui.theme;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Menu;
import android.view.MenuInflater;
/**
* Customized abstract Fragment class with some useful methods
* Created by vanitas on 21.09.16.
*/
public abstract class CustomFragment extends Fragment {
public static final String TAG = "com.github.dfa.diaspora_android.ui.theme.CustomFragment";
/**
* We have an optionsMenu
*
* @param savedInstanceState state
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
/**
* 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 inflater inflater
*/
public abstract void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater);
/**
* 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();
public boolean isAllowedIntellihide() {
return true;
}
}

View file

@ -1,25 +1,24 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
This class is inspired by org.horasapps.LeafPic
*/
package com.github.dfa.diaspora_android.ui.theme;
import android.content.DialogInterface;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PorterDuff;
@ -27,11 +26,9 @@ import android.os.Build;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.CompoundButtonCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ProgressBar;
@ -64,7 +61,7 @@ public class ThemeHelper {
public static ThemeHelper getInstance() {
if (instance == null)
throw new IllegalStateException("ThemeHelper must be initialized using getInstance(AppSettingsBase) before it can be used!");
throw new IllegalStateException("ThemeHelper must be initialized using getInstance(AppSettings) before it can be used!");
return instance;
}
@ -154,26 +151,6 @@ public class ThemeHelper {
}
public static int getNeutralGreyColor() {
return ContextCompat.getColor(getInstance().appSettings.getContext(), R.color.md_grey_800);
}
public static void updateAlertDialogColor(AlertDialog alertDialog) {
if (alertDialog != null) {
for (int i : new int[]{
DialogInterface.BUTTON_POSITIVE,
DialogInterface.BUTTON_NEUTRAL,
DialogInterface.BUTTON_NEGATIVE}) {
Button b = alertDialog.getButton(i);
if (b != null) {
b.setTextColor(getAccentColor());
}
}
}
}
public static void updateButtonTextColor(Button button) {
if (button != null) {
button.setTextColor(getAccentColor());
}
return ContextCompat.getColor(getInstance().appSettings.getApplicationContext(), R.color.md_grey_800);
}
}

View file

@ -1,32 +1,32 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.ui.theme;
import android.annotation.TargetApi;
import android.content.pm.ActivityInfo;
import android.app.ActivityManager;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
/**
* Activity that supports color schemes
@ -43,11 +43,9 @@ public abstract class ThemedActivity extends AppCompatActivity {
protected void onResume() {
super.onResume();
ThemeHelper.getInstance(getAppSettings());
updateLanguage();
updateStatusBarColor();
updateRecentAppColor();
applyColorToViews();
updateScreenRotation();
}
protected abstract void applyColorToViews();
@ -67,25 +65,14 @@ public abstract class ThemedActivity extends AppCompatActivity {
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void updateRecentAppColor() {
}
protected void updateScreenRotation() {
String setting = getAppSettings().getScreenRotation();
int rotation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; // Default (system settings)
if (setting.equals(getString(R.string.rotation_val_sensor))) {
rotation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
} else if (setting.equals(getString(R.string.rotation_val_portrait))) {
rotation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
} else if (setting.equals(getString(R.string.rotation_val_landscape))) {
rotation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
BitmapDrawable drawable = ((BitmapDrawable) getDrawable(R.drawable.ic_launcher));
if (drawable != null) {
setTaskDescription(new ActivityManager.TaskDescription(
getResources().getString(R.string.app_name),
drawable.getBitmap(),
getAppSettings().getPrimaryColor()));
}
}
setRequestedOrientation(rotation);
}
public void updateLanguage() {
AppSettings appSettings = getAppSettings();
ContextUtils.get().setAppLanguage(appSettings.getLanguage());
}
}

View file

@ -1,45 +0,0 @@
package com.github.dfa.diaspora_android.ui.theme;
import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.annotation.StyleRes;
import android.support.v7.app.AlertDialog;
import com.github.dfa.diaspora_android.util.AppSettings;
/**
* AlertDialog Builder that colors its buttons
* Created by vanitas on 06.11.16.
*/
public class ThemedAlertDialogBuilder extends AlertDialog.Builder {
protected AppSettings appSettings;
public ThemedAlertDialogBuilder(@NonNull Context context, AppSettings appSettings) {
super(context);
this.appSettings = appSettings;
}
public ThemedAlertDialogBuilder(@NonNull Context context, @StyleRes int themeResId, AppSettings appSettings) {
super(context, themeResId);
this.appSettings = appSettings;
}
@Override
public AlertDialog create() {
final AlertDialog dialog = super.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
applyColors(dialog);
}
});
return dialog;
}
private void applyColors(AlertDialog alertDialog) {
ThemeHelper.getInstance(appSettings);
ThemeHelper.updateAlertDialogColor(alertDialog);
}
}

View file

@ -2,7 +2,6 @@ package com.github.dfa.diaspora_android.ui.theme;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatDialogFragment;
import com.github.dfa.diaspora_android.util.AppSettings;
@ -14,7 +13,6 @@ import com.github.dfa.diaspora_android.util.AppSettings;
public abstract class ThemedAppCompatDialogFragment extends AppCompatDialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);

View file

@ -10,7 +10,6 @@ import android.widget.CheckBox;
import com.github.dfa.diaspora_android.util.AppSettings;
/**
* CheckboxPreference that colors its checkbox with accent color
* Created by vanitas on 24.10.16.
*/
@ -41,8 +40,8 @@ public class ThemedCheckBoxPreference extends CheckBoxPreference implements Them
@Override
public void setColors() {
CheckBox checkBox = rootLayout.findViewById(android.R.id.checkbox);
ThemeHelper.getInstance(AppSettings.get());
CheckBox checkBox = (CheckBox) rootLayout.findViewById(android.R.id.checkbox);
ThemeHelper.getInstance(new AppSettings(getContext()));
ThemeHelper.updateCheckBoxColor(checkBox);
}
}

View file

@ -10,7 +10,7 @@ import android.widget.ImageView;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
import com.github.dfa.diaspora_android.util.Helpers;
/**
* Preference that shows selected Color in a circle
@ -38,7 +38,7 @@ public class ThemedColorPickerPreference extends Preference implements Themeable
@Override
protected void onBindView(View view) {
super.onBindView(view);
colorPreview = view.findViewById(android.R.id.icon);
colorPreview = (ImageView) view.findViewById(android.R.id.icon);
setColors();
}
@ -47,16 +47,16 @@ public class ThemedColorPickerPreference extends Preference implements Themeable
Drawable circle;
if (colorPreview != null && (circle = colorPreview.getDrawable()) != null) {
Context c = getContext();
AppSettings appSettings = AppSettings.get();
AppSettings appSettings = new AppSettings(getContext());
String key = getKey();
int color = ContextUtils.get().rcolor(R.color.primary);
int color = Helpers.getColorFromRessource(c, R.color.primary);
if ((appSettings.isKeyEqual(key, R.string.pref_key__primary_color_shade))) {
color = appSettings.getPrimaryColor();
} else if ((appSettings.isKeyEqual(key, R.string.pref_key__accent_color_shade))) {
color = appSettings.getAccentColor();
} else {
color = appSettings.getColor(key, color, getSharedPreferences());
color = appSettings.getColor(getSharedPreferences(), key, color);
}
circle.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -21,14 +21,12 @@ package com.github.dfa.diaspora_android.ui.theme;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.util.AppSettings;
import net.gsantner.opoc.activity.GsFragmentBase;
/**
* Fragment that supports color schemes
* Created by vanitas on 06.10.16.
*/
public abstract class ThemedFragment extends GsFragmentBase {
public abstract class ThemedFragment extends CustomFragment {
protected AppSettings getAppSettings() {
return ((App) getActivity().getApplication()).getSettings();
}
@ -41,9 +39,4 @@ public abstract class ThemedFragment extends GsFragmentBase {
ThemeHelper.getInstance(getAppSettings());
applyColorToViews();
}
public boolean isAllowedIntellihide() {
return true;
}
}

View file

@ -36,7 +36,7 @@ public class ThemedPreferenceCategory extends PreferenceCategory implements Them
@Override
protected View onCreateView(ViewGroup parent) {
View rootLayout = super.onCreateView(parent);
this.titleTextView = rootLayout.findViewById(android.R.id.title);
this.titleTextView = (TextView) rootLayout.findViewById(android.R.id.title);
setColors();
return rootLayout;
}
@ -44,7 +44,7 @@ public class ThemedPreferenceCategory extends PreferenceCategory implements Them
@Override
public void setColors() {
if (titleTextView != null) {
ThemeHelper.getInstance(AppSettings.get());
ThemeHelper.getInstance(new AppSettings(getContext()));
ThemeHelper.updateTextViewTextColor(titleTextView);
}
}

View file

@ -10,7 +10,6 @@ import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.util.AppSettings;
/**
* PreferenceFragment with a colored status bar
* Created by vanitas on 24.10.16.
*/

View file

@ -27,9 +27,9 @@ public class ThemedVisibilityPreference extends ThemedCheckBoxPreference {
@Override
public void setColors() {
CheckBox checkBox = rootLayout.findViewById(android.R.id.checkbox);
CheckBox checkBox = (CheckBox) rootLayout.findViewById(android.R.id.checkbox);
checkBox.setButtonDrawable(R.drawable.ic_visibility_selector);
ThemeHelper.getInstance(AppSettings.get());
ThemeHelper.getInstance(new AppSettings(getContext()));
ThemeHelper.updateCheckBoxColor(checkBox);
}
}

View file

@ -1,86 +0,0 @@
package com.github.dfa.diaspora_android.util;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.FileProvider;
import android.view.View;
import com.github.dfa.diaspora_android.BuildConfig;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.web.WebHelper;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue"})
public class ActivityUtils extends net.gsantner.opoc.util.ActivityUtils {
public ActivityUtils(Activity activity) {
super(activity);
}
public static ActivityUtils get(Activity activity) {
return new ActivityUtils(activity);
}
public File createImageFile() throws IOException {
// 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(ActivityUtils.class, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
return new File(
imageFileName + /* prefix */
".jpg", /* suffix */
storageDir.getAbsolutePath() /* directory */
);
}
/**
* Show Information if user is offline, returns true if is not connected to internet
*
* @param anchor A view anchor
*/
public boolean showInfoIfUserNotConnectedToInternet(View anchor) {
boolean isOnline = WebHelper.isOnline(_context);
if (!isOnline) {
showSnackBar(R.string.sorry_need_to_be_connected_to_internet, true);
}
return !isOnline;
}
public void logBundle(Bundle savedInstanceState, String k) {
if (savedInstanceState != null) {
for (String key : savedInstanceState.keySet()) {
AppLog.d("Bundle", key + " is a key in the bundle " + k);
Object bun = savedInstanceState.get(key);
if (bun != null) {
if (bun instanceof Bundle) {
logBundle((Bundle) bun, k + "." + key);
} else if (bun instanceof byte[]) {
AppLog.d("Bundle", "Key: " + k + "." + key + ": " + Arrays.toString((byte[]) bun));
} else {
AppLog.d("Bundle", "Key: " + k + "." + key + ": " + bun.toString());
}
}
}
}
}
/**
* This method creates file sharing uri by using FileProvider
*
* @return
*/
public static Uri getFileSharingUri(Context context, File file) {
return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, file);
}
}

View file

@ -1,58 +0,0 @@
package com.github.dfa.diaspora_android.util;
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
// From https://stackoverflow.com/a/19494006
public class AndroidBug5497Workaround {
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
public static void assistActivity(Activity activity) {
new AndroidBug5497Workaround(activity);
}
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private AndroidBug5497Workaround(Activity activity) {
FrameLayout content = activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
} else {
// keyboard probably just became hidden
frameLayoutParams.height = usableHeightSansKeyboard;
}
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
}

View file

@ -1,24 +1,23 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.util;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@ -26,7 +25,6 @@ import java.util.Observable;
import java.util.Observer;
/**
* Class that logs debug messages to Androids Log and to additional targets (like textviews)
* Created by gregor on 18.09.16.
*/
public class AppLog {
@ -61,61 +59,37 @@ public class AppLog {
*/
public static void v(Object source, String _text) {
if (isLoggingEnabled()) {
if (source != null) {
Log.v(getLogPrefix(source), _text);
} else {
Log.v("null", _text);
}
Log.v(getLogPrefix(source), _text);
}
}
public static void i(Object source, String _text) {
if (isLoggingEnabled()) {
if (source != null) {
Log.i(getLogPrefix(source), _text);
} else {
Log.i("null", _text);
}
Log.i(getLogPrefix(source), _text);
}
}
public static void d(Object source, String _text) {
if (isLoggingEnabled()) {
if (source != null) {
Log.d(getLogPrefix(source), _text);
} else {
Log.d("null", _text);
}
Log.d(getLogPrefix(source), _text);
}
}
public static void e(Object source, String _text) {
if (isLoggingEnabled()) {
if (source != null) {
Log.e(getLogPrefix(source), _text);
} else {
Log.e("null", _text);
}
Log.e(getLogPrefix(source), _text);
}
}
public static void w(Object source, String _text) {
if (isLoggingEnabled()) {
if (source != null) {
Log.w(getLogPrefix(source), _text);
} else {
Log.w("null", _text);
}
Log.w(getLogPrefix(source), _text);
}
}
public static void spam(Object source, String _text) {
if (isLoggingEnabled() && isLoggingSpamEnabled()) {
if (source != null) {
Log.v(getLogPrefix(source), _text);
} else {
Log.v("null", _text);
}
Log.v(getLogPrefix(source), _text);
}
}
@ -129,9 +103,9 @@ public class AppLog {
public static Log instance;
private AppSettings appSettings;
private final DateFormat dateFormat;
private final ArrayList<String> logBuffer;
private final ArrayList<Observer> observers;
private SimpleDateFormat dateFormat;
private ArrayList<String> logBuffer;
private ArrayList<Observer> observers;
private Log() {
this(null);
@ -144,8 +118,7 @@ public class AppLog {
} else {
logBuffer = new ArrayList<>();
}
SimpleDateFormat.getTimeInstance();
dateFormat = SimpleDateFormat.getDateInstance();
dateFormat = new SimpleDateFormat("HH:mm:ss");
observers = new ArrayList<>();
}

View file

@ -1,15 +1,15 @@
/*
This file is part of the dandelion*.
dandelion* is free software: you can redistribute it and/or modify
This file is part of the Diaspora for Android.
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.util;
@ -17,81 +17,117 @@ package com.github.dfa.diaspora_android.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Environment;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.BuildConfig;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaAspect;
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.web.ProxyHandler;
import net.gsantner.opoc.preference.SharedPreferencesPropertyBackend;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.util.List;
/**
* Settings
* Created by gsantner (gsantner AT mailbox DOT org) on 20.03.16. Part of dandelion*.
* Created by gsantner (https://gsantner.github.io/) on 20.03.16. Part of Diaspora for Android.
*/
@SuppressWarnings("ConstantConditions")
public class AppSettings extends SharedPreferencesPropertyBackend {
private final SharedPreferences _prefPod;
public class AppSettings {
private final SharedPreferences prefApp;
private final SharedPreferences prefPod;
private final Context context;
private DiasporaPod currentPod0Cached;
public static AppSettings get() {
return new AppSettings(App.get());
}
public AppSettings(Context context) {
super(context);
_prefPod = _context.getSharedPreferences("pod0", Context.MODE_PRIVATE);
this.context = context.getApplicationContext();
prefApp = this.context.getSharedPreferences("app", Context.MODE_PRIVATE);
prefPod = this.context.getSharedPreferences("pod0", Context.MODE_PRIVATE);
}
/**
* Clear all settings in _prefPod (Settings related to the configured pod)
* This uses commit instead of apply, since
* SettingsActivity.SettingsFragmentDebugging.showWipeSettingsDialog()
* kills the app after the calling this, so we have to block until we are finished.
*/
@SuppressLint("CommitPrefEdits")
public void resetPodSettings() {
super.resetSettings(_prefPod);
public Context getApplicationContext() {
return context;
}
/**
* Clear all settings in _prefApp (related to the App itself)
* This uses commit instead of apply, since
* SettingsActivity.SettingsFragmentDebugging.showWipeSettingsDialog()
* kills the app after the calling this, so we have to block until we are finished.
*/
@SuppressLint("CommitPrefEdits")
public void resetAppSettings() {
super.resetSettings(_prefApp);
public void clearPodSettings() {
prefPod.edit().clear().apply();
}
//#################################
//## Getter & Setter for settings
//#################################
public void clearAppSettings() {
prefApp.edit().clear().apply();
}
public String getKey(int stringKeyRessourceId) {
return context.getString(stringKeyRessourceId);
}
public boolean isKeyEqual(String key, int stringKeyRessourceId) {
return key.equals(getKey(stringKeyRessourceId));
}
private void setString(SharedPreferences pref, int keyRessourceId, String value) {
pref.edit().putString(context.getString(keyRessourceId), value).apply();
}
private void setInt(SharedPreferences pref, int keyRessourceId, int value) {
pref.edit().putInt(context.getString(keyRessourceId), value).apply();
}
private void setBool(SharedPreferences pref, int keyRessourceId, boolean value) {
pref.edit().putBoolean(context.getString(keyRessourceId), value).apply();
}
private void setStringArray(SharedPreferences pref, int keyRessourceId, Object[] values) {
StringBuilder sb = new StringBuilder();
for (Object value : values) {
sb.append("%%%");
sb.append(value.toString());
}
setString(pref, keyRessourceId, sb.toString().replaceFirst("%%%", ""));
}
private String[] getStringArray(SharedPreferences pref, int keyRessourceId) {
String value = pref.getString(context.getString(keyRessourceId), "%%%");
if (value.equals("%%%")) {
return new String[0];
}
return value.split("%%%");
}
private String getString(SharedPreferences pref, int ressourceId, String defaultValue) {
return pref.getString(context.getString(ressourceId), defaultValue);
}
private boolean getBoolean(SharedPreferences pref, int ressourceId, boolean defaultValue) {
return pref.getBoolean(context.getString(ressourceId), defaultValue);
}
private int getInt(SharedPreferences pref, int ressourceId, int defaultValue) {
return pref.getInt(context.getString(ressourceId), defaultValue);
}
public int getColor(SharedPreferences pref, String key, int defaultColor) {
return pref.getInt(key, defaultColor);
}
/*
// Setters & Getters
*/
public String getProfileId() {
return getString(R.string.pref_key__podprofile_id, "", _prefPod);
return getString(prefPod, R.string.pref_key__podprofile_id, "");
}
public void setProfileId(String profileId) {
setString(R.string.pref_key__podprofile_id, profileId, _prefPod);
setString(prefPod, R.string.pref_key__podprofile_id, profileId);
}
public boolean isLoadImages() {
return getBool(R.string.pref_key__load_images, true);
return getBoolean(prefApp, R.string.pref_key__load_images, true);
}
public int getMinimumFontSize() {
switch (getString(R.string.pref_key__font_size, "")) {
switch (getString(prefApp, R.string.pref_key__font_size, "")) {
case "huge":
return 20;
case "large":
@ -99,30 +135,43 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
case "normal":
return 8;
default:
setString(R.string.pref_key__font_size, "normal");
setString(prefApp, R.string.pref_key__font_size, "normal");
return 8;
}
}
public String getAvatarUrl() {
return getString(R.string.pref_key__podprofile_avatar_url, "", _prefPod);
return getString(prefPod, R.string.pref_key__podprofile_avatar_url, "");
}
public void setAvatarUrl(String avatarUrl) {
setString(R.string.pref_key__podprofile_avatar_url, avatarUrl, _prefPod);
setString(prefPod, R.string.pref_key__podprofile_avatar_url, avatarUrl);
}
public String getName() {
return getString(R.string.pref_key__podprofile_name, "", _prefPod);
return getString(prefPod, R.string.pref_key__podprofile_name, "");
}
public void setName(String name) {
setString(R.string.pref_key__podprofile_name, name, _prefPod);
setString(prefPod, R.string.pref_key__podprofile_name, name);
}
// 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 DiasporaPod getPod() {
upgradeLegacyPoddomain();
if (currentPod0Cached == null) {
String pref = getString(R.string.pref_key__current_pod_0, "", _prefPod);
String pref = getString(prefPod, R.string.pref_key__current_pod_0, "");
try {
currentPod0Cached = new DiasporaPod().fromJson(new JSONObject(pref));
@ -135,27 +184,24 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
public void setPod(DiasporaPod pod) {
try {
setString(R.string.pref_key__current_pod_0,
pod == null ? null : pod.toJson().toString(), _prefPod);
setString(prefPod, R.string.pref_key__current_pod_0,
pod == null ? null : pod.toJson().toString());
currentPod0Cached = pod;
} catch (JSONException ignored) {
}
}
public boolean hasPod() {
return !getString(R.string.pref_key__current_pod_0, "", _prefPod).equals("");
upgradeLegacyPoddomain();
return !getString(prefPod, R.string.pref_key__current_pod_0, "").equals("");
}
public void setPodAspects(DiasporaAspect[] aspects) {
String[] strs = new String[aspects.length];
for (int i = 0; i < strs.length; i++) {
strs[i] = aspects[i].toShareAbleText();
}
setStringArray(R.string.pref_key__podprofile_aspects, strs, _prefPod);
setStringArray(prefPod, R.string.pref_key__podprofile_aspects, aspects);
}
public DiasporaAspect[] getAspects() {
String[] s = getStringArray(R.string.pref_key__podprofile_aspects, _prefPod);
String[] s = getStringArray(prefPod, R.string.pref_key__podprofile_aspects);
DiasporaAspect[] aspects = new DiasporaAspect[s.length];
for (int i = 0; i < aspects.length; i++) {
aspects[i] = new DiasporaAspect(s[i]);
@ -164,53 +210,53 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
}
public String[] getFollowedTags() {
return getStringArray(R.string.pref_key__podprofile_followed_tags, _prefPod);
return getStringArray(prefPod, R.string.pref_key__podprofile_followed_tags);
}
public void setFollowedTags(String[] values) {
setStringArray(R.string.pref_key__podprofile_followed_tags, values, _prefPod);
setStringArray(prefPod, R.string.pref_key__podprofile_followed_tags, values);
}
public String[] getFollowedTagsFavs() {
return getStringArray(R.string.pref_key__podprofile_followed_tags_favs, _prefPod);
return getStringArray(prefPod, R.string.pref_key__podprofile_followed_tags_favs);
}
public void setFollowedTagsFavs(List<String> values) {
setStringList(R.string.pref_key__podprofile_followed_tags_favs, values, _prefPod);
setStringArray(prefPod, R.string.pref_key__podprofile_followed_tags_favs, values.toArray(new String[values.size()]));
}
public String[] getAspectFavs() {
return getStringArray(R.string.pref_key__podprofile_aspects_favs, _prefPod);
return getStringArray(prefPod, R.string.pref_key__podprofile_aspects_favs);
}
public void setAspectFavs(List<String> values) {
setStringList(R.string.pref_key__podprofile_aspects_favs, values, _prefPod);
setStringArray(prefPod, R.string.pref_key__podprofile_aspects_favs, values.toArray(new String[values.size()]));
}
public int getUnreadMessageCount() {
return getInt(R.string.pref_key__podprofile_unread_message_count, 0, _prefPod);
return getInt(prefPod, R.string.pref_key__podprofile_unread_message_count, 0);
}
public void setUnreadMessageCount(int unreadMessageCount) {
setInt(R.string.pref_key__podprofile_unread_message_count, unreadMessageCount, _prefPod);
setInt(prefPod, R.string.pref_key__podprofile_unread_message_count, unreadMessageCount);
}
public int getNotificationCount() {
return getInt(R.string.pref_key__podprofile_notification_count, 0, _prefPod);
return getInt(prefPod, R.string.pref_key__podprofile_notification_count, 0);
}
public void setNotificationCount(int notificationCount) {
setInt(R.string.pref_key__podprofile_notification_count, notificationCount, _prefPod);
setInt(prefPod, R.string.pref_key__podprofile_notification_count, notificationCount);
}
public boolean isAppendSharedViaApp() {
return getBool(R.string.pref_key__append_shared_via_app, true);
return getBoolean(prefApp, R.string.pref_key__append_shared_via_app, true);
}
@SuppressLint("CommitPrefEdits")
public void setProxyHttpEnabled(boolean enabled) {
//commit instead of apply because the app is likely to be killed before apply is called.
_prefApp.edit().putBoolean(rstr(R.string.pref_key__http_proxy_enabled), enabled).commit();
prefApp.edit().putBoolean(context.getString(R.string.pref_key__http_proxy_enabled), enabled).commit();
}
/**
@ -219,16 +265,11 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
* @return whether proxy is enabled or not
*/
public boolean isProxyHttpEnabled() {
try {
return getBool(R.string.pref_key__http_proxy_enabled, false);
} catch (ClassCastException e) {
setProxyHttpEnabled(false);
return false;
}
return getBoolean(prefApp, R.string.pref_key__http_proxy_enabled, false);
}
public boolean wasProxyEnabled() {
return getBool(R.string.pref_key__proxy_was_enabled, false);
return getBoolean(prefApp, R.string.pref_key__proxy_was_enabled, false);
}
/**
@ -239,7 +280,7 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
*/
@SuppressLint("CommitPrefEdits")
public void setProxyWasEnabled(boolean b) {
_prefApp.edit().putBoolean(rstr(R.string.pref_key__proxy_was_enabled), b).commit();
prefApp.edit().putBoolean(context.getString(R.string.pref_key__proxy_was_enabled), b).commit();
}
/**
@ -248,11 +289,11 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
* @return proxy host
*/
public String getProxyHttpHost() {
return getString(R.string.pref_key__http_proxy_host, "");
return getString(prefApp, R.string.pref_key__http_proxy_host, "");
}
public void setProxyHttpHost(String value) {
setString(R.string.pref_key__http_proxy_host, value);
setString(prefApp, R.string.pref_key__http_proxy_host, value);
}
/**
@ -262,17 +303,17 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
*/
public int getProxyHttpPort() {
try {
String str = getString(R.string.pref_key__http_proxy_port, "0");
String str = getString(prefApp, R.string.pref_key__http_proxy_port, "0");
return Integer.parseInt(str);
} catch (ClassCastException e) {
int port = getInt(R.string.pref_key__http_proxy_port, 0);
int port = getInt(prefApp, R.string.pref_key__http_proxy_port, 0);
setProxyHttpPort(port);
return port;
}
}
public void setProxyHttpPort(int value) {
setString(R.string.pref_key__http_proxy_port, Integer.toString(value));
setString(prefApp, R.string.pref_key__http_proxy_port, Integer.toString(value));
}
public ProxyHandler.ProxySettings getProxySettings() {
@ -280,201 +321,98 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
}
public boolean isIntellihideToolbars() {
return getBool(R.string.pref_key__intellihide_toolbars, false);
return getBoolean(prefApp, R.string.pref_key__intellihide_toolbars, true);
}
public boolean isChromeCustomTabsEnabled() {
return getBool(R.string.pref_key__chrome_custom_tabs_enabled, true);
return getBoolean(prefApp, R.string.pref_key__chrome_custom_tabs_enabled, true);
}
public boolean isLoggingEnabled() {
return getBool(R.string.pref_key__logging_enabled, false);
return getBoolean(prefApp, R.string.pref_key__logging_enabled, false);
}
public boolean isLoggingSpamEnabled() {
return getBool(R.string.pref_key__logging_spam_enabled, false);
return getBoolean(prefApp, R.string.pref_key__logging_spam_enabled, false);
}
public boolean isVisibleInNavExit() {
return getBool(R.string.pref_key__visibility_nav__exit, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__exit, false);
}
public boolean isVisibleInNavHelp_license() {
return getBool(R.string.pref_key__visibility_nav__help_license, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__help_license, true);
}
public boolean isVisibleInNavPublic_activities() {
return getBool(R.string.pref_key__visibility_nav__public_activities, false);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__public_activities, false);
}
public boolean isVisibleInNavMentions() {
return getBool(R.string.pref_key__visibility_nav__mentions, false);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__mentions, false);
}
public boolean isVisibleInNavCommented() {
return getBool(R.string.pref_key__visibility_nav__commented, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__commented, true);
}
public boolean isVisibleInNavLiked() {
return getBool(R.string.pref_key__visibility_nav__liked, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__liked, true);
}
public boolean isVisibleInNavActivities() {
return getBool(R.string.pref_key__visibility_nav__activities, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__activities, true);
}
public boolean isVisibleInNavAspects() {
return getBool(R.string.pref_key__visibility_nav__aspects, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__aspects, true);
}
public boolean isVisibleInNavFollowed_tags() {
return getBool(R.string.pref_key__visibility_nav__followed_tags, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__followed_tags, true);
}
public boolean isVisibleInNavProfile() {
return getBool(R.string.pref_key__visibility_nav__profile, true);
return getBoolean(prefApp, R.string.pref_key__visibility_nav__profile, true);
}
public boolean isVisibleInNavContacts() {
return getBool(R.string.pref_key__visibility_nav__contacts, false);
}
public boolean isVisibleInNavStatistics() {
return getBool(R.string.pref_key__visibility_nav__statistics, false);
}
public boolean isVisibleInNavReports() {
return getBool(R.string.pref_key__visibility_nav__reports, false);
}
public boolean isVisibleInNavGsantnerAccount() {
return getBool(R.string.pref_key__visibility_nav__gsantner_account, false);
}
public boolean isVisibleInNavToggleMobileDesktop() {
return getBool(R.string.pref_key__visibility_nav__toggle_mobile_desktop, false);
}
public boolean isTopbarStreamShortcutEnabled() {
return getBool(R.string.pref_key__topbar_stream_shortcut, false);
}
public boolean isOpenYoutubeExternalEnabled() {
return getBool(R.string.pref_key__open_youtube_external_enabled, true);
}
public boolean isSwipeRefreshEnabled() {
return getBool(R.string.pref_key__swipe_refresh_enabled, true);
}
public String getScreenRotation() {
return getString(R.string.pref_key__screen_rotation, R.string.rotation_val_system);
}
public boolean isAppFirstStart() {
boolean value = getBool(R.string.pref_key__app_first_start, true);
setBool(R.string.pref_key__app_first_start, false);
return value;
}
public boolean isAppCurrentVersionFirstStart(boolean doSet) {
int value = getInt(R.string.pref_key__app_first_start_current_version, -1);
if (doSet) {
setInt(R.string.pref_key__app_first_start_current_version, BuildConfig.VERSION_CODE);
}
return value != BuildConfig.VERSION_CODE && !BuildConfig.IS_TEST_BUILD;
}
public File getAppSaveDirectory() {
return new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/dandelion");
}
public long getLastVisitedPositionInStream() {
return getLong(R.string.pref_key__podprofile_last_stream_position, -1, _prefPod);
}
public void setLastVisitedPositionInStream(long timestamp) {
setLong(R.string.pref_key__podprofile_last_stream_position, timestamp, _prefPod);
}
public void setLanguage(String value) {
setString(R.string.pref_key__language, value);
}
public String getLanguage() {
return getString(R.string.pref_key__language, "");
return getBoolean(prefApp, R.string.pref_key__visibility_nav__contacts, false);
}
public void setPrimaryColorSettings(int base, int shade) {
setInt(R.string.pref_key__primary_color_base, base);
setInt(R.string.pref_key__primary_color_shade, shade);
setInt(prefApp, R.string.pref_key__primary_color_base, base);
setInt(prefApp, R.string.pref_key__primary_color_shade, shade);
}
public int[] getPrimaryColorSettings() {
return new int[]{
getInt(R.string.pref_key__primary_color_base, rcolor(R.color.md_blue_650)),
getInt(R.string.pref_key__primary_color_shade, rcolor(R.color.primary))
getInt(prefApp, R.string.pref_key__primary_color_base, context.getResources().getColor(R.color.md_blue_500)),
getInt(prefApp, R.string.pref_key__primary_color_shade, context.getResources().getColor(R.color.primary))
};
}
@SuppressWarnings("ConstantConditions")
public int getPrimaryColor() {
if (isAmoledColorMode()) {
return Color.BLACK;
} else {
return getInt(R.string.pref_key__primary_color_shade, rcolor(
BuildConfig.IS_TEST_BUILD ? R.color.md_brown_800 : R.color.primary));
}
return getInt(prefApp, R.string.pref_key__primary_color_shade, context.getResources().getColor(R.color.primary));
}
public void setAccentColorSettings(int base, int shade) {
setInt(R.string.pref_key__accent_color_base, base);
setInt(R.string.pref_key__accent_color_shade, shade);
setInt(prefApp, R.string.pref_key__accent_color_base, base);
setInt(prefApp, R.string.pref_key__accent_color_shade, shade);
}
public int[] getAccentColorSettings() {
return new int[]{
getInt(R.string.pref_key__accent_color_base, rcolor(R.color.md_green_400)),
getInt(R.string.pref_key__accent_color_shade, rcolor(R.color.accent))
getInt(prefApp, R.string.pref_key__accent_color_base, context.getResources().getColor(R.color.md_deep_orange_500)),
getInt(prefApp, R.string.pref_key__accent_color_shade, context.getResources().getColor(R.color.accent))
};
}
public int getAccentColor() {
return getInt(R.string.pref_key__accent_color_shade, rcolor(R.color.accent));
return getInt(prefApp, R.string.pref_key__accent_color_shade, context.getResources().getColor(R.color.accent));
}
public boolean isExtendedNotificationsActivated() {
return getBool(R.string.pref_key__extended_notifications, false);
return getBoolean(prefApp, R.string.pref_key__extended_notifications, false);
}
public boolean isAmoledColorMode() {
return getBool(R.string.pref_key__primary_color__amoled_mode, false);
}
public void setAmoledColorMode(boolean enable) {
setBool(R.string.pref_key__primary_color__amoled_mode, enable);
}
public boolean isAdBlockEnabled() {
return getBool(R.string.pref_key__adblock_enable, true);
}
public boolean isEditorStatusBarHidden() {
return getBool(R.string.pref_key__is_overview_statusbar_hidden, false);
}
public void setRecreateMainActivity(boolean value) {
setBool(R.string.pref_key__recreate_main_activity, value);
}
public boolean isRecreateMainActivity() {
boolean value = getBool(R.string.pref_key__recreate_main_activity, false);
setRecreateMainActivity(false);
return value;
}
public boolean isShowTitleInMainView() {
return getBool(R.string.pref_key__show_title, false);
}
}
}

View file

@ -1,58 +0,0 @@
package com.github.dfa.diaspora_android.util;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import com.github.dfa.diaspora_android.App;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
@SuppressWarnings({"WeakerAccess", "unused", "SameParameterValue"})
public class ContextUtils extends net.gsantner.opoc.util.ContextUtils {
protected ContextUtils(Context context) {
super(context);
}
public static ContextUtils get() {
return new ContextUtils(App.get());
}
public File createImageFile() throws IOException {
// 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(ContextUtils.class, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
return new File(
imageFileName + /* prefix */
".jpg", /* suffix */
storageDir.getAbsolutePath() /* directory */
);
}
public void logBundle(Bundle savedInstanceState, String k) {
if (savedInstanceState != null) {
for (String key : savedInstanceState.keySet()) {
AppLog.d("Bundle", key + " is a key in the bundle " + k);
Object bun = savedInstanceState.get(key);
if (bun != null) {
if (bun instanceof Bundle) {
logBundle((Bundle) bun, k + "." + key);
} else if (bun instanceof byte[]) {
AppLog.d("Bundle", "Key: " + k + "." + key + ": " + Arrays.toString((byte[]) bun));
} else {
AppLog.d("Bundle", "Key: " + k + "." + key + ": " + bun.toString());
}
}
}
}
}
}

View file

@ -1,18 +1,18 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
@ -27,15 +27,13 @@ import com.github.dfa.diaspora_android.data.DiasporaPodList.DiasporaPod;
* Helper class that provides easy access to specific urls related to diaspora
* Created by vanitasvitae on 10.08.16.
*/
@SuppressWarnings({"unused", "SpellCheckingInspection", "SameParameterValue", "WeakerAccess"})
@SuppressWarnings("unused")
public class DiasporaUrlHelper {
private final AppSettings settings;
public static final String URL_BLANK = "about:blank";
public static final String SUBURL_NOTIFICATIONS = "/notifications";
public static final String SUBURL_POSTS = "/posts/";
public static final String SUBURL_STREAM = "/stream";
public static final String SUBURL_STREAM_WITH_TIMESTAMP = SUBURL_STREAM + "?max_time=";
public static final String SUBURL_CONVERSATIONS = "/conversations";
public static final String SUBURL_NEW_POST = "/status_messages/new";
public static final String SUBURL_PEOPLE = "/people/";
@ -54,22 +52,21 @@ public class DiasporaUrlHelper {
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_CONTACTS = "/contacts";
public static final String SUBURL_REPORTS = "/reports";
public static final String SUBURL_MANAGE_CONTACTS = "/contacts";
public static final String URL_BLANK = "about:blank";
public static final String SUBURL_NOTIFICATIONS_ALSO_COMMENTED = "/notifications?type=also_commented";
public static final String SUBURL_NOTIFICATIONS_COMMENT_ON_POST = "/notifications?type=comment_on_post";
public static final String SUBURL_NOTIFICATIONS_LIKED = "/notifications?type=liked";
public static final String SUBURL_NOTIFICATIONS_MENTIONED = "/notifications?type=mentioned";
public static final String SUBURL_NOTIFICATIONS_RESHARED = "/notifications?type=reshared";
public static final String SUBURL_NOTIFICATIONS_STARTED_SHARING = "/notifications?type=started_sharing";
public static final String SUBURL_THEME = "/user/edit";
public DiasporaUrlHelper(AppSettings settings) {
this.settings = settings;
}
/**
* Return a url of the pod set in AppSettingsBase.
* Return a url of the pod set in AppSettings.
* Eg. https://pod.geraspora.de
*
* @return https://(pod-domain.tld)
@ -92,15 +89,6 @@ public class DiasporaUrlHelper {
return getPodUrl() + SUBURL_STREAM;
}
/**
* Return a url that points to the stream of the configured diaspora account on a timestamp
*
* @return https://(pod-domain.tld)/stream?max_time=1482057867
*/
public String getStreamWithTimestampUrl(long timestamp) {
return getPodUrl() + SUBURL_STREAM_WITH_TIMESTAMP + timestamp;
}
/**
* Return a url that points to the notifications feed of the configured diaspora account
*
@ -152,7 +140,7 @@ public class DiasporaUrlHelper {
* @param profileId Id of the profile to be shown
* @return https://(pod-domain.tld)/people/(profileId)
*/
public String getProfileUrl(String profileId) {
public String getProfileUrl(long profileId) {
return getPodUrl() + SUBURL_PEOPLE + profileId;
}
@ -230,15 +218,6 @@ public class DiasporaUrlHelper {
return getPodUrl() + SUBURL_SEARCH_TAGS + query;
}
/**
* Return a url that queries posts for the given hashtag query
*
* @return https://(pod-domain.tld)/followed_tags
*/
public String getAllFollowedTagsUrl() {
return getPodUrl() + SUBURL_FOLOWED_TAGS;
}
/**
* Return a url that queries user accounts for query
*
@ -258,16 +237,6 @@ public class DiasporaUrlHelper {
return getPodUrl() + SUBURL_STATISTICS;
}
/**
* Return an Url that points to the reports page of a the configured pod.
* Note: This url is only useful/visible for podmins and moderators.
*
* @return https://(pod-domain.tld)/reports
*/
public String getReportsUrl() {
return getPodUrl() + SUBURL_REPORTS;
}
/**
* Return a url that points to the sign in page of the pod.
*
@ -300,8 +269,8 @@ public class DiasporaUrlHelper {
*
* @return https://(pod-domain.tld)/contacts
*/
public String getContactsUrl() {
return getPodUrl() + SUBURL_CONTACTS;
public String getManageContactsUrl() {
return getPodUrl() + SUBURL_MANAGE_CONTACTS;
}
public String getSuburlNotificationsAlsoCommentedUrl() {
@ -354,13 +323,4 @@ public class DiasporaUrlHelper {
}
return app.getString(R.string.aspects);
}
/**
* Return a url that points to the settings of the pod.
*
* @return https://(pod-domain.tld)/user/edit
*/
public String getThemeUrl() {
return getPodUrl() + SUBURL_THEME;
}
}

View file

@ -0,0 +1,153 @@
/*
This file is part of the Diaspora for Android.
Diaspora for Android 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.
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.util;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
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.R;
import com.github.dfa.diaspora_android.web.WebHelper;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Arrays;
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) {
return res.getColor(ressourceId, context.getTheme());
} else {
return res.getColor(ressourceId);
}
}
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());
String imageFileName = "JPEG_" + timeStamp + "_";
AppLog.d(Helpers.class, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
return new File(
imageFileName + /* prefix */
".jpg", /* suffix */
storageDir.getAbsolutePath() /* directory */
);
}
public static String readTextfileFromRawRessource(Context context, int rawRessourceId, String linePrefix, String linePostfix) {
StringBuilder sb = new StringBuilder();
String line = "";
BufferedReader br = null;
linePrefix = linePrefix == null ? "" : linePrefix;
linePostfix = linePostfix == null ? "" : linePostfix;
try {
br = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(rawRessourceId)));
while ((line = br.readLine()) != null) {
sb.append(linePrefix);
sb.append(line);
sb.append(linePostfix);
sb.append("\n");
}
} catch (Exception ignored) {
} finally {
if (br != null) {
try {
br.close();
} catch (IOException ignored) {
}
}
}
return sb.toString();
}
public static String hexColorFromRessourceColor(Context context, int idColor) {
return "#" + Integer.toHexString(context.getResources().getColor(idColor) & 0x00ffffff);
}
public static String colorToHex(int color) {
return "#" + Integer.toHexString(color & 0x00ffffff);
}
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);
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));
} else {
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;
}
}

View file

@ -1,27 +1,36 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.web;
import android.content.Context;
import android.content.MutableContextWrapper;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.os.Environment;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
@ -30,11 +39,21 @@ import android.widget.ProgressBar;
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.ui.theme.ThemeHelper;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
import com.github.dfa.diaspora_android.util.AppLog;
import com.github.dfa.diaspora_android.util.AppSettings;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Fragment with a webView and a ProgressBar.
* This Fragment retains its instance.
@ -44,6 +63,7 @@ import com.github.dfa.diaspora_android.util.AppSettings;
public class BrowserFragment extends ThemedFragment {
public static final String TAG = "com.github.dfa.diaspora_android.BrowserFragment";
protected View rootLayout;
protected ContextMenuWebView webView;
protected ProgressBar progressBar;
protected AppSettings appSettings;
@ -51,14 +71,16 @@ public class BrowserFragment extends ThemedFragment {
protected WebSettings webSettings;
protected String pendingUrl;
protected SwipeRefreshLayout swipe;//pull to refresh
@Override
protected int getLayoutResId() {
return R.layout.browser__fragment;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
AppLog.d(this, "onCreateView()");
if (rootLayout == null) {
rootLayout = inflater.inflate(R.layout.browser__fragment, container, false);
}
return rootLayout;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
AppLog.d(this, "onViewCreated()");
@ -69,7 +91,7 @@ public class BrowserFragment extends ThemedFragment {
}
if (this.webView == null) {
this.webView = view.findViewById(R.id.webView);
this.webView = (ContextMenuWebView) view.findViewById(R.id.webView);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
@ -81,7 +103,7 @@ public class BrowserFragment extends ThemedFragment {
}
if (this.progressBar == null) {
this.progressBar = view.findViewById(R.id.progressBar);
this.progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
}
if (pendingUrl != null) {
@ -92,26 +114,14 @@ public class BrowserFragment extends ThemedFragment {
webView.setParentActivity(getActivity());
this.setRetainInstance(true);
//pull to refresh
swipe = view.findViewById(R.id.swipe);
swipe.setDistanceToTriggerSync(2000);
swipe.setOnRefreshListener(() -> reloadUrl());
if (appSettings.isSwipeRefreshEnabled()) {
swipe.setEnabled(true);
} else {
swipe.setRefreshing(false);
swipe.setEnabled(false);
return;
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (getRetainInstance() && getView() != null && getView().getParent() instanceof ViewGroup) {
((ViewGroup) getView().getParent()).removeView(getView());
if (getRetainInstance() && rootLayout.getParent() instanceof ViewGroup) {
((ViewGroup) rootLayout.getParent()).removeView(rootLayout);
}
}
@ -149,17 +159,96 @@ public class BrowserFragment extends ThemedFragment {
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
protected boolean makeScreenshotOfWebView(boolean hasToShareScreenshot) {
AppLog.i(this, "StreamFragment.makeScreenshotOfWebView()");
if (android.os.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)) {
new AlertDialog.Builder(getContext())
.setMessage(R.string.permissions_screenshot)
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (android.os.Build.VERSION.SDK_INT >= 23)
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE_ASK_PERMISSIONS);
}
})
.show();
return false;
}
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE_ASK_PERMISSIONS);
return false;
}
}
Date dateNow = new Date();
DateFormat dateFormat = new SimpleDateFormat("yy_MM_dd--HH_mm_ss", Locale.getDefault());
File fileSaveDirectory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/Diaspora");
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 (!hasToShareScreenshot) {
Snackbar.make(webView, getString(R.string.share__toast_screenshot) + " " + fileSaveName, Snackbar.LENGTH_LONG).show();
}
Bitmap bitmap;
webView.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(webView.getDrawingCache());
webView.setDrawingCacheEnabled(false);
OutputStream bitmapWriter = null;
try {
bitmapWriter = new FileOutputStream(new File(fileSaveDirectory, fileSaveName));
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, bitmapWriter);
bitmapWriter.flush();
bitmap.recycle();
} catch (Exception e) {
return false;
} finally {
if (bitmapWriter != null) {
try {
bitmapWriter.close();
} catch (IOException _ignSaveored) {/* Nothing */}
}
}
// Only show share intent when Action Share Screenshot was selected
if (hasToShareScreenshot) {
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/jpeg");
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, webView.getTitle());
sharingIntent.putExtra(Intent.EXTRA_TEXT, webView.getUrl());
Uri bmpUri = Uri.fromFile(new File(fileSaveDirectory, fileSaveName));
sharingIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
startActivity(Intent.createChooser(sharingIntent, getString(R.string.action_share_dotdotdot)));
} else {
// Broadcast that this file is indexable
File file = new File(fileSaveDirectory, fileSaveName);
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
getActivity().sendBroadcast(intent);
}
return true;
}
@Override
public String getFragmentTag() {
return TAG;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (webView != null && webView.getContext() instanceof MutableContextWrapper) {
((MutableContextWrapper) webView.getContext()).setBaseContext(context);
}
public void onCreateBottomOptionsMenu(Menu menu, MenuInflater inflater) {
/* Nothing to do here */
}
public boolean onBackPressed() {
@ -206,7 +295,6 @@ public class BrowserFragment extends ThemedFragment {
@Override
public void run() {
getWebView().reload();
swipe.setRefreshing(false);//pull to refresh
}
});

View file

@ -1,44 +1,47 @@
/*
This file is part of the dandelion*.
This file is part of the Diaspora for Android.
dandelion* is free software: you can redistribute it and/or modify
Diaspora for Android 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.
dandelion* is distributed in the hope that it will be useful,
Diaspora for Android is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
along with the Diaspora for Android.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.web;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.content.LocalBroadcastManager;
import android.util.AttributeSet;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.widget.Toast;
import com.github.dfa.diaspora_android.BuildConfig;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.util.AppSettings;
import net.gsantner.opoc.util.DownloadTask;
import net.gsantner.opoc.util.PermissionChecker;
import net.gsantner.opoc.util.ShareUtil;
import com.github.dfa.diaspora_android.activity.MainActivity;
import com.github.dfa.diaspora_android.service.ImageDownloadTask;
import java.io.File;
import java.util.Date;
/**
* Subclass of WebView which adds a context menu for long clicks on images or links to share, save
@ -49,14 +52,13 @@ public class ContextMenuWebView extends NestedWebView {
public static final int ID_SAVE_IMAGE = 10;
public static final int ID_IMAGE_EXTERNAL_BROWSER = 11;
public static final int ID_COPY_IMAGE_LINK = 15;
public static final int ID_COPY_LINK = 12;
public static final int ID_SHARE_LINK = 13;
public static final int ID_SHARE_IMAGE = 14;
private final Context context;
private Activity parentActivity;
private String lastLoadUrl = "";
private String lasLoadUrl = "";
public ContextMenuWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
@ -78,46 +80,93 @@ public class ContextMenuWebView extends NestedWebView {
public boolean onMenuItemClick(MenuItem item) {
HitTestResult result = getHitTestResult();
String url = result.getExtra();
final ShareUtil shu = new ShareUtil(context);
final PermissionChecker permc = new PermissionChecker(parentActivity);
final AppSettings appSettings = new AppSettings(context);
switch (item.getItemId()) {
//Save image to external memory
case ID_SAVE_IMAGE: {
if (permc.doIfExtStoragePermissionGranted(context.getString(R.string.image_permission_description__appspecific))) {
File fileSaveDirectory = appSettings.getAppSaveDirectory();
if (permc.mkdirIfStoragePermissionGranted(fileSaveDirectory)) {
String filename = "dandelion-" + ShareUtil.SDF_SHORT.format(new Date()) + url.substring(url.lastIndexOf("."));
/*Uri source = Uri.parse(url);
boolean writeToStoragePermitted = true;
if (android.os.Build.VERSION.SDK_INT >= 23) {
int hasWRITE_EXTERNAL_STORAGE = parentActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
writeToStoragePermitted = false;
if (!parentActivity.shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(parentActivity)
.setMessage(R.string.permissions_image)
.setPositiveButton(context.getText(android.R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (android.os.Build.VERSION.SDK_INT >= 23)
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
}
})
.setNegativeButton(context.getText(android.R.string.no), null)
.show();
}
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
}
}
if (writeToStoragePermitted) {
if (url != null) {
Uri source = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(source);
request.setDestinationUri(Uri.fromFile(new File(fileSaveDirectory, filename)));
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);*/
new DownloadTask(new File(fileSaveDirectory, filename), (ok, dlfile) -> {
if (ok) {
Toast.makeText(context, context.getText(R.string.saving_image_to) + " " + dlfile.getName(), Toast.LENGTH_LONG).show();
}
}).execute(url);
File destinationFile = new File(Environment.getExternalStorageDirectory() + "/Pictures/Diaspora/"
+ System.currentTimeMillis() + ".png");
request.setDestinationUri(Uri.fromFile(destinationFile));
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
Toast.makeText(context, context.getText(R.string.share__toast_saved_image_to_location) + " " +
destinationFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
}
}
break;
}
break;
case ID_SHARE_IMAGE: {
if (permc.doIfExtStoragePermissionGranted(context.getString(R.string.image_permission_description__appspecific))) {
File fileSaveDirectory = appSettings.getAppSaveDirectory();
if (permc.mkdirIfStoragePermissionGranted(fileSaveDirectory)) {
String filename = ".dandelion-shared" + url.substring(url.lastIndexOf("."));
new DownloadTask(new File(fileSaveDirectory, filename), (ok, dlfile) -> {
if (ok) {
Toast.makeText(context, context.getText(R.string.saving_image_to) + " " + dlfile.getName(), Toast.LENGTH_LONG).show();
shu.shareStream(dlfile, "image/" + dlfile.getAbsolutePath().lastIndexOf(".") + 1);
case ID_SHARE_IMAGE:
if (url != null) {
boolean writeToStoragePermitted = true;
if (android.os.Build.VERSION.SDK_INT >= 23) {
int hasWRITE_EXTERNAL_STORAGE = parentActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
writeToStoragePermitted = false;
if (!parentActivity.shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(parentActivity)
.setMessage(R.string.permissions_image)
.setPositiveButton(context.getText(android.R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (android.os.Build.VERSION.SDK_INT >= 23)
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
}
})
.setNegativeButton(context.getText(android.R.string.no), null)
.show();
} else {
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
}
}).execute(url);
}
}
if (writeToStoragePermitted) {
final Uri local = Uri.parse(Environment.getExternalStorageDirectory() + "/Pictures/Diaspora/" + System.currentTimeMillis() + ".png");
new ImageDownloadTask(null, local.getPath()) {
@Override
protected void onPostExecute(Bitmap result) {
Uri myUri = Uri.fromFile(new File(local.getPath()));
Intent sharingIntent = new Intent();
sharingIntent.setAction(Intent.ACTION_SEND);
sharingIntent.putExtra(Intent.EXTRA_STREAM, myUri);
sharingIntent.setType("image/png");
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.action_share_dotdotdot)));
}
}.execute(url);
}
} else {
Toast.makeText(context, "Cannot share image: url is null", Toast.LENGTH_SHORT).show();
}
break;
}
case ID_IMAGE_EXTERNAL_BROWSER:
if (url != null) {
@ -127,12 +176,11 @@ public class ContextMenuWebView extends NestedWebView {
break;
//Copy url to clipboard
case ID_COPY_IMAGE_LINK:
case ID_COPY_LINK:
if (url != null) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(ClipData.newPlainText("text", url));
Toast.makeText(context, R.string.link_adress_copied, Toast.LENGTH_SHORT).show();
Toast.makeText(context, R.string.share__toast_link_address_copied, Toast.LENGTH_SHORT).show();
}
break;
@ -144,7 +192,7 @@ public class ContextMenuWebView extends NestedWebView {
sendIntent.putExtra(Intent.EXTRA_TEXT, url);
sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, getResources()
.getText(R.string.share_link_address)));
.getText(R.string.context_menu_share_link)));
}
break;
}
@ -157,16 +205,15 @@ public class ContextMenuWebView extends NestedWebView {
result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
// Menu options for an image.
menu.setHeaderTitle(result.getExtra());
menu.add(0, ID_SAVE_IMAGE, 0, context.getString(R.string.save_image)).setOnMenuItemClickListener(handler);
menu.add(0, ID_IMAGE_EXTERNAL_BROWSER, 0, context.getString(R.string.open_in_external_browser)).setOnMenuItemClickListener(handler);
menu.add(0, ID_SHARE_IMAGE, 0, context.getString(R.string.share_image)).setOnMenuItemClickListener(handler);
menu.add(0, ID_COPY_IMAGE_LINK, 0, context.getString(R.string.copy_image_address_to_clipboard)).setOnMenuItemClickListener(handler);
menu.add(0, ID_SAVE_IMAGE, 0, context.getString(R.string.context_menu_save_image)).setOnMenuItemClickListener(handler);
menu.add(0, ID_IMAGE_EXTERNAL_BROWSER, 0, context.getString(R.string.context_menu_open_external_browser)).setOnMenuItemClickListener(handler);
menu.add(0, ID_SHARE_IMAGE, 0, context.getString(R.string.context_menu_share_image)).setOnMenuItemClickListener(handler);
} else if (result.getType() == HitTestResult.ANCHOR_TYPE ||
result.getType() == HitTestResult.SRC_ANCHOR_TYPE) {
// Menu options for a hyperlink.
menu.setHeaderTitle(result.getExtra());
menu.add(0, ID_COPY_LINK, 0, context.getString(R.string.copy_link_adress_to_clipboard)).setOnMenuItemClickListener(handler);
menu.add(0, ID_SHARE_LINK, 0, context.getString(R.string.share_link_address)).setOnMenuItemClickListener(handler);
menu.add(0, ID_COPY_LINK, 0, context.getString(R.string.context_menu_copy_link)).setOnMenuItemClickListener(handler);
menu.add(0, ID_SHARE_LINK, 0, context.getString(R.string.context_menu_share_link)).setOnMenuItemClickListener(handler);
}
}
@ -178,7 +225,14 @@ public class ContextMenuWebView extends NestedWebView {
@Override
public void loadUrl(String url) {
super.loadUrl(url);
WebHelper.sendUpdateTitleByUrlIntent(url, getContext());
// Don't spam intents ;)
if (!lasLoadUrl.equals(url)) {
Intent updateActivityTitleIntent = new Intent(MainActivity.ACTION_UPDATE_TITLE_FROM_URL);
updateActivityTitleIntent.putExtra(MainActivity.EXTRA_URL, getUrl());
LocalBroadcastManager.getInstance(context).sendBroadcast(updateActivityTitleIntent);
}
lasLoadUrl = url;
}
public void setParentActivity(Activity activity) {

Some files were not shown because too many files have changed in this diff Show more