improving auto complete
This commit is contained in:
parent
7893268b2d
commit
79eb0981a1
|
@ -286,6 +286,16 @@ public interface TwidereDataStore {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Suggestions extends BaseColumns {
|
||||||
|
String TYPE = "type";
|
||||||
|
String VALUE1 = "value1";
|
||||||
|
String VALUE2 = "value2";
|
||||||
|
|
||||||
|
interface Compose extends Suggestions {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface CachedValues extends BaseColumns {
|
interface CachedValues extends BaseColumns {
|
||||||
|
|
||||||
String NAME = "name";
|
String NAME = "name";
|
||||||
|
|
|
@ -30,6 +30,7 @@ import android.text.TextUtils;
|
||||||
|
|
||||||
import org.mariotaku.twidere.Constants;
|
import org.mariotaku.twidere.Constants;
|
||||||
import org.mariotaku.twidere.app.TwidereApplication;
|
import org.mariotaku.twidere.app.TwidereApplication;
|
||||||
|
import org.mariotaku.twidere.util.JsonSerializer;
|
||||||
import org.mariotaku.twidere.util.Utils;
|
import org.mariotaku.twidere.util.Utils;
|
||||||
import org.mariotaku.twidere.util.dagger.ApplicationModule;
|
import org.mariotaku.twidere.util.dagger.ApplicationModule;
|
||||||
|
|
||||||
|
@ -65,6 +66,7 @@ public class HotMobiLogger {
|
||||||
public static final String LOGTAG = "HotMobiLogger";
|
public static final String LOGTAG = "HotMobiLogger";
|
||||||
public static final long UPLOAD_INTERVAL_MILLIS = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS);
|
public static final long UPLOAD_INTERVAL_MILLIS = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS);
|
||||||
public static final String LAST_UPLOAD_TIME = "last_upload_time";
|
public static final String LAST_UPLOAD_TIME = "last_upload_time";
|
||||||
|
public static final String FALLBACK_CACHED_LOCATION = "fallback_cached_location";
|
||||||
final static SimpleDateFormat DATE_FORMAT;
|
final static SimpleDateFormat DATE_FORMAT;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -123,8 +125,18 @@ public class HotMobiLogger {
|
||||||
|
|
||||||
public static LatLng getCachedLatLng(Context context) {
|
public static LatLng getCachedLatLng(Context context) {
|
||||||
final Location location = Utils.getCachedLocation(context);
|
final Location location = Utils.getCachedLocation(context);
|
||||||
if (location == null) return null;
|
if (location == null) {
|
||||||
return new LatLng(location.getLatitude(), location.getLongitude());
|
return getFallbackCachedLocation(context);
|
||||||
|
}
|
||||||
|
final LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
|
||||||
|
final SharedPreferences prefs = context.getSharedPreferences("spice_data_profiling", Context.MODE_PRIVATE);
|
||||||
|
prefs.edit().putString(FALLBACK_CACHED_LOCATION, JsonSerializer.serialize(latLng, LatLng.class)).apply();
|
||||||
|
return latLng;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LatLng getFallbackCachedLocation(Context context) {
|
||||||
|
final SharedPreferences prefs = context.getSharedPreferences("spice_data_profiling", Context.MODE_PRIVATE);
|
||||||
|
return JsonSerializer.parse(prefs.getString(FALLBACK_CACHED_LOCATION, null), LatLng.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getLogFile(Context context, long accountId, String type) {
|
public static File getLogFile(Context context, long accountId, String type) {
|
||||||
|
|
|
@ -27,61 +27,52 @@ import android.widget.MultiAutoCompleteTextView;
|
||||||
/**
|
/**
|
||||||
* Created by mariotaku on 15/5/14.
|
* Created by mariotaku on 15/5/14.
|
||||||
*/
|
*/
|
||||||
public class ScreenNameTokenizer implements MultiAutoCompleteTextView.Tokenizer {
|
public class StatusTextTokenizer implements MultiAutoCompleteTextView.Tokenizer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int findTokenStart(final CharSequence text, final int cursor) {
|
public int findTokenStart(CharSequence text, int cursor) {
|
||||||
int start = cursor;
|
|
||||||
|
|
||||||
while (start > 0 && text.charAt(start - 1) != ' ') {
|
|
||||||
start--;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (start < cursor && text.charAt(start) == ' ') {
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start < cursor && isToken(text.charAt(start))) {
|
|
||||||
start++;
|
|
||||||
} else {
|
|
||||||
start = cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int findTokenEnd(final CharSequence text, final int cursor) {
|
|
||||||
int i = cursor;
|
int i = cursor;
|
||||||
final int len = text.length();
|
// Search backward to find start symbol
|
||||||
|
while (i > 0 && !isStartSymbol(text.charAt(i - 1))) {
|
||||||
while (i < len) {
|
|
||||||
if (text.charAt(i) == ' ')
|
|
||||||
return i;
|
|
||||||
else {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence terminateToken(final CharSequence text) {
|
|
||||||
int i = text.length();
|
|
||||||
|
|
||||||
while (i > 0 && isToken(text.charAt(i - 1))) {
|
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
return i;
|
||||||
if (i > 0 && text.charAt(i - 1) == ' ' || !(text instanceof Spanned)) return text;
|
|
||||||
final SpannableString sp = new SpannableString(text);
|
|
||||||
TextUtils.copySpansFrom((Spanned) text, 0, text.length(), Object.class, sp, 0);
|
|
||||||
return sp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isToken(final char character) {
|
@Override
|
||||||
switch (character) {
|
public int findTokenEnd(CharSequence text, int cursor) {
|
||||||
|
int i = cursor;
|
||||||
|
int len = text.length();
|
||||||
|
// Search backward to find start symbol
|
||||||
|
while (i > 0 && !isStartSymbol(text.charAt(i - 1))) {
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
// Search forward to find space
|
||||||
|
while (i < len && !isSpace(text.charAt(i))) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence terminateToken(CharSequence text) {
|
||||||
|
// We already have spaces at the end, so just ignore
|
||||||
|
if (text instanceof Spanned) {
|
||||||
|
SpannableString sp = new SpannableString(text + " ");
|
||||||
|
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
|
||||||
|
Object.class, sp, 0);
|
||||||
|
return sp;
|
||||||
|
} else {
|
||||||
|
return text + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSpace(final char c) {
|
||||||
|
return Character.isSpaceChar(c) || Character.isWhitespace(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isStartSymbol(final char c) {
|
||||||
|
switch (c) {
|
||||||
case '\uff20':
|
case '\uff20':
|
||||||
case '@':
|
case '@':
|
||||||
case '\uff03':
|
case '\uff03':
|
|
@ -21,15 +21,12 @@ package org.mariotaku.twidere.view;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.v7.widget.AppCompatMultiAutoCompleteTextView;
|
import android.support.v7.widget.AppCompatMultiAutoCompleteTextView;
|
||||||
import android.text.InputType;
|
|
||||||
import android.text.method.ArrowKeyMovementMethod;
|
import android.text.method.ArrowKeyMovementMethod;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import com.rengwuxian.materialedittext.MaterialMultiAutoCompleteTextView;
|
|
||||||
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||||
import org.mariotaku.twidere.util.widget.ScreenNameTokenizer;
|
import org.mariotaku.twidere.util.widget.StatusTextTokenizer;
|
||||||
|
|
||||||
public class ComposeEditText extends AppCompatMultiAutoCompleteTextView {
|
public class ComposeEditText extends AppCompatMultiAutoCompleteTextView {
|
||||||
|
|
||||||
|
@ -46,15 +43,8 @@ public class ComposeEditText extends AppCompatMultiAutoCompleteTextView {
|
||||||
|
|
||||||
public ComposeEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
public ComposeEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
setTokenizer(new ScreenNameTokenizer());
|
setTokenizer(new StatusTextTokenizer());
|
||||||
setMovementMethod(ArrowKeyMovementMethod.getInstance());
|
setMovementMethod(ArrowKeyMovementMethod.getInstance());
|
||||||
setupComposeInputType();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupComposeInputType() {
|
|
||||||
int rawInputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
|
|
||||||
rawInputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
|
||||||
setRawInputType(rawInputType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -85,11 +75,4 @@ public class ComposeEditText extends AppCompatMultiAutoCompleteTextView {
|
||||||
if (mAdapter == null) return;
|
if (mAdapter == null) return;
|
||||||
mAdapter.setAccountId(mAccountId);
|
mAdapter.setAccountId(mAccountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void replaceText(final CharSequence text) {
|
|
||||||
super.replaceText(text);
|
|
||||||
append(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import android.util.AttributeSet;
|
||||||
|
|
||||||
import org.mariotaku.twidere.R;
|
import org.mariotaku.twidere.R;
|
||||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||||
import org.mariotaku.twidere.util.widget.ScreenNameTokenizer;
|
import org.mariotaku.twidere.util.widget.StatusTextTokenizer;
|
||||||
import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView;
|
import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView;
|
||||||
|
|
||||||
public class ComposeMaterialEditText extends AppCompatMultiAutoCompleteTextView implements IThemeBackgroundTintView {
|
public class ComposeMaterialEditText extends AppCompatMultiAutoCompleteTextView implements IThemeBackgroundTintView {
|
||||||
|
@ -47,7 +47,7 @@ public class ComposeMaterialEditText extends AppCompatMultiAutoCompleteTextView
|
||||||
|
|
||||||
public ComposeMaterialEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
public ComposeMaterialEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
setTokenizer(new ScreenNameTokenizer());
|
setTokenizer(new StatusTextTokenizer());
|
||||||
setMovementMethod(ArrowKeyMovementMethod.getInstance());
|
setMovementMethod(ArrowKeyMovementMethod.getInstance());
|
||||||
setupComposeInputType();
|
setupComposeInputType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
android:completionThreshold="1"
|
android:completionThreshold="1"
|
||||||
android:gravity="top"
|
android:gravity="top"
|
||||||
android:hint="@string/status_hint"
|
android:hint="@string/status_hint"
|
||||||
|
android:inputType="text|textLongMessage|textAutoComplete|textMultiLine"
|
||||||
android:minLines="6"
|
android:minLines="6"
|
||||||
android:padding="@dimen/element_spacing_normal"
|
android:padding="@dimen/element_spacing_normal"
|
||||||
android:scrollbars="vertical" />
|
android:scrollbars="vertical" />
|
||||||
|
|
|
@ -543,7 +543,7 @@
|
||||||
<string name="theme_background_transparent">Transparent</string>
|
<string name="theme_background_transparent">Transparent</string>
|
||||||
<string name="theme_dark_actionbar">Dark ActionBar</string>
|
<string name="theme_dark_actionbar">Dark ActionBar</string>
|
||||||
<string name="wizard_hint_compose_select_account">Click profile image to select account when writing a tweet.</string>
|
<string name="wizard_hint_compose_select_account">Click profile image to select account when writing a tweet.</string>
|
||||||
<string name="wizard_hint_quote_format">Set your favorite quote format in "Settings" - "Content & Storage"</string>
|
<string name="wizard_hint_quote_format">Set your favorite quote format in "Settings" - "Compose"</string>
|
||||||
<string name="wizard_hint_filters">You can hide unwanted tweets from timeline and notification by using "Filters".</string>
|
<string name="wizard_hint_filters">You can hide unwanted tweets from timeline and notification by using "Filters".</string>
|
||||||
<string name="view_replies">View Replies</string>
|
<string name="view_replies">View Replies</string>
|
||||||
<string name="compact_cards">Compact cards</string>
|
<string name="compact_cards">Compact cards</string>
|
||||||
|
|
Loading…
Reference in New Issue