Skip to content

Commit 1a9225e

Browse files
author
Nicholas Harrison
committed
2 parents 1ef1b1b + c010310 commit 1a9225e

File tree

124 files changed

+1767
-700
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+1767
-700
lines changed

.github/workflows/android-build-master.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build on PR Create or Merge
1+
name: Build
22

33
on:
44
pull_request:
@@ -7,18 +7,20 @@ on:
77
push:
88
branches:
99
- 'master'
10+
- 'release-*'
1011

1112
jobs:
1213
build:
1314
name: Generate APK
1415
runs-on: ubuntu-18.04
1516

1617
steps:
17-
- uses: actions/checkout@v1
18-
- name: Setup JDK 1.8
19-
uses: actions/setup-java@v1
18+
- uses: actions/checkout@v2
19+
- name: Setup JDK
20+
uses: actions/setup-java@v2
2021
with:
21-
java-version: 1.8
22+
distribution: 'zulu'
23+
java-version: '11'
2224
- name: Build APK
2325
run: ./gradlew assembleDebug
2426
- name: Upload APK

README.org

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#+BEGIN_HTML
2+
<a title="Build" target="_blank" href="https://github.com/orgzly/orgzly-android/actions/workflows/android-build-master.yml"><img src="https://github.com/orgzly/orgzly-android/actions/workflows/android-build-master.yml/badge.svg"></a>
23
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/orgzly"><img src="https://d322cqt584bo4o.cloudfront.net/orgzly/localized.svg"></a>
34
#+END_HTML
45

@@ -16,10 +17,10 @@ http://orgmode.org for more information.
1617

1718
#+BEGIN_HTML
1819
<a href="https://play.google.com/store/apps/details?id=com.orgzly">
19-
<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="70">
20+
<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="80">
2021
</a>
2122
<a href="https://f-droid.org/app/com.orgzly">
22-
<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="70">
23+
<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80">
2324
</a>
2425
#+END_HTML
2526

@@ -38,13 +39,6 @@ example:
3839

