Skip to content

Commit

Permalink
Merge pull request #8722 from cketti/integrate_TokenAutoComplete
Browse files Browse the repository at this point in the history
Copy the TokenAutoComplete library into our repository
  • Loading branch information
cketti authored Jan 9, 2025
2 parents 04b95c6 + 6576dba commit 09a7edc
Show file tree
Hide file tree
Showing 23 changed files with 2,008 additions and 11 deletions.
1 change: 0 additions & 1 deletion app-k9mail/dependencies/fossReleaseRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
1 change: 0 additions & 1 deletion app-k9mail/dependencies/fullReleaseRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
1 change: 0 additions & 1 deletion app-thunderbird/dependencies/fossBetaRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
1 change: 0 additions & 1 deletion app-thunderbird/dependencies/fossDailyRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
1 change: 0 additions & 1 deletion app-thunderbird/dependencies/fullBetaRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
1 change: 0 additions & 1 deletion app-thunderbird/dependencies/fullDailyRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.cketti.temp:tokenautocomplete:4.0.0-beta01-k9mail02
de.hdodenhof:circleimageview:3.1.0
io.coil-kt.coil3:coil-android:3.0.4
io.coil-kt.coil3:coil-core-android:3.0.4
Expand Down
2 changes: 0 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ safeContentResolver = "1.0.0"
searchPreference = "v2.3.0"
spotlessPlugin = "6.25.0"
timber = "5.0.1"
tokenautocomplete = "4.0.0-beta01-k9mail02"
turbine = "1.2.0"
xmlpull = "1.0"
zxing = "3.5.3"
Expand Down Expand Up @@ -241,7 +240,6 @@ robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectr
safeContentResolver = { module = "de.cketti.safecontentresolver:safe-content-resolver-v21", version.ref = "safeContentResolver" }
searchPreference = { module = "com.github.ByteHamster:SearchPreference", version.ref = "searchPreference" }
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
tokenautocomplete = { module = "de.cketti.temp:tokenautocomplete", version.ref = "tokenautocomplete" }
turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }
xmlpull = { module = "com.github.cketti:xmlpull-extracted-from-android", version.ref = "xmlpull" }
zxing = { module = "com.google.zxing:core", version.ref = "zxing" }
Expand Down
2 changes: 1 addition & 1 deletion legacy/ui/legacy/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ dependencies {
implementation(libs.androidx.localbroadcastmanager)
implementation(libs.androidx.swiperefreshlayout)
implementation(libs.ckchangelog.core)
implementation(libs.tokenautocomplete)
implementation(projects.library.tokenAutoComplete)
implementation(libs.safeContentResolver)
implementation(libs.searchPreference)
implementation(libs.fastadapter)
Expand Down
9 changes: 9 additions & 0 deletions library/TokenAutoComplete/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# TokenAutoComplete

Gmail style `MultiAutoCompleteTextView` for Android.

---

Forked from https://github.com/splitwise/TokenAutoComplete (licensed under the Apache License, Version 2.0).

Based on https://github.com/splitwise/TokenAutoComplete/commit/bb51c96b39d90d43e74b2b8cf709ec58dd633c45
14 changes: 14 additions & 0 deletions library/TokenAutoComplete/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id(ThunderbirdPlugins.Library.android)
}

android {
namespace = "app.k9mail.library.tokenautocomplete"
}

dependencies {
implementation(libs.androidx.annotation)
implementation(libs.androidx.appcompat)

testImplementation(libs.junit)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.tokenautocomplete;

import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;

import java.util.ArrayList;
import java.util.List;

/**
* Tokenizer with configurable array of characters to tokenize on.
*
* Created on 2/3/15.
* @author mgod
*/
public class CharacterTokenizer implements Tokenizer {
private ArrayList<Character> splitChar;
private String tokenTerminator;

@SuppressWarnings("WeakerAccess")
public CharacterTokenizer(List<Character> splitChar, String tokenTerminator){
super();
this.splitChar = new ArrayList<>(splitChar);
this.tokenTerminator = tokenTerminator;
}

@Override
public boolean containsTokenTerminator(CharSequence charSequence) {
for (int i = 0; i < charSequence.length(); ++i) {
if (splitChar.contains(charSequence.charAt(i))) {
return true;
}
}
return false;
}

@Override
@NonNull
public List<Range> findTokenRanges(CharSequence charSequence, int start, int end) {
ArrayList<Range>result = new ArrayList<>();

if (start == end) {
//Can't have a 0 length token
return result;
}

int tokenStart = start;

for (int cursor = start; cursor < end; ++cursor) {
char character = charSequence.charAt(cursor);

//Avoid including leading whitespace, tokenStart will match the cursor as long as we're at the start
if (tokenStart == cursor && Character.isWhitespace(character)) {
tokenStart = cursor + 1;
}

//Either this is a split character, or we contain some content and are at the end of input
if (splitChar.contains(character) || cursor == end - 1) {
boolean hasTokenContent =
//There is token content befor the current character
cursor > tokenStart ||
//If the current single character is valid token content, not a split char or whitespace
(cursor == tokenStart && !splitChar.contains(character));
if (hasTokenContent) {
//There is some token content
//Add one to range end as the end of the ranges is not inclusive
result.add(new Range(tokenStart, cursor + 1));
}

tokenStart = cursor + 1;
}
}

return result;
}

@Override
@NonNull
public CharSequence wrapTokenValue(CharSequence text) {
CharSequence wrappedText = text + tokenTerminator;

if (text instanceof Spanned) {
SpannableString sp = new SpannableString(wrappedText);
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return wrappedText;
}
}

public static final Parcelable.Creator<CharacterTokenizer> CREATOR = new Parcelable.Creator<CharacterTokenizer>() {
@SuppressWarnings("unchecked")
public CharacterTokenizer createFromParcel(Parcel in) {
return new CharacterTokenizer(in);
}

public CharacterTokenizer[] newArray(int size) {
return new CharacterTokenizer[size];
}
};

@Override
public int describeContents() {
return 0;
}

@SuppressWarnings({"WeakerAccess", "unchecked"})
CharacterTokenizer(Parcel in) {
this(in.readArrayList(Character.class.getClassLoader()), in.readString());
}

@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeList(splitChar);
parcel.writeString(tokenTerminator);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.tokenautocomplete;

import android.text.Layout;
import android.text.TextPaint;
import android.text.style.CharacterStyle;

import java.util.Locale;

/**
* Span that displays +[x]
*
* Created on 2/3/15.
* @author mgod
*/

class CountSpan extends CharacterStyle {
private String countText;

CountSpan() {
super();
countText = "";
}

@Override
public void updateDrawState(TextPaint textPaint) {
//Do nothing, we are using this span as a location marker
}

void setCount(int c) {
if (c > 0) {
countText = String.format(Locale.getDefault(), " +%d", c);
} else {
countText = "";
}
}

String getCountText() {
return countText;
}

float getCountTextWidthForPaint(TextPaint paint) {
return Layout.getDesiredWidth(countText, 0, countText.length(), paint);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.tokenautocomplete;

import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;

import androidx.annotation.NonNull;

/**
* Invisible MetricAffectingSpan that will trigger a redraw when it is being added to or removed from an Editable.
*
* @see TokenCompleteTextView#redrawTokens()
*/
class DummySpan extends MetricAffectingSpan {
static final DummySpan INSTANCE = new DummySpan();

private DummySpan() {}

@Override
public void updateMeasureState(@NonNull TextPaint textPaint) {}

@Override
public void updateDrawState(TextPaint tp) {}
}
Loading

0 comments on commit 09a7edc

Please sign in to comment.