├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── gradle.xml
├── kotlinc.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── _config.yml
├── app
├── .gitignore
├── app-release.apk
├── build.gradle
├── proguard-rules.pro
├── release
│ ├── app-release.apk
│ └── output.json
└── src
│ ├── androidTest
│ └── java
│ │ └── org
│ │ └── lenchan139
│ │ └── ncbookmark
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── org
│ │ │ └── lenchan139
│ │ │ └── ncbookmark
│ │ │ ├── Class
│ │ │ ├── BookmarkItem.kt
│ │ │ ├── BookmarkItemV2.kt
│ │ │ ├── FloccusBookmarkItem.kt
│ │ │ ├── FloccusHelper.kt
│ │ │ ├── FloccusListviewItem.kt
│ │ │ └── TagsItem.kt
│ │ │ ├── Constants.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── v1
│ │ │ ├── AddBookmarkActivity.java
│ │ │ ├── BookmarkViewActivity.java
│ │ │ ├── ListViewActivity.java
│ │ │ └── TagViewActivity.java
│ │ │ ├── v2
│ │ │ ├── AddBookmarkActivityV2.kt
│ │ │ ├── BookmarkViewActivityV2.kt
│ │ │ ├── EditBookmarkActivityV2.kt
│ │ │ └── TagListActivityV2.kt
│ │ │ └── v2floccus
│ │ │ └── V2FloccusViewActivity.kt
│ └── res
│ │ ├── drawable
│ │ ├── ic_fab_add.png
│ │ ├── ic_menu_camera.xml
│ │ ├── ic_menu_gallery.xml
│ │ ├── ic_menu_manage.xml
│ │ ├── ic_menu_send.xml
│ │ ├── ic_menu_share.xml
│ │ ├── ic_menu_slideshow.xml
│ │ └── side_nav_bar.xml
│ │ ├── layout
│ │ ├── activity_add_bookmark.xml
│ │ ├── activity_add_bookmark_v2.xml
│ │ ├── activity_bookmark_view_v2.xml
│ │ ├── activity_edit_bookmark_v2.xml
│ │ ├── activity_list_view.xml
│ │ ├── activity_main.xml
│ │ ├── activity_tag_list_v2.xml
│ │ ├── activity_v2_floccus_view.xml
│ │ ├── app_bar_main.xml
│ │ ├── content_add_bookmark_activity_v2.xml
│ │ ├── content_bookmark_view_activity_v2.xml
│ │ ├── content_edit_bookmark_activity_v2.xml
│ │ ├── content_list_view.xml
│ │ ├── content_main.xml
│ │ ├── content_v2_floccus_view.xml
│ │ └── nav_header_main.xml
│ │ ├── menu
│ │ ├── activity_main_drawer.xml
│ │ ├── bookmark_view.xml
│ │ └── main.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-ldpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── playstore-icon.png
│ │ ├── values-v21
│ │ └── styles.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── org
│ └── lenchan139
│ └── ncbookmark
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screenshots
├── Screen_Shot_2018-07-27_at_13.26.20.png
├── index
├── photo_2017-04-15_17-12-19.jpg
└── photo_2017-04-15_17-12-21.jpg
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This project has moved GitLab
2 | This project has move to: [https://gitlab.com/lenchan139/NCBookmark](https://gitlab.com/lenchan139/NCBookmark)
3 | # NCBookmark Viewer
4 | This is a Veeeeeeeeerrrrrry lightweight viewer for NextCloud Bookamrk. I made it because my needs.
5 |
6 | ## Licenses
7 | Basically, NCBookmark is under GPLv3.
8 |
9 |
10 | #### - GNU General Public License v3.0
11 | A few files is coding by myself. Those files is licensing under GPLv3.
12 | You can go to (http://wiki.linux.org.hk/w/GPLv3) view the full content of the license.
13 | ## Screenshots
14 |
15 | ## Download
16 | You can download this application from F-Droid, Play Store or Aptoide.
17 | - [F-Droid](https://f-droid.org/packages/org.lenchan139.ncbookmark/)
18 | - [Play Store](https://play.google.com/store/apps/details?id=org.lenchan139.ncbookmark)
19 | - [Aptoide](https://nc-bookmark-viewer.en.aptoide.com/)
20 | - [APK file](https://github.com/lenchan139/NCBookmark/blob/master/app/app-release.apk?raw=true)
21 |
22 | ## Feedback
23 | I doubt that who will use this application...
24 | However, you can send feedback or feature request by mailing to mail@lenchan139.org
25 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-slate
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lenchan139/NCBookmark/ada4d5d4ad7a4335e27c1ec1040bb38328e5115a/app/app-release.apk
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdkVersion 27
6 | buildToolsVersion '27.0.3'
7 | defaultConfig {
8 | applicationId "org.lenchan139.ncbookmark"
9 | minSdkVersion 21
10 | targetSdkVersion 27
11 | versionCode 15
12 | versionName 'v15'
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | productFlavors {
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(include: ['*.jar'], dir: 'libs')
27 | androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
28 | exclude group: 'com.android.support', module: 'support-annotations'
29 | })
30 | api "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
31 | api 'com.android.support:appcompat-v7:27.1.1'
32 | api 'com.android.support.constraint:constraint-layout:1.1.2'
33 | api 'com.android.support:design:27.1.1'
34 | api 'org.jsoup:jsoup:1.10.2'
35 | api 'com.google.code.gson:gson:2.8.0'
36 | testImplementation 'junit:junit:4.12'
37 | }
38 | repositories {
39 | mavenCentral()
40 | }
41 |
42 | apply plugin: 'kotlin-android-extensions'
43 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/len/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/release/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lenchan139/NCBookmark/ada4d5d4ad7a4335e27c1ec1040bb38328e5115a/app/release/app-release.apk
--------------------------------------------------------------------------------
/app/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":15,"versionName":"v15","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
--------------------------------------------------------------------------------
/app/src/androidTest/java/org/lenchan139/ncbookmark/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("org.lenchan139.ncbookmark", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
30 |
34 |
35 |
38 |
42 |
46 |
47 |
48 |
49 |
50 |
54 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/Class/BookmarkItem.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark.Class
2 |
3 | /**
4 | * Created by len on 10/3/2017.
5 | */
6 |
7 | class BookmarkItem {
8 | var title: String? = null
9 | var url: String? = null
10 | var tags: String? = null
11 | var id: Int = 0
12 |
13 | override fun toString(): String {
14 | return "$url|$title|$tags"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/Class/BookmarkItemV2.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark.Class
2 |
3 | import org.json.JSONArray
4 |
5 | /**
6 | * Created by len on 28/6/2017.
7 | */
8 |
9 | class BookmarkItemV2{
10 |
11 | var title: String? = null
12 | var url: String? = null
13 | var tags: JSONArray? = null
14 | var id: Int = 0
15 |
16 | override fun toString(): String {
17 | return "$url|$title|$tags"
18 | }
19 | fun hasTag(tag:String): Boolean {
20 | if(tags != null){
21 | for(o in 0..tags!!.length()-1){
22 | if(tag.equals(tags!![o])){
23 | return true
24 | }
25 | }
26 | }
27 | return false
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/Class/FloccusBookmarkItem.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark.Class
2 |
3 | import android.util.Log
4 | import org.lenchan139.ncbookmark.Constants
5 |
6 | class FloccusBookmarkItem(rawTagContent:String){
7 | val arrayTagsLevel = ArrayList()
8 | init {
9 | Log.v("arrayTestFBItem1",rawTagContent)
10 | if(rawTagContent.startsWith(Constants.FLOCCUS_TAG_PREFIX) && rawTagContent.contains(">")){
11 |
12 | val tagsString = rawTagContent.substringAfter(Constants.FLOCCUS_TAG_PREFIX)
13 | val tags = rawTagContent.split(">")
14 | Log.v("arrayTestFBItem2",tags.toString())
15 | for(tag in tags){
16 | if(tag.isNotEmpty())
17 | arrayTagsLevel.add(tag)
18 | }
19 |
20 | Log.v("arrayTestFBItem3",arrayTagsLevel.toArray().contentToString())
21 | }else{
22 |
23 |
24 | }
25 | }
26 | fun get(i:Int):String{
27 | return arrayTagsLevel.get(i)
28 | }
29 | fun set(i:Int,str:String):ArrayList{
30 | arrayTagsLevel.set(i,str)
31 | return arrayTagsLevel
32 | }
33 | fun count():Int{
34 | return arrayTagsLevel.size
35 | }
36 | fun getFullPath():String{
37 | return getFullWithParent(count()-1)
38 | }
39 | fun getFullWithParent(to:Int):String{
40 | if(arrayTagsLevel.size > 1){
41 | var result = arrayTagsLevel[0]
42 | for(i in 1..to){
43 | result += ">" + arrayTagsLevel.get(i)
44 | }
45 | return result
46 | }else{
47 | return ""
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/Class/FloccusHelper.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark.Class
2 |
3 | import android.provider.SyncStateContract
4 | import android.util.Log
5 | import org.lenchan139.ncbookmark.Constants
6 |
7 | class FloccusHelper{
8 | var bookmarks = ArrayList()
9 | var currentPathLevel = 0
10 | var currentPath = Constants.FLOCCUS_TAG_PREFIX
11 | var currentBookmarksSet = 0
12 | fun add(floccusBookmark:FloccusBookmarkItem): ArrayList {
13 | bookmarks.add(floccusBookmark)
14 | return bookmarks
15 | }
16 | fun addFromString(str:String):ArrayList{
17 | Log.v("arrayTestFHObj0",str)
18 | val obj = FloccusBookmarkItem(str)
19 | Log.v("arrayTestFHObj1", obj.count().toString())
20 | bookmarks.add(obj)
21 | return bookmarks
22 | }
23 | fun canBack():Boolean{
24 | return (currentPath.contains(">")) || (currentPathLevel>0)
25 | }
26 | fun goBack():Boolean{
27 | if(currentPath.contains(">") || currentPathLevel<=0){
28 | val curr = currentPath.split(">").toTypedArray()
29 | curr[curr.lastIndex] = ""
30 | var newPath = curr[0]
31 | for(i in 1..curr.lastIndex-1){
32 | newPath += ">" + curr[i]
33 | }
34 | currentPath = newPath
35 | currentPathLevel -= 1
36 | return true
37 | }else{
38 | return false
39 | }
40 | }
41 | fun enterNextUseTag(nextTag:String):Boolean{
42 | val nextPath = currentPath + ">" + nextTag
43 | for(obj in bookmarks){
44 | if(obj.getFullPath().contains(nextPath)){
45 | currentPath = nextPath
46 | currentPathLevel += 1
47 | return true
48 | }
49 | }
50 | return false
51 | }
52 | fun getPossibleLowerPath():ArrayList{
53 | val arraylist = ArrayList()
54 | val nextIndex = currentPathLevel + 1
55 | Log.v("arrayTestFH0",bookmarks[0].arrayTagsLevel.size.toString())
56 | for(i in bookmarks.indices){
57 | Log.v("arrayTestFH1",i.toString())
58 | val path = currentPath
59 | Log.v("arrayTestFH2Path",path)
60 | val arr = bookmarks[i].arrayTagsLevel
61 | Log.v("arrayTestFH3",bookmarks[i].getFullPath())
62 | if (bookmarks[i].getFullPath().startsWith(currentPath) && arr.size > 0){
63 | Log.v("arrayTest", arr.toString())
64 | if(arr.size > nextIndex) {
65 | if (!arraylist.contains(arr[nextIndex])) {
66 | arraylist.add(arr[nextIndex])
67 | }
68 | }
69 | }
70 | }
71 | Log.v("currentLevel",arraylist.toArray().contentToString())
72 | return arraylist
73 | }
74 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/Class/FloccusListviewItem.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark.Class
2 |
3 | class FloccusListviewItem(var type:Int, var uri:String, var bookmarkItem:BookmarkItemV2?){
4 |
5 | }
6 | class FloccusListviewItemConst(){
7 | val ITEM_TYPE_TAG : Int = 0
8 | val ITEM_TYPE_BOOKMARK : Int = 1
9 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/Class/TagsItem.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark.Class
2 |
3 | import org.json.JSONArray
4 |
5 | /**
6 | * Created by len on 28/6/2017.
7 | */
8 | class TagsItem{
9 | fun jsonArrayToString(jsonArray: JSONArray): String?{
10 |
11 | if(jsonArray.length() == 1){
12 | return jsonArray.getString(0)
13 | }else if (jsonArray.length() >= 2){
14 | var array : ArrayList
15 | var str : String
16 | str = jsonArray.getString(0)
17 | for(i in 1..jsonArray.length()-1){
18 | str = str + "," + jsonArray.getString(i)
19 | }
20 | return str
21 | }
22 | return null
23 | }
24 |
25 | fun strToArray(str: String): Array? {
26 | if(str.indexOf(",")<=0){
27 | return arrayOf(str)
28 | }else if(str.indexOf(",")>=1){
29 | return str.split(",").toTypedArray()
30 |
31 | }
32 | return null
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/Constants.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark
2 |
3 | class Constants
4 | {
5 | companion object {
6 | val V2_API_ENDPOINT = "/apps/bookmarks/public/rest/v2/";
7 | val FLOCCUS_TAG_PREFIX = "floccus:"
8 | }
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/lenchan139/ncbookmark/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package org.lenchan139.ncbookmark
2 |
3 | import android.app.Activity
4 | import android.content.Intent
5 | import android.content.SharedPreferences
6 | import android.os.AsyncTask
7 | import android.support.v7.app.AppCompatActivity
8 | import android.os.Bundle
9 | import android.util.Base64
10 | import android.util.Log
11 | import android.widget.*
12 | import org.jsoup.Connection
13 | import org.jsoup.HttpStatusException
14 | import org.jsoup.Jsoup
15 | import org.jsoup.nodes.Document
16 |
17 | import org.lenchan139.ncbookmark.v1.TagViewActivity
18 | import org.lenchan139.ncbookmark.v2.TagListActivityV2
19 | import org.lenchan139.ncbookmark.v2floccus.V2FloccusViewActivity
20 | import java.io.FileNotFoundException
21 | import java.io.IOException
22 | import java.net.URL
23 | import java.net.UnknownHostException
24 |
25 | class MainActivity : AppCompatActivity() {
26 | internal lateinit var edtUrl: EditText
27 | internal lateinit var edtUsername: EditText
28 | internal lateinit var edtPassword: EditText
29 | internal lateinit var btnSave: Button
30 | internal lateinit var sp: SharedPreferences
31 | internal lateinit var url: String
32 | internal lateinit var username: String
33 | internal lateinit var password: String
34 | internal lateinit var spinnerApi : Spinner
35 | internal lateinit var spinnerUrlPrefix : Spinner
36 | val apiString = arrayOf("v2 with Floccus", "v2", "v1")
37 | val urlPrefixArray = arrayOf("https://","http://")
38 | internal var urlSe = Constants.V2_API_ENDPOINT + "tag"
39 | override fun onCreate(savedInstanceState: Bundle?) {
40 | super.onCreate(savedInstanceState)
41 | setContentView(R.layout.activity_main)
42 | sp = getSharedPreferences("data", 0)
43 |
44 | edtUrl = findViewById(R.id.url)
45 | edtUsername = findViewById(R.id.username)
46 | edtPassword = findViewById(R.id.password)
47 | btnSave = findViewById