Merge branch '843-landscape-keyboard' into 'master'

Raise target API version to 28 and fix soft keyboard issues

Closes #1505

See merge request briar/briar!1043
This commit is contained in:
Torsten Grote
2019-10-21 12:38:38 +00:00
33 changed files with 146 additions and 369 deletions

View File

@@ -10,7 +10,7 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 26
targetSdkVersion 28
versionCode 10109
versionName "1.1.9"
consumerProguardFiles 'proguard-rules.txt'

View File

@@ -21,7 +21,7 @@ android {
defaultConfig {
minSdkVersion 16
targetSdkVersion 26
targetSdkVersion 28
versionCode 10109
versionName "1.1.9"
applicationId "org.briarproject.briar.android"
@@ -117,7 +117,7 @@ dependencies {
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.google.zxing:core:3.3.3'
implementation 'uk.co.samuelwall:material-tap-target-prompt:2.14.0'
implementation 'com.vanniktech:emoji-google:0.5.1'
implementation 'com.vanniktech:emoji-google:0.6.0' // later versions already use androidx
implementation 'com.github.kobakei:MaterialFabSpeedDial:1.2.1' // later versions already use androidx
def glideVersion = '4.9.0'
implementation("com.github.bumptech.glide:glide:$glideVersion") {

View File

@@ -73,7 +73,7 @@
android:label="@string/crash_report_title"
android:launchMode="singleInstance"
android:theme="@style/BriarTheme.NoActionBar"
android:windowSoftInputMode="stateHidden">
android:windowSoftInputMode="adjustResize|stateHidden">
</activity>
<activity
@@ -89,7 +89,7 @@
<activity
android:name="org.briarproject.briar.android.account.SetupActivity"
android:label="@string/setup_title"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
</activity>
<activity
@@ -126,7 +126,7 @@
android:label="@string/app_name"
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
android:theme="@style/BriarTheme.NoActionBar"
android:windowSoftInputMode="stateHidden|adjustResize">
android:windowSoftInputMode="adjustResize|stateUnchanged">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
@@ -145,7 +145,7 @@
android:name="org.briarproject.briar.android.privategroup.creation.CreateGroupActivity"
android:label="@string/groups_create_group_title"
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
@@ -174,8 +174,7 @@
<activity
android:name="org.briarproject.briar.android.privategroup.memberlist.GroupMemberListActivity"
android:label="@string/groups_member_list"
android:parentActivityName="org.briarproject.briar.android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
android:parentActivityName="org.briarproject.briar.android.privategroup.conversation.GroupActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity"/>
@@ -184,8 +183,7 @@
<activity
android:name="org.briarproject.briar.android.privategroup.reveal.RevealContactsActivity"
android:label="@string/groups_reveal_contacts"
android:parentActivityName="org.briarproject.briar.android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
android:parentActivityName="org.briarproject.briar.android.privategroup.conversation.GroupActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.privategroup.conversation.GroupActivity"/>
@@ -223,7 +221,7 @@
android:name="org.briarproject.briar.android.forum.CreateForumActivity"
android:label="@string/create_forum_title"
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
@@ -292,7 +290,7 @@
android:name="org.briarproject.briar.android.blog.WriteBlogPostActivity"
android:label="@string/blogs_write_blog_post"
android:parentActivityName="org.briarproject.briar.android.blog.BlogActivity"
android:windowSoftInputMode="stateVisible|adjustResize">
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.blog.BlogActivity"/>
@@ -302,7 +300,7 @@
android:name="org.briarproject.briar.android.blog.ReblogActivity"
android:label="@string/blogs_reblog_button"
android:parentActivityName="org.briarproject.briar.android.blog.BlogActivity"
android:windowSoftInputMode="stateHidden">
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.blog.BlogActivity"/>
@@ -312,7 +310,7 @@
android:name="org.briarproject.briar.android.blog.RssFeedImportActivity"
android:label="@string/blogs_rss_feeds_import"
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
android:windowSoftInputMode="stateVisible|adjustResize">
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.navdrawer.NavDrawerActivity"/>
@@ -341,7 +339,7 @@
android:name="org.briarproject.briar.android.introduction.IntroductionActivity"
android:label="@string/introduction_activity_title"
android:parentActivityName="org.briarproject.briar.android.conversation.ConversationActivity"
android:windowSoftInputMode="stateHidden|adjustResize">
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.conversation.ConversationActivity"/>
@@ -369,7 +367,8 @@
<activity
android:name="org.briarproject.briar.android.login.ChangePasswordActivity"
android:label="@string/change_password"
android:parentActivityName="org.briarproject.briar.android.settings.SettingsActivity">
android:parentActivityName="org.briarproject.briar.android.settings.SettingsActivity"
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.settings.SettingsActivity"/>
@@ -424,7 +423,7 @@
android:name=".android.contact.add.remote.AddContactActivity"
android:label="@string/add_contact_remotely_title_case"
android:theme="@style/BriarTheme"
android:windowSoftInputMode="stateHidden|adjustResize"/>
android:windowSoftInputMode="adjustResize|stateHidden"/>
<activity
android:name=".android.contact.add.remote.PendingContactListActivity"

View File

@@ -16,13 +16,10 @@ import org.briarproject.briar.android.activity.ActivityComponent;
import javax.annotation.Nullable;
import static android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
import static android.view.inputmethod.EditorInfo.IME_ACTION_NONE;
import static java.util.Objects.requireNonNull;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
import static org.briarproject.briar.android.util.UiUtils.setError;
import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -65,12 +62,6 @@ public class AuthorNameFragment extends SetupFragment {
return TAG;
}
@Override
public void onResume() {
super.onResume();
showSoftKeyboard(authorNameInput);
}
@Override
protected String getHelpText() {
return getString(R.string.setup_name_explanation);
@@ -82,8 +73,6 @@ public class AuthorNameFragment extends SetupFragment {
boolean error = authorNameLength > MAX_AUTHOR_NAME_LENGTH;
setError(authorNameWrapper, getString(R.string.name_too_long), error);
boolean enabled = authorNameLength > 0 && !error;
authorNameInput
.setImeOptions(enabled ? IME_ACTION_NEXT : IME_ACTION_NONE);
authorNameInput.setOnEditorActionListener(enabled ? this : null);
nextButton.setEnabled(enabled);
}

View File

@@ -61,7 +61,6 @@ public class SetPasswordFragment extends SetupFragment {
strengthMeter = v.findViewById(R.id.strength_meter);
passwordEntryWrapper = v.findViewById(R.id.password_entry_wrapper);
passwordEntry = v.findViewById(R.id.password_entry);
passwordEntry.requestFocus();
passwordConfirmationWrapper =
v.findViewById(R.id.password_confirm_wrapper);
passwordConfirmation = v.findViewById(R.id.password_confirm);

View File

@@ -2,7 +2,6 @@ package org.briarproject.briar.android.activity;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.LayoutRes;
import android.support.annotation.UiThread;
import android.support.v4.app.Fragment;
@@ -12,7 +11,6 @@ import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.InputMethodManager;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
@@ -44,10 +42,10 @@ import javax.inject.Inject;
import static android.arch.lifecycle.Lifecycle.State.STARTED;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.briar.android.TestingConstants.PREVENT_SCREENSHOTS;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
/**
* Warning: Some activities don't extend {@link BaseActivity}.
@@ -217,17 +215,6 @@ public abstract class BaseActivity extends AppCompatActivity
});
}
public void showSoftKeyboard(View view) {
Object o = getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).showSoftInput(view, SHOW_IMPLICIT);
}
public void hideSoftKeyboard(View view) {
IBinder token = view.getWindowToken();
Object o = getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
}
@UiThread
public void handleDbException(DbException e) {
supportFinishAfterTransition();

View File

@@ -32,6 +32,7 @@ import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
public class RssFeedImportActivity extends BriarActivity {
@@ -77,7 +78,6 @@ public class RssFeedImportActivity extends BriarActivity {
if (actionId == IME_ACTION_DONE && importButton.isEnabled() &&
importButton.getVisibility() == VISIBLE) {
publish();
hideSoftKeyboard(urlInput);
return true;
}
return false;
@@ -123,6 +123,7 @@ public class RssFeedImportActivity extends BriarActivity {
// hide import button, show progress bar
importButton.setVisibility(GONE);
progressBar.setVisibility(VISIBLE);
hideSoftKeyboard(urlInput);
String url = validateAndNormaliseUrl(urlInput.getText().toString());
if (url == null) throw new AssertionError();

View File

@@ -3,11 +3,8 @@ package org.briarproject.briar.android.blog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.db.DbException;
@@ -44,7 +41,7 @@ import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_POST_TEXT_L
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class WriteBlogPostActivity extends BriarActivity
implements OnEditorActionListener, SendListener {
implements SendListener {
private static final Logger LOG =
Logger.getLogger(WriteBlogPostActivity.class.getName());
@@ -113,12 +110,6 @@ public class WriteBlogPostActivity extends BriarActivity
component.inject(this);
}
@Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent e) {
input.requestFocus();
return true;
}
@Override
public void onSendClick(@Nullable String text,
List<AttachmentHeader> headers) {

View File

@@ -21,9 +21,12 @@ import org.briarproject.briar.android.activity.BaseActivity;
import javax.inject.Inject;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
import static java.util.Objects.requireNonNull;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
@@ -76,12 +79,13 @@ public class AliasDialogFragment extends AppCompatDialogFragment {
setButton.setOnClickListener(v1 -> onSetButtonClicked());
Button cancelButton = v.findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(v1 -> getDialog().cancel());
cancelButton.setOnClickListener(v1 -> onCancelButtonClicked());
return v;
}
private void onSetButtonClicked() {
hideSoftKeyboard(aliasEditText);
String alias = aliasEditText.getText().toString().trim();
if (toUtf8(alias).length > MAX_AUTHOR_NAME_LENGTH) {
aliasEditLayout.setError(getString(R.string.name_too_long));
@@ -91,4 +95,17 @@ public class AliasDialogFragment extends AppCompatDialogFragment {
}
}
private void onCancelButtonClicked() {
hideSoftKeyboard(aliasEditText);
getDialog().cancel();
}
@Override
public void onStart() {
super.onStart();
requireNonNull(getDialog().getWindow())
.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
showSoftKeyboard(aliasEditText);
}
}

View File

@@ -276,7 +276,7 @@ public class ConversationActivity extends BriarActivity
textInputView.setSendController(sendController);
textInputView.setMaxTextLength(MAX_PRIVATE_MESSAGE_TEXT_LENGTH);
textInputView.setReady(false);
textInputView.addOnKeyboardShownListener(this::scrollToBottom);
textInputView.setOnKeyboardShownListener(this::scrollToBottom);
}
private void scrollToBottom() {

View File

@@ -34,6 +34,8 @@ import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.util.UiUtils.enterPressed;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
@MethodsNotNullByDefault
@@ -91,12 +93,6 @@ public class CreateForumActivity extends BriarActivity {
progress = findViewById(R.id.createForumProgressBar);
}
@Override
public void onStart() {
super.onStart();
showSoftKeyboard(nameEntry);
}
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);

View File

@@ -43,6 +43,7 @@ import static java.util.Objects.requireNonNull;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.util.UiUtils.getContactDisplayName;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_TEXT_LENGTH;
@MethodsNotNullByDefault
@@ -184,7 +185,7 @@ public class IntroductionMessageFragment extends BaseFragment
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
introductionActivity.hideSoftKeyboard(ui.message);
hideSoftKeyboard(ui.message);
introductionActivity.onBackPressed();
return true;
default:
@@ -201,7 +202,7 @@ public class IntroductionMessageFragment extends BaseFragment
makeIntroduction(contact1, contact2, text);
// don't wait for the introduction to be made before finishing activity
introductionActivity.hideSoftKeyboard(ui.message);
hideSoftKeyboard(ui.message);
introductionActivity.setResult(RESULT_OK);
introductionActivity.supportFinishAfterTransition();
}

View File

@@ -26,6 +26,8 @@ import javax.inject.Inject;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.android.util.UiUtils.showSoftKeyboard;
public class ChangePasswordActivity extends BriarActivity
implements OnClickListener, OnEditorActionListener {

View File

@@ -83,12 +83,6 @@ public class PasswordFragment extends BaseFragment implements TextWatcher {
return v;
}
@Override
public void onResume() {
super.onResume();
showSoftKeyboard(password);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

View File

@@ -24,6 +24,7 @@ import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
import static org.briarproject.briar.android.util.UiUtils.enterPressed;
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
@MethodsNotNullByDefault
@@ -91,12 +92,6 @@ public class CreateGroupFragment extends BaseFragment {
return v;
}
@Override
public void onStart() {
super.onStart();
listener.showSoftKeyboard(nameEntry);
}
@Override
public String getUniqueTag() {
return TAG;
@@ -120,7 +115,7 @@ public class CreateGroupFragment extends BaseFragment {
private void createGroup() {
if (!validateName()) return;
listener.hideSoftKeyboard(nameEntry);
hideSoftKeyboard(nameEntry);
createGroupButton.setVisibility(GONE);
progress.setVisibility(VISIBLE);
listener.onGroupNameChosen(nameEntry.getText().toString());

View File

@@ -1,15 +1,8 @@
package org.briarproject.briar.android.privategroup.creation;
import android.view.View;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
interface CreateGroupListener extends BaseFragmentListener {
void onGroupNameChosen(String name);
void showSoftKeyboard(View view);
void hideSoftKeyboard(View view);
}

View File

@@ -64,12 +64,6 @@ public abstract class BaseMessageFragment extends BaseFragment
@StringRes
protected abstract int getHintText();
@Override
public void onStart() {
super.onStart();
message.showSoftKeyboard();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {

View File

@@ -27,7 +27,6 @@ import org.briarproject.briar.android.threaded.ThreadListController.ThreadListDa
import org.briarproject.briar.android.threaded.ThreadListController.ThreadListListener;
import org.briarproject.briar.android.util.BriarSnackbarBuilder;
import org.briarproject.briar.android.view.BriarRecyclerView;
import org.briarproject.briar.android.view.KeyboardAwareLinearLayout;
import org.briarproject.briar.android.view.TextInputView;
import org.briarproject.briar.android.view.TextSendController;
import org.briarproject.briar.android.view.TextSendController.SendListener;
@@ -284,14 +283,10 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
scrollToItemAtTop(item);
} else {
// wait with scrolling until keyboard opened
textInput.addOnKeyboardShownListener(
new KeyboardAwareLinearLayout.OnKeyboardShownListener() {
@Override
public void onKeyboardShown() {
scrollToItemAtTop(item);
textInput.removeOnKeyboardShownListener(this);
}
});
textInput.setOnKeyboardShownListener(() -> {
scrollToItemAtTop(item);
textInput.setOnKeyboardShownListener(null);
});
}
}
@@ -332,7 +327,6 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
private void updateTextInput() {
if (replyId != null) {
textInput.setHint(R.string.forum_message_reply_hint);
textInput.requestFocus();
textInput.showSoftKeyboard();
} else {
textInput.setHint(R.string.forum_new_message_hint);

View File

@@ -92,9 +92,11 @@ public class UiUtils {
public static final float GREY_OUT = 0.5f;
public static void showSoftKeyboard(View view) {
InputMethodManager imm = requireNonNull(
getSystemService(view.getContext(), InputMethodManager.class));
imm.showSoftInput(view, SHOW_IMPLICIT);
if (view.requestFocus()) {
InputMethodManager imm = requireNonNull(getSystemService(
view.getContext(), InputMethodManager.class));
imm.showSoftInput(view, SHOW_IMPLICIT);
}
}
public static void hideSoftKeyboard(View view) {

View File

@@ -13,8 +13,8 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.vanniktech.emoji.EmojiEditText;
import com.vanniktech.emoji.EmojiPopup;
import com.vanniktech.emoji.RecentEmoji;
@@ -31,8 +31,9 @@ import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT;
import static java.lang.Character.isWhitespace;
import static java.util.Objects.requireNonNull;
import static org.briarproject.bramble.util.StringUtils.utf8IsTooLong;
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
public class EmojiTextInputView extends KeyboardAwareLinearLayout implements
public class EmojiTextInputView extends LinearLayout implements
TextWatcher {
@Inject
@@ -41,12 +42,16 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements
private final AppCompatImageButton emojiToggle;
private final EmojiPopup emojiPopup;
private final EditText editText;
private final InputMethodManager imm;
@Nullable
private TextInputListener listener;
@Nullable
private OnKeyboardShownListener keyboardShownListener;
private int maxLength = Integer.MAX_VALUE;
private boolean emptyTextAllowed = false;
private boolean isEmpty = true;
private boolean keyboardOpen = false;
public EmojiTextInputView(Context context) {
this(context, null);
@@ -104,17 +109,26 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements
// stuff we can't do in edit mode goes below
if (isInEditMode()) {
emojiPopup = null;
imm = null;
return;
}
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
imm = (InputMethodManager) requireNonNull(o);
BriarApplication app =
(BriarApplication) context.getApplicationContext();
app.getApplicationComponent().inject(this);
emojiPopup = EmojiPopup.Builder
.fromRootView(this)
.fromRootView(getRootView())
.setRecentEmoji(recentEmoji)
.setOnEmojiPopupShownListener(this::showKeyboardIcon)
.setOnEmojiPopupDismissListener(this::showEmojiIcon)
.build((EmojiEditText) editText);
.setKeyboardAnimationStyle(R.style.emoji_fade_animation_style)
.setOnSoftKeyboardOpenListener(this::onKeyboardOpened)
.setOnSoftKeyboardCloseListener(this::onKeyboardClosed)
.setIconColor(resolveColorAttribute(getContext(),
R.attr.colorControlNormal))
.build(editText);
emojiToggle.setOnClickListener(v -> emojiPopup.toggle());
}
@@ -231,6 +245,10 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements
editText.setHint(hint);
}
boolean isKeyboardOpen() {
return keyboardOpen || imm.isFullscreenMode();
}
private void showEmojiIcon() {
emojiToggle.setImageResource(R.drawable.ic_emoji_toggle);
}
@@ -240,23 +258,43 @@ public class EmojiTextInputView extends KeyboardAwareLinearLayout implements
}
void showSoftKeyboard() {
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
InputMethodManager imm = (InputMethodManager) requireNonNull(o);
imm.showSoftInput(editText, SHOW_IMPLICIT);
if (editText.requestFocus()) imm.showSoftInput(editText, SHOW_IMPLICIT);
}
void hideSoftKeyboard() {
if (emojiPopup.isShowing()) emojiPopup.dismiss();
IBinder token = editText.getWindowToken();
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
InputMethodManager imm = (InputMethodManager) requireNonNull(o);
imm.hideSoftInputFromWindow(token, 0);
}
private void onKeyboardOpened(
@SuppressWarnings("unused") int keyboardHeight) {
keyboardOpen = true;
if (keyboardShownListener != null)
keyboardShownListener.onKeyboardShown();
}
private void onKeyboardClosed() {
if (imm.isFullscreenMode()) {
onKeyboardOpened(0);
return;
}
keyboardOpen = false;
}
void setOnKeyboardShownListener(
@Nullable OnKeyboardShownListener listener) {
keyboardShownListener = listener;
}
interface TextInputListener {
void onTextIsEmptyChanged(boolean isEmpty);
void onSendEvent();
}
public interface OnKeyboardShownListener {
void onKeyboardShown();
}
}

View File

@@ -1,225 +0,0 @@
/*
Taken from Signal, licences under GPLv3
*/
package org.briarproject.briar.android.view;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.annotation.UiThread;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import org.briarproject.briar.R;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static android.content.Context.WINDOW_SERVICE;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static java.util.Objects.requireNonNull;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
/**
* RelativeLayout that, when a view container, will report back when it thinks
* a soft keyboard has been opened and what its height would be.
*/
@UiThread
public class KeyboardAwareLinearLayout extends LinearLayout {
private static final Logger LOG =
Logger.getLogger(KeyboardAwareLinearLayout.class.getName());
private final Rect rect = new Rect();
private final Set<OnKeyboardShownListener> shownListeners = new HashSet<>();
private final int minKeyboardSize;
private final int minCustomKeyboardSize;
private final int defaultCustomKeyboardSize;
private final int minCustomKeyboardTopMargin;
private final int statusBarHeight;
private int viewInset;
private boolean keyboardOpen = false;
private int rotation = -1;
public KeyboardAwareLinearLayout(Context context) {
this(context, null);
}
public KeyboardAwareLinearLayout(Context context,
@Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public KeyboardAwareLinearLayout(Context context,
@Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
rotation = getDeviceRotation();
int statusBarRes = getResources()
.getIdentifier("status_bar_height", "dimen", "android");
minKeyboardSize =
getResources().getDimensionPixelSize(R.dimen.min_keyboard_size);
minCustomKeyboardSize = getResources()
.getDimensionPixelSize(R.dimen.min_custom_keyboard_size);
defaultCustomKeyboardSize = getResources()
.getDimensionPixelSize(R.dimen.default_custom_keyboard_size);
minCustomKeyboardTopMargin = getResources()
.getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin);
statusBarHeight = statusBarRes > 0 ?
getResources().getDimensionPixelSize(statusBarRes) : 0;
viewInset = getViewInset();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
updateRotation();
updateKeyboardState();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void updateRotation() {
int oldRotation = rotation;
rotation = getDeviceRotation();
if (oldRotation != rotation) {
LOG.info("Rotation changed");
onKeyboardClose();
}
}
private void updateKeyboardState() {
if (isLandscape()) {
if (keyboardOpen) onKeyboardClose();
return;
}
if (viewInset == 0 && Build.VERSION.SDK_INT >= 21)
viewInset = getViewInset();
int availableHeight =
getRootView().getHeight() - statusBarHeight - viewInset;
getWindowVisibleDisplayFrame(rect);
int keyboardHeight = availableHeight - (rect.bottom - rect.top);
if (keyboardHeight > minKeyboardSize) {
if (getKeyboardHeight() != keyboardHeight)
setKeyboardPortraitHeight(keyboardHeight);
if (!keyboardOpen) onKeyboardOpen(keyboardHeight);
} else if (keyboardOpen) {
onKeyboardClose();
}
}
@TargetApi(21)
private int getViewInset() {
try {
Field attachInfoField = View.class.getDeclaredField("mAttachInfo");
attachInfoField.setAccessible(true);
Object attachInfo = attachInfoField.get(this);
if (attachInfo != null) {
Field stableInsetsField =
attachInfo.getClass().getDeclaredField("mStableInsets");
stableInsetsField.setAccessible(true);
Rect insets = (Rect) stableInsetsField.get(attachInfo);
return insets.bottom;
}
} catch (NoSuchFieldException e) {
LOG.log(WARNING,
"field reflection error when measuring view inset", e);
} catch (IllegalAccessException e) {
LOG.log(WARNING,
"access reflection error when measuring view inset", e);
}
return 0;
}
protected void onKeyboardOpen(int keyboardHeight) {
if (LOG.isLoggable(INFO))
LOG.info("onKeyboardOpen(" + keyboardHeight + ")");
keyboardOpen = true;
notifyShownListeners();
}
protected void onKeyboardClose() {
LOG.info("onKeyboardClose()");
keyboardOpen = false;
}
public boolean isKeyboardOpen() {
return keyboardOpen;
}
public int getKeyboardHeight() {
return isLandscape() ? getKeyboardLandscapeHeight() :
getKeyboardPortraitHeight();
}
public boolean isLandscape() {
int rotation = getDeviceRotation();
return rotation == ROTATION_90 || rotation == ROTATION_270;
}
private int getDeviceRotation() {
WindowManager windowManager =
(WindowManager) getContext().getSystemService(WINDOW_SERVICE);
return requireNonNull(windowManager).getDefaultDisplay().getRotation();
}
private int getKeyboardLandscapeHeight() {
return Math.max(getHeight(), getRootView().getHeight()) / 2;
}
private int getKeyboardPortraitHeight() {
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(getContext());
int keyboardHeight = prefs.getInt("keyboard_height_portrait",
defaultCustomKeyboardSize);
return clamp(keyboardHeight, minCustomKeyboardSize,
getRootView().getHeight() - minCustomKeyboardTopMargin);
}
private int clamp(int value, int min, int max) {
return Math.min(Math.max(value, min), max);
}
private void setKeyboardPortraitHeight(int height) {
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(getContext());
prefs.edit().putInt("keyboard_height_portrait", height).apply();
}
public void addOnKeyboardShownListener(OnKeyboardShownListener listener) {
shownListeners.add(listener);
}
public void removeOnKeyboardShownListener(
OnKeyboardShownListener listener) {
shownListeners.remove(listener);
}
private void notifyShownListeners() {
// Make a copy as listeners may remove themselves when called
Set<OnKeyboardShownListener> listeners = new HashSet<>(shownListeners);
for (OnKeyboardShownListener listener : listeners) {
listener.onKeyboardShown();
}
}
public interface OnKeyboardShownListener {
void onKeyboardShown();
}
}

View File

@@ -16,7 +16,7 @@ import android.widget.LinearLayout;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.view.KeyboardAwareLinearLayout.OnKeyboardShownListener;
import org.briarproject.briar.android.view.EmojiTextInputView.OnKeyboardShownListener;
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
import static java.util.Objects.requireNonNull;
@@ -139,13 +139,9 @@ public class TextInputView extends LinearLayout {
textInput.hideSoftKeyboard();
}
public void addOnKeyboardShownListener(OnKeyboardShownListener listener) {
textInput.addOnKeyboardShownListener(listener);
}
public void removeOnKeyboardShownListener(
OnKeyboardShownListener listener) {
textInput.removeOnKeyboardShownListener(listener);
public void setOnKeyboardShownListener(
@Nullable OnKeyboardShownListener listener) {
textInput.setOnKeyboardShownListener(listener);
}
}

View File

@@ -29,13 +29,17 @@
app:layout_constraintTop_toTopOf="parent"
app:passwordToggleEnabled="true">
<EditText
<android.support.design.widget.TextInputEditText
android:id="@+id/current_password_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/current_password"
android:importantForAutofill="no"
android:inputType="textPassword"
android:maxLines="1"/>
<requestFocus/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
@@ -49,11 +53,12 @@
app:layout_constraintTop_toBottomOf="@id/current_password_entry_wrapper"
app:passwordToggleEnabled="true">
<EditText
<android.support.design.widget.TextInputEditText
android:id="@+id/new_password_entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/choose_new_password"
android:importantForAutofill="no"
android:inputType="textPassword"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
@@ -69,12 +74,13 @@
app:layout_constraintTop_toBottomOf="@id/new_password_entry_wrapper"
app:passwordToggleEnabled="true">
<EditText
<android.support.design.widget.TextInputEditText
android:id="@+id/new_password_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/confirm_new_password"
android:imeOptions="actionDone"
android:importantForAutofill="no"
android:inputType="textPassword"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>

View File

@@ -15,14 +15,17 @@
app:errorEnabled="true"
app:hintEnabled="false">
<EditText
<android.support.design.widget.TextInputEditText
android:id="@+id/createForumNameEntry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/choose_forum_hint"
android:importantForAutofill="no"
android:inputType="text|textCapSentences"
android:maxLines="1"/>
<requestFocus/>
</android.support.design.widget.TextInputLayout>
<Button

View File

@@ -18,7 +18,7 @@
app:cardCornerRadius="0dp"
app:cardUseCompatPadding="false">
<EditText
<android.support.design.widget.TextInputEditText
android:id="@+id/urlInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -26,9 +26,14 @@
android:gravity="top"
android:hint="@string/blogs_rss_feeds_import_hint"
android:imeOptions="actionDone"
android:importantForAutofill="no"
android:inputType="textUri"
android:padding="@dimen/margin_medium"
android:textColor="?android:attr/textColorPrimary"/>
android:textColor="?android:attr/textColorPrimary">
<requestFocus/>
</android.support.design.widget.TextInputEditText>
</android.support.v7.widget.CardView>

View File

@@ -14,7 +14,11 @@
android:gravity="bottom"
app:buttonText="@string/blogs_publish_blog_post"
app:fillHeight="true"
app:hint="@string/blogs_write_blog_post_body_hint"/>
app:hint="@string/blogs_write_blog_post_body_hint">
<requestFocus/>
</org.briarproject.briar.android.view.LargeTextInputView>
<ProgressBar
android:id="@+id/progressBar"

View File

@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:parentTag="org.briarproject.briar.android.view.KeyboardAwareLinearLayout"
tools:parentTag="android.widget.LinearLayout"
tools:showIn="@layout/fragment_reblog">
<android.support.v7.widget.AppCompatImageButton

View File

@@ -15,14 +15,17 @@
app:errorEnabled="true"
app:hintEnabled="false">
<EditText
<android.support.design.widget.TextInputEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/groups_create_group_hint"
android:importantForAutofill="no"
android:inputType="text|textCapSentences"
android:maxLines="1"/>
<requestFocus/>
</android.support.design.widget.TextInputLayout>
<Button

View File

@@ -31,6 +31,9 @@
android:imeOptions="actionDone"
android:inputType="textPassword"
android:maxLines="1"/>
<requestFocus/>
</android.support.design.widget.TextInputLayout>
<Button

View File

@@ -38,6 +38,7 @@
android:maxLines="1"/>
<requestFocus/>
</android.support.design.widget.TextInputLayout>
<Button

View File

@@ -39,6 +39,7 @@
android:maxLines="1">
<requestFocus/>
</android.support.design.widget.TextInputEditText>
</android.support.design.widget.TextInputLayout>

View File

@@ -68,18 +68,6 @@
<dimen name="blogs_avatar_icon_size">15dp</dimen>
<dimen name="blogs_avatar_comment_size">20dp</dimen>
<!-- Emoji -->
<dimen name="text_input_height">42dp</dimen>
<dimen name="conversation_item_body_text_size">16sp</dimen>
<dimen name="emoji_drawer_size">32sp</dimen>
<dimen name="emoji_drawer_indicator_height">2dp</dimen>
<dimen name="emoji_drawer_item_padding">5dp</dimen>
<dimen name="emoji_drawer_left_right_padding">2dp</dimen>
<!-- Keyboard Sizes -->
<dimen name="min_keyboard_size">50dp</dimen>
<dimen name="default_custom_keyboard_size">220dp</dimen>
<dimen name="min_custom_keyboard_size">110dp</dimen>
<dimen name="min_custom_keyboard_top_margin">170dp</dimen>
</resources>

View File

@@ -118,8 +118,8 @@ dependencyVerification {
'com.sun.activation:javax.activation:1.2.0:javax.activation-1.2.0.jar:993302b16cd7056f21e779cc577d175a810bb4900ef73cd8fbf2b50f928ba9ce',
'com.sun.istack:istack-commons-runtime:2.21:istack-commons-runtime-2.21.jar:c33e67a0807095f02a0e2da139412dd7c4f9cc1a4c054b3e434f96831ba950f4',
'com.sun.xml.fastinfoset:FastInfoset:1.2.13:FastInfoset-1.2.13.jar:27a77db909f3c2833c0b1a37c55af1db06045118ad2eed96ce567b6632bce038',
'com.vanniktech:emoji-google:0.5.1:emoji-google-0.5.1.aar:5f4a88e1a3bb5f694ddccf2e49dc9ccc44431f1d4f980bc453c178f57869dea0',
'com.vanniktech:emoji:0.5.1:emoji-0.5.1.aar:d55f44e04e31895647d62c33c34a8d501995e9e1b5c5f5cee6cbb8630eeb37f7',
'com.vanniktech:emoji-google:0.6.0:emoji-google-0.6.0.aar:029d6a954cebfe3f0a5bac0c9539a054fa7db2e1272d006a8f0e850f3794d44b',
'com.vanniktech:emoji:0.6.0:emoji-0.6.0.aar:a5fcde58902305c004f03c6dc2241e718400ac4162226079791d87fac83ef639',
'commons-codec:commons-codec:1.10:commons-codec-1.10.jar:4241dfa94e711d435f29a4604a3e2de5c4aa3c165e23bd066be6fc1fc4309569',
'commons-logging:commons-logging:1.2:commons-logging-1.2.jar:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636',
'de.hdodenhof:circleimageview:2.2.0:circleimageview-2.2.0.aar:bc34761dcd5036229ac1ffed6b5b1bef722ad5b097a2c8bba1c5ed2cd4b5c82b',