├── .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 | 15 | 16 | 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 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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