3940
Make sure you [[https://developer.android.com/training/testing/espresso/setup][turn off animations]] for the device you're testing on.
4041

41-
Java 8 is required for command line usage. Later versions are currently not compatible.
42-
43-
*** Dropbox
44-
45-
Dropbox integration, and associated tests, are disabled in the default configuration.
46-
To enable, follow the instructions in sample.app.properties.
47-
4842
** License
4943

5044
The project is licensed under the [[https://github.com/orgzly/orgzly-android/blob/master/LICENSE][GNU General Public License version 3 (or newer)]].

app/build.gradle

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,14 @@ apply plugin: 'kotlin-kapt'
44

55

66
android {
7-
dexOptions {
8-
maxProcessCount 4
9-
javaMaxHeapSize "2g"
10-
}
11-
12-
compileSdkVersion 29
7+
compileSdkVersion 30
138

149
defaultConfig {
1510
minSdkVersion 16 // Jelly Bean (4.1)
16-
targetSdkVersion 29 // Android 10
11+
targetSdkVersion 30 // Android 11
1712
applicationId "com.orgzly"
18-
versionCode 155
19-
versionName "1.8.4"
13+
versionCode 158
14+
versionName "1.8.5"
2015

2116
testInstrumentationRunner "com.orgzly.android.OrgzlyTestRunner"
2217
// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -26,8 +21,6 @@ android {
2621
buildConfigField "String", "DROPBOX_APP_KEY", gradle.ext.appProperties.getProperty("dropbox.app_key", '""')
2722
resValue "string", "dropbox_app_key_schema", gradle.ext.appProperties.getProperty("dropbox.app_key_schema", '')
2823

29-
buildConfigField "boolean", "IS_GIT_ENABLED", gradle.ext.appProperties.getProperty("git.enabled", 'false')
30-
3124
javaCompileOptions {
3225
annotationProcessorOptions {
3326
arguments = [
@@ -103,15 +96,18 @@ android {
10396
* javax.servlet.http. Referenced from com.dropbox.core.DbxStandardSessionStore.
10497
*/
10598
disable 'InvalidPackage'
99+
100+
checkDependencies true
106101
}
107102

108103
compileOptions {
109-
sourceCompatibility JavaVersion.VERSION_1_8
110-
targetCompatibility JavaVersion.VERSION_1_8
104+
sourceCompatibility JavaVersion.VERSION_11
105+
targetCompatibility JavaVersion.VERSION_11
111106
}
112107

113108
packagingOptions {
114109
exclude 'META-INF/DEPENDENCIES'
110+
exclude 'plugin.properties'
115111
}
116112
}
117113

@@ -134,7 +130,7 @@ dependencies {
134130
implementation "androidx.recyclerview:recyclerview:$versions.android_recyclerview"
135131
implementation "androidx.viewpager:viewpager:$versions.android_viewpager"
136132
implementation "androidx.constraintlayout:constraintlayout:$versions.android_constraint_layout"
137-
implementation "androidx.preference:preference:$versions.android_preference"
133+
implementation "androidx.preference:preference-ktx:$versions.android_preference"
138134
implementation "com.google.android.material:material:$versions.android_material"
139135
implementation "androidx.swiperefreshlayout:swiperefreshlayout:$versions.android_swiperefreshlayout"
140136

@@ -196,14 +192,20 @@ dependencies {
196192

197193
implementation "com.github.bumptech.glide:glide:$versions.glide"
198194

199-
implementation("com.thegrizzlylabs.sardine-android:sardine-android:$versions.sardine") {
195+
implementation("com.github.thegrizzlylabs:sardine-android:$versions.sardine") {
200196
exclude group: 'xpp3', module: 'xpp3'
201197
}
202198

203-
implementation("org.eclipse.jgit:org.eclipse.jgit:$versions.jgit") {
204-
// Resolves DuplicatePlatformClasses lint error
205-
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
199+
constraints {
200+
implementation('com.squareup.okhttp3:okhttp:4.10.0-RC1') {
201+
because 'https://github.com/orgzly/orgzly-android/issues/880'
202+
}
206203
}
204+
205+
implementation "io.github.rburgst:okhttp-digest:$versions.okhttp_digest"
206+
207+
implementation "org.eclipse.jgit:org.eclipse.jgit:$versions.jgit"
208+
implementation "org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:$versions.jgit"
207209
}
208210

209211
repositories {

app/src/androidTest/java/com/orgzly/android/espresso/QueryFragmentTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,4 +815,12 @@ public void testScheduledTimestamp() {
815815

816816
onNotesInSearch().check(matches(recyclerViewItemCount(1)));
817817
}
818+
819+
@Test
820+
public void testNotScheduled() {
821+
testUtils.setupBook("notebook-1", "* Note A");
822+
ActivityScenario.launch(MainActivity.class);
823+
searchForText("s.no");
824+
onNotesInSearch().check(matches(recyclerViewItemCount(1)));
825+
}
818826
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.orgzly.android.misc
2+
3+
import android.os.Environment
4+
import android.util.Log
5+
import com.orgzly.android.OrgzlyTest
6+
import org.junit.Test
7+
8+
class LogSomethingNotTest : OrgzlyTest() {
9+
@Test
10+
fun testLink() {
11+
Log.i(
12+
"XXX", String.format(
13+
"""
14+
Environment.getExternalStorageDirectory: %s
15+
context.filesDir: %s
16+
context.getExternalFilesDir(null): %s
17+
context.getExternalFilesDir(DOWNLOADS): %s""".trimIndent(),
18+
Environment.getExternalStorageDirectory(),
19+
context.filesDir,
20+
context.getExternalFilesDir(null),
21+
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
22+
)
23+
);
24+
}
25+
}

app/src/androidTest/java/com/orgzly/android/query/QueryTest.kt

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,27 +178,27 @@ class QueryTest(private val param: Parameter) : OrgzlyTest() {
178178
Parameter(
179179
queryString = "s.le.2w",
180180
expectedQueryString = "s.2w",
181-
expectedSqlSelection = "((scheduled_is_active = 1 AND (scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 14+1) + ")))"
181+
expectedSqlSelection = "((scheduled_is_active = 1 AND scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 14+1) + "))"
182182
),
183183
Parameter(
184184
queryString = "s.le.3d",
185185
expectedQueryString = "s.3d",
186-
expectedSqlSelection = "((scheduled_is_active = 1 AND (scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 3+1) + ")))"
186+
expectedSqlSelection = "((scheduled_is_active = 1 AND scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 3+1) + "))"
187187
),
188188
Parameter(
189189
queryString = "s.le.2h",
190190
expectedQueryString = "s.2h",
191-
expectedSqlSelection = "((scheduled_is_active = 1 AND (scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.HOUR_OF_DAY, 2+1) + ")))"
191+
expectedSqlSelection = "((scheduled_is_active = 1 AND scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.HOUR_OF_DAY, 2+1) + "))"
192192
),
193193
Parameter(
194194
queryString = "s.le.+2h",
195195
expectedQueryString = "s.2h",
196-
expectedSqlSelection = "((scheduled_is_active = 1 AND (scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.HOUR_OF_DAY, 2+1) + ")))"
196+
expectedSqlSelection = "((scheduled_is_active = 1 AND scheduled_time_timestamp != 0 AND scheduled_time_timestamp < " + TimeUtils.timeFromNow(Calendar.HOUR_OF_DAY, 2+1) + "))"
197197
),
198198
Parameter(
199199
queryString = "d.tom",
200200
expectedQueryString = "d.tomorrow",
201-
expectedSqlSelection = "((deadline_is_active = 1 AND (deadline_time_timestamp != 0 AND deadline_time_timestamp < " + TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 1+1) + ")))"
201+
expectedSqlSelection = "((deadline_is_active = 1 AND deadline_time_timestamp != 0 AND deadline_time_timestamp < " + TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 1+1) + "))"
202202
),
203203
Parameter(
204204
queryString = "c.eq.today",
@@ -278,12 +278,14 @@ class QueryTest(private val param: Parameter) : OrgzlyTest() {
278278
Parameter(
279279
queryString = "s.ge.3d",
280280
expectedQueryString = "s.ge.3d",
281-
expectedSqlSelection = "((scheduled_is_active = 1 AND (scheduled_time_timestamp != 0 AND ${TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 3)} <= scheduled_time_timestamp)))"
281+
expectedSqlSelection = "((scheduled_is_active = 1 AND scheduled_time_timestamp != 0 AND ${TimeUtils.timeFromNow(Calendar.DAY_OF_MONTH, 3)} <= scheduled_time_timestamp))"
282282
),
283283
Parameter(
284284
queryString = "((i.todo s.no) or i.later) o.state",
285285
expectedQueryString = "(i.todo s.none or i.later) o.state",
286-
expectedQuerySortOrders = listOf(SortOrder.State())
286+
expectedQuerySortOrders = listOf(SortOrder.State()),
287+
expectedSqlSelection = "(((COALESCE(state, '') = ? AND scheduled_time_timestamp IS NULL) OR COALESCE(state, '') = ?))",
288+
expectedSelectionArgs = listOf("TODO", "LATER")
287289
),
288290
Parameter(
289291
queryString = "o.title",
@@ -292,7 +294,12 @@ class QueryTest(private val param: Parameter) : OrgzlyTest() {
292294
expectedSelectionArgs = listOf(),
293295
expectedSqlOrder = "title, lft",
294296
expectedQuerySortOrders = listOf(SortOrder.Title())
295-
)
297+
),
298+
Parameter(
299+
queryString = "s.no",
300+
expectedQueryString = "s.none",
301+
expectedSqlSelection = "(scheduled_time_timestamp IS NULL)"
302+
),
296303
)
297304
}
298305
}
Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.orgzly.android.util
22

