Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add user status #1668

Merged
merged 56 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
05586cc
add user status option to account dialog (WIP)
mahibi Dec 28, 2021
a94f0f1
Adopt more parts from files app [WIP]
timkrueger Jan 12, 2022
57a408a
add predefined statuses
mahibi Feb 2, 2022
8117c77
notifyDataSetChanged after predefines statuses were loaded
mahibi Feb 4, 2022
454c6cd
add ability to send predefined and custom status
mahibi Feb 4, 2022
df5ac64
fix to clear the status
mahibi Feb 4, 2022
7cc8751
disable set status button until status is received
mahibi Feb 7, 2022
967b63b
draw status in ChooseAccountDialogFragment
mahibi Feb 7, 2022
45028c3
fix colors for online status
mahibi Feb 7, 2022
dad53a7
fix wrong calculation for "in 4h" (=remove linebreak)
mahibi Feb 7, 2022
622eaa1
check capabilities to set status support
mahibi Feb 7, 2022
19060bd
delete comments
mahibi Feb 8, 2022
45cfbc7
add ability to set status type
mahibi Feb 8, 2022
ea634ff
delete comments
mahibi Feb 8, 2022
c87940e
fix seperator color for in account dialog
mahibi Feb 16, 2022
bce0d27
fix to be able to modify status message after predefined status was s…
mahibi Feb 16, 2022
546f3fe
fix to be able to set only "icon" / only "clear at" for status
mahibi Feb 17, 2022
e27ede7
tidy up
mahibi Feb 17, 2022
6057306
show user statuses in conversation list
mahibi Feb 17, 2022
d453773
show user statuses in conversation info (wip)
mahibi Feb 18, 2022
176568b
show online status AND emoji in conversations info
mahibi Feb 21, 2022
22c770f
set "away" / "dnd" as status message if it's empty
mahibi Feb 21, 2022
c64a71b
improve layout
mahibi Feb 21, 2022
21af838
hide secondary text for normal users
mahibi Feb 21, 2022
ffbe39b
change UserStatusCapability to kotlin data class
mahibi Feb 21, 2022
e3fd9a7
fix onlinestatus color for night mode
mahibi Feb 21, 2022
e94cb3b
allow 2 lines for status message in conversation info
mahibi Feb 22, 2022
6a9dea7
fix autocomplete mentions
mahibi Feb 22, 2022
0078778
show status for autocomplete mentions
mahibi Feb 22, 2022
02bd95f
improve autocomplete mention items design
mahibi Feb 23, 2022
452baf4
improve autocomplete mentions UI
mahibi Feb 23, 2022
7820bc7
hide status of "Talk updates" conversation
mahibi Feb 23, 2022
4c07cce
fix NPE when opening Contacts view.
mahibi Feb 23, 2022
4f1a188
fix lint/spotbug warnings
mahibi Feb 23, 2022
73ce271
fix klint warnings
mahibi Feb 23, 2022
1da8c3b
modify StatusDrawable and use it for conversationList
mahibi Feb 24, 2022
5437466
use same online state color as web and iOS
mahibi Feb 24, 2022
fc8462e
use StatusDrawable for conversationInfo and mention autocomplete
mahibi Feb 24, 2022
ce00231
fix NPE for contacts view
mahibi Feb 24, 2022
a7792cb
fix lint and spotbugs warnings
mahibi Feb 24, 2022
c746b95
add author to license headers
mahibi Feb 24, 2022
305ceed
align username etc vertical if no status message is set
mahibi Feb 24, 2022
b7b92eb
fix textcolor for highlighted online status button
mahibi Feb 24, 2022
f475065
set same textSize for all headings in Status dialog
mahibi Feb 24, 2022
4984ba4
avoid linebreaks for "clear at" calculation
mahibi Feb 24, 2022
e1c706f
align icons + text in choose account dialog
mahibi Feb 24, 2022
ec438b0
add rounded colors to online status buttons
mahibi Feb 24, 2022
d4f9f99
fix vertical alignment for MentionAutocompleteItem's
mahibi Feb 24, 2022
0677607
migrate FlexibleItems to native view bindings
AndyScherzinger Feb 25, 2022
7ce1b9e
adapt license header to app
AndyScherzinger Feb 25, 2022
d3c46e7
Drone: update Lint results to reflect reduced error/warning count [sk…
Feb 25, 2022
0dc42a1
fix NPE if status is null
mahibi Feb 25, 2022
a3e86d8
correct enum comparisons and add constants for fixed values
AndyScherzinger Feb 25, 2022
5c86629
fix license header mail format
AndyScherzinger Feb 25, 2022
9d29cbf
fix vertical alignments for UserItem
mahibi Feb 25, 2022
dacaf5b
Drone: update FindBugs results to reflect reduced error/warning count…
Feb 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.github.vanniktech:Emoji:0.6.0' // 0.7.0 has display issue - don't update to 0.7.0
implementation "com.vanniktech:emoji-google:0.8.0"
implementation group: 'androidx.emoji', name: 'emoji-bundled', version: '1.1.0'
implementation 'org.michaelevans.colorart:library:0.0.3'
implementation "androidx.work:work-runtime:${workVersion}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
apiVersion,
signatureVerification.userEntity.baseUrl,
decryptedPushMessage.id
)
),
null
)
.repeatWhen { completed ->
completed.zipWith(Observable.range(1, 12), { _, i -> i })
Expand Down
134 changes: 89 additions & 45 deletions app/src/main/java/com/nextcloud/talk/activities/CallActivity.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ private void checkIfAnyParticipantsRemainInRoom() {
int apiVersion = ApiUtils.getCallApiVersion(userBeingCalled, new int[]{ApiUtils.APIv4, 1});

ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, userBeingCalled.getBaseUrl(),
currentConversation.getToken()))
currentConversation.getToken()), null)
.subscribeOn(Schedulers.io())
.repeatWhen(completed -> completed.zipWith(Observable.range(1, 12), (n, i) -> i)
.flatMap(retryCount -> Observable.timer(5, TimeUnit.SECONDS))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Nextcloud Talk application
*
* @author Tobias Kaminsky
* Copyright (C) 2020 Tobias Kaminsky
* Copyright (C) 2020 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.nextcloud.talk.adapters

import com.nextcloud.talk.models.json.status.predefined.PredefinedStatus

interface PredefinedStatusClickListener {
fun onClick(predefinedStatus: PredefinedStatus)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Nextcloud Talk application
*
* @author Tobias Kaminsky
* Copyright (C) 2020 Tobias Kaminsky
* Copyright (C) 2020 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.nextcloud.talk.adapters

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.databinding.PredefinedStatusBinding
import com.nextcloud.talk.models.json.status.predefined.PredefinedStatus

class PredefinedStatusListAdapter(
private val clickListener: PredefinedStatusClickListener,
val context: Context
) : RecyclerView.Adapter<PredefinedStatusViewHolder>() {
internal var list: List<PredefinedStatus> = emptyList()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PredefinedStatusViewHolder {
val itemBinding = PredefinedStatusBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return PredefinedStatusViewHolder(itemBinding)
}

override fun onBindViewHolder(holder: PredefinedStatusViewHolder, position: Int) {
holder.bind(list[position], clickListener, context)
}

override fun getItemCount(): Int {
return list.size
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Nextcloud Talk application
*
* @author Tobias Kaminsky
* Copyright (C) 2020 Tobias Kaminsky
* Copyright (C) 2020 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.nextcloud.talk.adapters

import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.R
import com.nextcloud.talk.databinding.PredefinedStatusBinding
import com.nextcloud.talk.models.json.status.predefined.PredefinedStatus
import com.nextcloud.talk.utils.DisplayUtils

private const val ONE_SECOND_IN_MILLIS = 1000

class PredefinedStatusViewHolder(private val binding: PredefinedStatusBinding) : RecyclerView.ViewHolder(binding.root) {

fun bind(status: PredefinedStatus, clickListener: PredefinedStatusClickListener, context: Context) {
binding.root.setOnClickListener { clickListener.onClick(status) }
binding.icon.text = status.icon
binding.name.text = status.message

if (status.clearAt == null) {
binding.clearAt.text = context.getString(R.string.dontClear)
} else {
val clearAt = status.clearAt!!
if (clearAt.type.equals("period")) {
binding.clearAt.text = DisplayUtils.getRelativeTimestamp(
context,
System.currentTimeMillis() + clearAt.time.toInt() * ONE_SECOND_IN_MILLIS,
true
)
} else {
// end-of
if (clearAt.time.equals("day")) {
binding.clearAt.text = context.getString(R.string.today)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Nextcloud Talk application
*
* @author Mario Danic
* @author Andy Scherzinger
* Copyright (C) 2022 Andy Scherzinger <[email protected]>
* Copyright (C) 2017 Mario Danic ([email protected])
*
* This program is free software: you can redistribute it and/or modify
Expand All @@ -24,17 +26,12 @@
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.nextcloud.talk.R;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.databinding.AccountItemBinding;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.participants.Participant;
import com.nextcloud.talk.utils.ApiUtils;
Expand All @@ -44,9 +41,6 @@
import java.util.regex.Pattern;

import androidx.annotation.Nullable;
import androidx.emoji.widget.EmojiTextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
import eu.davidea.flexibleadapter.items.IFilterable;
Expand All @@ -56,10 +50,10 @@
public class AdvancedUserItem extends AbstractFlexibleItem<AdvancedUserItem.UserItemViewHolder> implements
IFilterable<String> {

private Participant participant;
private UserEntity userEntity;
private final Participant participant;
private final UserEntity userEntity;
@Nullable
private Account account;
private final Account account;

public AdvancedUserItem(Participant participant, UserEntity userEntity, @Nullable Account account) {
this.participant = participant;
Expand Down Expand Up @@ -110,68 +104,70 @@ public UserItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) {

@Override
public void bindViewHolder(FlexibleAdapter adapter, UserItemViewHolder holder, int position, List payloads) {
holder.avatarImageView.setController(null);
holder.binding.userIcon.setController(null);

if (adapter.hasFilter()) {
FlexibleUtils.highlightText(
holder.contactDisplayName,
holder.binding.userName,
participant.getDisplayName(),
String.valueOf(adapter.getFilter(String.class)),
NextcloudTalkApplication.Companion.getSharedApplication()
.getResources()
.getColor(R.color.colorPrimary));
} else {
holder.contactDisplayName.setText(participant.getDisplayName());
holder.binding.userName.setText(participant.getDisplayName());
}

if (userEntity != null && !TextUtils.isEmpty(userEntity.getBaseUrl())) {
String host = Uri.parse(userEntity.getBaseUrl()).getHost();
if (!TextUtils.isEmpty(host)) {
holder.serverUrl.setText(Uri.parse(userEntity.getBaseUrl()).getHost());
holder.binding.account.setText(Uri.parse(userEntity.getBaseUrl()).getHost());
} else {
holder.serverUrl.setText(userEntity.getBaseUrl());
holder.binding.account.setText(userEntity.getBaseUrl());
}
}

holder.avatarImageView.getHierarchy().setPlaceholderImage(R.drawable.account_circle_48dp);
holder.avatarImageView.getHierarchy().setFailureImage(R.drawable.account_circle_48dp);
holder.binding.userIcon.getHierarchy().setPlaceholderImage(R.drawable.account_circle_48dp);
holder.binding.userIcon.getHierarchy().setFailureImage(R.drawable.account_circle_48dp);

if (userEntity != null && userEntity.getBaseUrl() != null &&
userEntity.getBaseUrl().startsWith("http://") ||
userEntity.getBaseUrl().startsWith("https://")) {

DraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setOldController(holder.avatarImageView.getController())
.setOldController(holder.binding.userIcon.getController())
.setAutoPlayAnimations(true)
.setImageRequest(DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(userEntity.getBaseUrl(),
participant.getActorId(), R.dimen.small_item_height), null))
.setImageRequest(
DisplayUtils.getImageRequestForUrl(
ApiUtils.getUrlForAvatarWithName(
userEntity.getBaseUrl(),
participant.getActorId(),
R.dimen.small_item_height),
null))
.build();
holder.avatarImageView.setController(draweeController);
holder.binding.userIcon.setController(draweeController);
}
}

@Override
public boolean filter(String constraint) {
return participant.getDisplayName() != null &&
Pattern.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL).matcher(participant.getDisplayName().trim()).find();
Pattern
.compile(constraint, Pattern.CASE_INSENSITIVE | Pattern.LITERAL)
.matcher(participant.getDisplayName().trim())
.find();
}


static class UserItemViewHolder extends FlexibleViewHolder {

@BindView(R.id.user_name)
public EmojiTextView contactDisplayName;
@BindView(R.id.account)
public TextView serverUrl;
@BindView(R.id.user_icon)
public SimpleDraweeView avatarImageView;
public AccountItemBinding binding;

/**
* Default constructor.
*/
UserItemViewHolder(View view, FlexibleAdapter adapter) {
super(view, adapter);
ButterKnife.bind(this, view);
binding = AccountItemBinding.bind(view);
}
}
}
Loading