3-
import android.os.Environment
43
import android.text.style.URLSpan
54
import com.orgzly.android.ui.views.style.FileLinkSpan
65
import com.orgzly.android.ui.views.style.IdLinkSpan
76
import org.hamcrest.CoreMatchers.equalTo
7+
import org.junit.After
88
import org.junit.Assert.assertThat
99
import org.junit.Before
1010
import org.junit.Test
@@ -18,70 +18,99 @@ class OrgFormatterLinkTest(private val param: Parameter) : OrgFormatterTest() {
1818

1919
data class Span(val start: Int, val end: Int, val klass: Class<*>)
2020

21-
data class Parameter(val input: String, val output: String, val startEnd: List<Span>)
21+
data class Parameter(
22+
val inputString: String,
23+
val outputString: String,
24+
val expectedSpans: List<Span>)
2225

2326
@Before
2427
@Throws(Exception::class)
2528
override fun setUp() {
2629
super.setUp()
2730

28-
File(Environment.getExternalStorageDirectory(), "orgzly-tests").let { dir ->
31+
File(context.cacheDir, "orgzly-tests").let { dir ->
2932
if (!dir.exists() && !dir.mkdirs()) {
3033
throw IOException("Failed to create $dir")
3134
}
3235

3336
MiscUtils.writeStringToFile("Lorem ipsum", File(dir, "document.txt"))
3437

3538
val classLoader = javaClass.classLoader
36-
?: throw IOException("Failed to get a class loader for $javaClass")
39+
?: throw IOException("Failed to get a class loader for $javaClass")
3740

3841
classLoader.getResourceAsStream("assets/images/logo.png").use { stream ->
3942
MiscUtils.writeStreamToFile(stream, File(dir, "logo.png"))
4043
}
4144
}
4245
}
4346

47+
@After
48+
override fun tearDown() {
49+
super.tearDown()
50+
51+
File(context.cacheDir, "orgzly-tests").let { dir ->
52+
dir.deleteRecursively()
53+
}
54+
}
55+
4456
companion object {
4557
@JvmStatic @Parameterized.Parameters(name = "{index}: {0}")
4658
fun data(): Collection<Parameter> {
4759
return listOf(
48-
Parameter("[[orgzly-tests/document.txt]]", "orgzly-tests/document.txt", listOf(Span(0, 25, FileLinkSpan::class.java))),
49-
Parameter("[[./document.txt]]", "./document.txt", listOf(Span(0, 14, FileLinkSpan::class.java))),
50-
Parameter("[[/document.txt]]", "/document.txt", listOf(Span(0, 13, FileLinkSpan::class.java))),
51-
Parameter("[[document.txt]]", "document.txt", listOf(Span(0, 12, FileLinkSpan::class.java))),
60+
Parameter("[[orgzly-tests/document.txt]]", "orgzly-tests/document.txt", listOf(Span(0, 25, FileLinkSpan::class.java))),
61+
Parameter("[[./document.txt]]", "./document.txt", listOf(Span(0, 14, FileLinkSpan::class.java))),
62+
Parameter("[[/document.txt]]", "/document.txt", listOf(Span(0, 13, FileLinkSpan::class.java))),
63+
Parameter("[[document.txt]]", "document.txt", listOf(Span(0, 12, FileLinkSpan::class.java))),
64+
65+
Parameter("file:orgzly-tests/document.txt", "file:orgzly-tests/document.txt", listOf(Span(0, 30, FileLinkSpan::class.java))),
66+
Parameter("[[file:orgzly-tests/document.txt]]", "file:orgzly-tests/document.txt", listOf(Span(0, 30, FileLinkSpan::class.java))),
67+
Parameter("[[file:orgzly-tests/document.txt][Document]]", "Document", listOf(Span(0, 8, FileLinkSpan::class.java))),
5268

53-
Parameter("file:orgzly-tests/document.txt", "file:orgzly-tests/document.txt", listOf(Span(0, 30, FileLinkSpan::class.java))),
54-
Parameter("[[file:orgzly-tests/document.txt]]", "file:orgzly-tests/document.txt", listOf(Span(0, 30, FileLinkSpan::class.java))),
55-
Parameter("[[file:orgzly-tests/document.txt][Document]]", "Document", listOf(Span(0, 8, FileLinkSpan::class.java))),
69+
Parameter("id:45DFE015-255E-4B86-B957-F7FD77364DCA", "id:45DFE015-255E-4B86-B957-F7FD77364DCA", listOf(Span(0, 39, IdLinkSpan::class.java))),
70+
Parameter("[[id:45DFE015-255E-4B86-B957-F7FD77364DCA]]", "id:45DFE015-255E-4B86-B957-F7FD77364DCA", listOf(Span(0, 39, IdLinkSpan::class.java))),
71+
Parameter("id:foo", "id:foo", listOf(Span(0, 6, IdLinkSpan::class.java))),
72+
Parameter("[[id:foo]]", "id:foo", listOf(Span(0, 6, IdLinkSpan::class.java))),
5673

57-
Parameter("id:45DFE015-255E-4B86-B957-F7FD77364DCA", "id:45DFE015-255E-4B86-B957-F7FD77364DCA", listOf(Span(0, 39, IdLinkSpan::class.java))),
58-
Parameter("[[id:45DFE015-255E-4B86-B957-F7FD77364DCA]]", "id:45DFE015-255E-4B86-B957-F7FD77364DCA", listOf(Span(0, 39, IdLinkSpan::class.java))),
59-
Parameter("id:foo", "id:foo", listOf(Span(0, 6, IdLinkSpan::class.java))),
60-
Parameter("[[id:foo]]", "id:foo", listOf(Span(0, 6, IdLinkSpan::class.java))),
74+
Parameter("mailto:[email protected]", "mailto:[email protected]", listOf(Span(0, 14, URLSpan::class.java))),
75+
Parameter("[[mailto:[email protected]]]", "mailto:[email protected]", listOf(Span(0, 14, URLSpan::class.java))),
6176

62-
Parameter("mailto:[email protected]", "mailto:[email protected]", listOf(Span(0, 14, URLSpan::class.java))),
63-
Parameter("[[mailto:[email protected]]]", "mailto:[email protected]", listOf(Span(0, 14, URLSpan::class.java))),
77+
Parameter("[[id:123][[a] b]]", "[a] b", listOf(Span(0, 5, IdLinkSpan::class.java))),
78+
Parameter("[[id:123][[a] b]] [[./456][[c] d]]", "[a] b [c] d", listOf(Span(0, 5, IdLinkSpan::class.java), Span(6, 11, FileLinkSpan::class.java))),
6479

65-
Parameter("[[id:123][[a] b]]", "[a] b", listOf(Span(0, 5, IdLinkSpan::class.java))),
66-
Parameter("[[id:123][[a] b]] [[./456][[c] d]]", "[a] b [c] d", listOf(Span(0, 5, IdLinkSpan::class.java), Span(6, 11, FileLinkSpan::class.java))),
80+
Parameter("[[gnus:msgid][subject]]", "subject", listOf(Span(0, 7, FileLinkSpan::class.java))),
81+
Parameter("[[gnus:\\[Gmail\\]/All Mail#msgid][subject]]", "subject", listOf(Span(0, 7, FileLinkSpan::class.java))),
6782

68-
Parameter("[[gnus:msgid][subject]]", "subject", listOf(Span(0, 7, FileLinkSpan::class.java))),
69-
Parameter("[[gnus:\\[Gmail\\]/All Mail#msgid][subject]]", "subject", listOf(Span(0, 7, FileLinkSpan::class.java)))
83+
Parameter("[[id:a][b]] [[id:1][2]]", "b 2", listOf(Span(0, 1, IdLinkSpan::class.java), Span(2, 3, IdLinkSpan::class.java))),
84+
Parameter("[[id:a][b]][[id:1][2]]", "b2", listOf(Span(0, 1, IdLinkSpan::class.java), Span(1, 2, IdLinkSpan::class.java))),
85+
86+
// Do not linkify
87+
Parameter("strhttp://orgzly.com/", "strhttp://orgzly.com/", emptyList()),
88+
Parameter("Need activity with <action android:name=\"android.intent.action.VIEW\"/>", "Need activity with <action android:name=\"android.intent.action.VIEW\"/>", emptyList())
7089
)
7190
}
7291
}
7392

7493
@Test
7594
fun testLink() {
76-
val spannable = OrgSpannable(param.input)
95+
val parseResult = ParseResult(param.inputString)
96+
97+
val msg = "${param.inputString} -> ${parseResult.outputString}"
98+
99+
assertThat(
100+
"Number of spans found is different then expected: $msg",
101+
parseResult.foundSpans.size,
102+
equalTo(param.expectedSpans.size))
103+
104+
assertThat(parseResult.outputString, equalTo(param.outputString))
77105

78-
assertThat(spannable.string, equalTo(param.output))
79-
assertThat(spannable.spans.size, equalTo(param.startEnd.size))
106+
for (i in parseResult.foundSpans.indices) {
107+
assertThat(parseResult.foundSpans[i].start, equalTo(param.expectedSpans[i].start))
108+
assertThat(parseResult.foundSpans[i].end, equalTo(param.expectedSpans[i].end))
80109

81-
for (i in spannable.spans.indices) {
82-
assertThat(spannable.spans[i].start, equalTo(param.startEnd[i].start))
83-
assertThat(spannable.spans[i].end, equalTo(param.startEnd[i].end))
84-
assertThat(spannable.spans[i].span.javaClass.simpleName, equalTo(param.startEnd[i].klass.simpleName))
110+
assertThat(
111+
"Found span class is different then expected: $msg",
112+
parseResult.foundSpans[i].span.javaClass.simpleName,
113+
equalTo(param.expectedSpans[i].klass.simpleName))
85114
}
86115
}
87116
}

0 commit comments

Comments
 (0)