Various updates

This commit is contained in:
Mario Danic 2019-12-08 13:20:07 +01:00
parent 8eb2f78a23
commit b492c8a576
No known key found for this signature in database
GPG Key ID: CDE0BBD2738C4CC0
45 changed files with 770 additions and 1248 deletions

View File

@ -1,229 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
</value>
</option>
<option name="RIGHT_MARGIN" value="100" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
</AndroidXmlCodeStyleSettings>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" />
<pair source="c" header="h" />
</extensions>
</Objective-C-extensions>
<XML>
<option name="XML_KEEP_LINE_BREAKS" value="false" />
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</value>
</option>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
</component>
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
</annotationProcessing>
</component>
</project>

View File

@ -1,7 +0,0 @@
<component name="CopyrightManager">
<copyright>
<option name="allowReplaceRegexp" value="true" />
<option name="notice" value="Nextcloud Talk application&#10; &#10;@author Mario Danic&#10;Copyright (C) 2017-2019 Mario Danic &lt;mario@lovelyhq.com&gt;&#10; &#10;This program is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;at your option) any later version.&#10; &#10;This program is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10; &#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." />
<option name="myName" value="GPL3" />
</copyright>
</component>

View File

@ -1,7 +0,0 @@
<component name="CopyrightManager">
<settings default="GPL3">
<module2copyright>
<element module="Project Files" copyright="GPL3" />
</module2copyright>
</settings>
</component>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@ -1,4 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project> </project>

View File

@ -2,10 +2,8 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/Projects-talk-android.iml" filepath="$PROJECT_DIR$/Projects-talk-android.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" /> <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
<module fileurl="file://$PROJECT_DIR$/talk-android.iml" filepath="$PROJECT_DIR$/talk-android.iml" /> <module fileurl="file://$PROJECT_DIR$/talk-android.iml" filepath="$PROJECT_DIR$/talk-android.iml" />
<module fileurl="file://$PROJECT_DIR$/app/talk-android-app.iml" filepath="$PROJECT_DIR$/app/talk-android-app.iml" />
</modules> </modules>
</component> </component>
</project> </project>

View File

@ -27,6 +27,7 @@ import coil.transform.CircleCropTransformation
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
@ -39,7 +40,7 @@ class MentionAutocompleteItem(
val objectId: String?, val objectId: String?,
val displayName: String?, val displayName: String?,
var source: String?, var source: String?,
private val currentUser: UserEntity private val currentUser: UserNgEntity
) : AbstractFlexibleItem<UserItem.UserItemViewHolder>(), IFilterable<String> { ) : AbstractFlexibleItem<UserItem.UserItemViewHolder>(), IFilterable<String> {
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {

View File

@ -309,18 +309,14 @@ public class AccountVerificationController extends BaseController {
@Override @Override
public void onNext(UserProfileOverall userProfileOverall) { public void onNext(UserProfileOverall userProfileOverall) {
String displayName = null; String displayName = null;
if (!TextUtils.isEmpty(userProfileOverall.getOcs().getData() if (!TextUtils.isEmpty(userProfileOverall.ocs.data.displayName)) {
.getDisplayName())) { displayName = userProfileOverall.ocs.data.displayName;
displayName = userProfileOverall.getOcs().getData() } else if (!TextUtils.isEmpty(userProfileOverall.ocs.data.displayNameAlt)) {
.getDisplayName(); displayName = userProfileOverall.ocs.data.displayNameAlt;
} else if (!TextUtils.isEmpty(userProfileOverall.getOcs().getData()
.getDisplayNameAlt())) {
displayName = userProfileOverall.getOcs().getData()
.getDisplayNameAlt();
} }
if (!TextUtils.isEmpty(displayName)) { if (!TextUtils.isEmpty(displayName)) {
storeProfile(displayName, userProfileOverall.getOcs().getData().getUserId()); storeProfile(displayName, userProfileOverall.ocs.data.userId);
} else { } else {
if (getActivity() != null) { if (getActivity() != null) {
getActivity().runOnUiThread( getActivity().runOnUiThread(
@ -356,28 +352,28 @@ public class AccountVerificationController extends BaseController {
@Subscribe(threadMode = ThreadMode.BACKGROUND) @Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessageEvent(EventStatus eventStatus) { public void onMessageEvent(EventStatus eventStatus) {
if (eventStatus.getEventType().equals(EventStatus.EventType.PUSH_REGISTRATION)) { if (EventStatus.EventType.PUSH_REGISTRATION == eventStatus.eventType) {
if (internalAccountId == eventStatus.getUserId() if (internalAccountId == eventStatus.userId
&& !eventStatus.isAllGood() && !eventStatus.allGood
&& getActivity() != null) { && getActivity() != null) {
getActivity().runOnUiThread( getActivity().runOnUiThread(
() -> progressText.setText(progressText.getText().toString() + "\n" + () -> progressText.setText(progressText.getText().toString() + "\n" +
getResources().getString(R.string.nc_push_disabled))); getResources().getString(R.string.nc_push_disabled)));
} }
fetchAndStoreCapabilities(); fetchAndStoreCapabilities();
} else if (eventStatus.getEventType().equals(EventStatus.EventType.CAPABILITIES_FETCH)) { } else if (EventStatus.EventType.CAPABILITIES_FETCH == eventStatus.eventType) {
if (internalAccountId == eventStatus.getUserId() && !eventStatus.isAllGood()) { if (internalAccountId == eventStatus.userId && !eventStatus.allGood) {
if (getActivity() != null) { if (getActivity() != null) {
getActivity().runOnUiThread( getActivity().runOnUiThread(
() -> progressText.setText(progressText.getText().toString() + "\n" + () -> progressText.setText(progressText.getText().toString() + "\n" +
getResources().getString(R.string.nc_capabilities_failed))); getResources().getString(R.string.nc_capabilities_failed)));
} }
abortVerification(); abortVerification();
} else if (internalAccountId == eventStatus.getUserId() && eventStatus.isAllGood()) { } else if (internalAccountId == eventStatus.userId && eventStatus.allGood) {
fetchAndStoreExternalSignalingSettings(); fetchAndStoreExternalSignalingSettings();
} }
} else if (eventStatus.getEventType().equals(EventStatus.EventType.SIGNALING_SETTINGS)) { } else if (EventStatus.EventType.SIGNALING_SETTINGS == eventStatus.eventType) {
if (internalAccountId == eventStatus.getUserId() && !eventStatus.isAllGood()) { if (internalAccountId == eventStatus.userId && !eventStatus.allGood) {
if (getActivity() != null) { if (getActivity() != null) {
getActivity().runOnUiThread( getActivity().runOnUiThread(
() -> progressText.setText(progressText.getText().toString() + "\n" + () -> progressText.setText(progressText.getText().toString() + "\n" +

View File

@ -1259,8 +1259,8 @@ class CallController(args: Bundle) : BaseController() {
if (webSocketClient == null) { if (webSocketClient == null) {
webSocketClient = WebSocketConnectionHelper.getExternalSignalingInstanceForServer( webSocketClient = WebSocketConnectionHelper.getExternalSignalingInstanceForServer(
externalSignalingServer!!.externalSignalingServer, externalSignalingServer!!.externalSignalingServer!!,
conversationUser, externalSignalingServer!!.externalSignalingTicket, conversationUser!!, externalSignalingServer!!.externalSignalingTicket,
TextUtils.isEmpty(credentials) TextUtils.isEmpty(credentials)
) )
} else { } else {

View File

@ -650,7 +650,7 @@ class ChatController(args: Bundle) : BaseController(), MessagesListAdapter
private fun setupMentionAutocomplete() { private fun setupMentionAutocomplete() {
val elevation = 6f val elevation = 6f
val backgroundDrawable = ColorDrawable(resources!!.getColor(R.color.bg_default)) val backgroundDrawable = ColorDrawable(resources!!.getColor(R.color.bg_default))
val presenter = MentionAutocompletePresenter(applicationContext, roomToken) val presenter = MentionAutocompletePresenter(applicationContext!!, roomToken)
val callback = MentionAutocompleteCallback( val callback = MentionAutocompleteCallback(
activity, activity,
conversationUser, messageInput conversationUser, messageInput

View File

@ -756,8 +756,7 @@ class ConversationInfoController(args: Bundle) : BaseController(),
putExtra( putExtra(
Intent.EXTRA_TEXT, ShareUtils.getStringForIntent( Intent.EXTRA_TEXT, ShareUtils.getStringForIntent(
context, conversation!!.password, context, conversation!!.password, conversation!!
userUtils, conversation
) )
) )

View File

@ -173,7 +173,7 @@ public class EntryMenuController extends BaseController {
} else if (operationCode == 7) { } else if (operationCode == 7) {
if (getActivity() != null) { if (getActivity() != null) {
shareIntent.putExtra(Intent.EXTRA_TEXT, ShareUtils.getStringForIntent(getActivity(), shareIntent.putExtra(Intent.EXTRA_TEXT, ShareUtils.getStringForIntent(getActivity(),
editText.getText().toString(), userUtils, conversation)); editText.getText().toString(), conversation));
Intent intent = new Intent(shareIntent); Intent intent = new Intent(shareIntent);
intent.setComponent(new ComponentName(packageName, name)); intent.setComponent(new ComponentName(packageName, name));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

View File

@ -24,9 +24,9 @@ import lombok.Data;
@Data @Data
public class EventStatus { public class EventStatus {
private long userId; public long userId;
private EventType eventType; public EventType eventType;
private boolean allGood; public boolean allGood;
public EventStatus(long userId, EventType eventType, boolean allGood) { public EventStatus(long userId, EventType eventType, boolean allGood) {
this.userId = userId; this.userId = userId;

View File

@ -1,95 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import autodagger.AutoInjector;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.events.EventStatus;
import com.nextcloud.talk.models.RetrofitBucket;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
import io.reactivex.schedulers.Schedulers;
import javax.inject.Inject;
import org.greenrobot.eventbus.EventBus;
@AutoInjector(NextcloudTalkApplication.class)
public class AddParticipantsToConversation extends Worker {
@Inject
NcApi ncApi;
@Inject
UserUtils userUtils;
@Inject
EventBus eventBus;
public AddParticipantsToConversation(@NonNull Context context,
@NonNull WorkerParameters workerParams) {
super(context, workerParams);
NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication()
.inject(this);
}
@NonNull
@Override
public Result doWork() {
Data data = getInputData();
String[] selectedUserIds = data.getStringArray(BundleKeys.INSTANCE.getKEY_SELECTED_USERS());
String[] selectedGroupIds = data.getStringArray(BundleKeys.INSTANCE.getKEY_SELECTED_GROUPS());
UserEntity user = userUtils.getUserWithInternalId(
data.getLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), -1));
String conversationToken = data.getString(BundleKeys.INSTANCE.getKEY_TOKEN());
String credentials = ApiUtils.getCredentials(user.getUsername(), user.getToken());
RetrofitBucket retrofitBucket;
for (String userId : selectedUserIds) {
retrofitBucket =
ApiUtils.getRetrofitBucketForAddParticipant(user.getBaseUrl(), conversationToken,
userId);
ncApi.addParticipant(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap())
.subscribeOn(Schedulers.io())
.blockingSubscribe();
}
for (String groupId : selectedGroupIds) {
retrofitBucket =
ApiUtils.getRetrofitBucketForAddGroupParticipant(user.getBaseUrl(), conversationToken,
groupId);
ncApi.addParticipant(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap())
.subscribeOn(Schedulers.io())
.blockingSubscribe();
}
eventBus.post(new EventStatus(user.getId(), EventStatus.EventType.PARTICIPANTS_UPDATE, true));
return Result.success();
}
}

View File

@ -0,0 +1,86 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.Worker
import androidx.work.WorkerParameters
import autodagger.AutoInjector
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.models.RetrofitBucket
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SELECTED_GROUPS
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SELECTED_USERS
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_TOKEN
import com.nextcloud.talk.utils.database.user.UserUtils
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.koin.core.KoinComponent
import org.koin.core.inject
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class AddParticipantsToConversation(context: Context,
workerParams: WorkerParameters) : CoroutineWorker(context, workerParams), KoinComponent {
@JvmField
@Inject
var ncApi: NcApi? = null
val eventBus: EventBus by inject()
val usersRepository: UsersRepository by inject()
override suspend fun doWork(): Result {
val data = inputData
val selectedUserIds = data.getStringArray(KEY_SELECTED_USERS)
val selectedGroupIds = data.getStringArray(KEY_SELECTED_GROUPS)
val user = usersRepository.getUserWithId(data.getLong(KEY_INTERNAL_USER_ID, -1))
val conversationToken = data.getString(KEY_TOKEN)
val credentials = ApiUtils.getCredentials(user.username, user.token)
var retrofitBucket: RetrofitBucket
for (userId in selectedUserIds!!) {
retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipant(user.baseUrl, conversationToken,
userId)
ncApi!!.addParticipant(credentials, retrofitBucket.url, retrofitBucket.queryMap)
.subscribeOn(Schedulers.io())
.blockingSubscribe()
}
for (groupId in selectedGroupIds!!) {
retrofitBucket = ApiUtils.getRetrofitBucketForAddGroupParticipant(user.baseUrl, conversationToken,
groupId)
ncApi!!.addParticipant(credentials, retrofitBucket.url, retrofitBucket.queryMap)
.subscribeOn(Schedulers.io())
.blockingSubscribe()
}
eventBus.post(EventStatus(user.id, EventStatus.EventType.PARTICIPANTS_UPDATE, true))
return Result.success()
}
init {
sharedApplication
?.componentApplication
?.inject(this)
}
}

View File

@ -1,165 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import autodagger.AutoInjector;
import com.bluelinelabs.logansquare.LoganSquare;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.events.EventStatus;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import java.io.IOException;
import java.net.CookieManager;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient;
import org.greenrobot.eventbus.EventBus;
import retrofit2.Retrofit;
@AutoInjector(NextcloudTalkApplication.class)
public class CapabilitiesWorker extends Worker {
public static final String TAG = "CapabilitiesWorker";
@Inject
UserUtils userUtils;
@Inject
Retrofit retrofit;
@Inject
EventBus eventBus;
@Inject
OkHttpClient okHttpClient;
NcApi ncApi;
public CapabilitiesWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
private void updateUser(CapabilitiesOverall capabilitiesOverall, UserEntity internalUserEntity) {
try {
userUtils.createOrUpdateUser(null, null,
null, null,
null, null, null, internalUserEntity.getId(),
LoganSquare.serialize(capabilitiesOverall.getOcs().getData().getCapabilities()), null,
null)
.blockingSubscribe(new Observer<UserEntity>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(UserEntity userEntity) {
eventBus.post(new EventStatus(userEntity.getId(),
EventStatus.EventType.CAPABILITIES_FETCH, true));
}
@Override
public void onError(Throwable e) {
eventBus.post(new EventStatus(internalUserEntity.getId(),
EventStatus.EventType.CAPABILITIES_FETCH, false));
}
@Override
public void onComplete() {
}
});
} catch (IOException e) {
Log.e(TAG, "Failed to create or update user");
}
}
@NonNull
@Override
public Result doWork() {
NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication()
.inject(this);
Data data = getInputData();
long internalUserId = data.getLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), -1);
UserEntity userEntity;
List userEntityObjectList = new ArrayList();
if (internalUserId == -1
|| (userEntity = userUtils.getUserWithInternalId(internalUserId)) == null) {
userEntityObjectList = userUtils.getUsers();
} else {
userEntityObjectList.add(userEntity);
}
for (Object userEntityObject : userEntityObjectList) {
UserEntity internalUserEntity = (UserEntity) userEntityObject;
ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
ncApi.getCapabilities(ApiUtils.getCredentials(internalUserEntity.getUsername(),
internalUserEntity.getToken()),
ApiUtils.getUrlForCapabilities(internalUserEntity.getBaseUrl()))
.retry(3)
.blockingSubscribe(new Observer<CapabilitiesOverall>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(CapabilitiesOverall capabilitiesOverall) {
updateUser(capabilitiesOverall, internalUserEntity);
}
@Override
public void onError(Throwable e) {
eventBus.post(new EventStatus(internalUserEntity.getId(),
EventStatus.EventType.CAPABILITIES_FETCH, false));
}
@Override
public void onComplete() {
}
});
}
return Result.success();
}
}

View File

@ -0,0 +1,103 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import autodagger.AutoInjector
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.runBlocking
import okhttp3.JavaNetCookieJar
import okhttp3.OkHttpClient
import org.greenrobot.eventbus.EventBus
import org.koin.core.KoinComponent
import org.koin.core.inject
import retrofit2.Retrofit
import java.net.CookieManager
import java.util.*
@AutoInjector(NextcloudTalkApplication::class)
class CapabilitiesWorker(context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams), KoinComponent {
val retrofit: Retrofit by inject()
val eventBus: EventBus by inject()
val okHttpClient: OkHttpClient by inject()
val usersRepository: UsersRepository by inject()
var ncApi: NcApi? = null
private fun updateUser(capabilitiesOverall: CapabilitiesOverall, internalUserEntity: UserNgEntity) {
internalUserEntity.capabilities = capabilitiesOverall.ocs.data.capabilities
runBlocking {
val result = usersRepository.updateUser(internalUserEntity)
eventBus!!.post(EventStatus(internalUserEntity.id,
EventStatus.EventType.CAPABILITIES_FETCH, result > 0))
}
}
override suspend fun doWork(): Result {
val data = inputData
val internalUserId = data.getLong(KEY_INTERNAL_USER_ID, -1)
var userEntity: UserNgEntity?
var userEntityObjectList: MutableList<UserNgEntity> = ArrayList()
if (internalUserId == -1L || usersRepository.getUserWithId(internalUserId) == null) {
userEntityObjectList = usersRepository.getUsers().toMutableList()
} else {
userEntity = usersRepository.getUserWithId(internalUserId)
userEntityObjectList.add(userEntity)
}
for (userEntityObject in userEntityObjectList) {
val internalUserEntity = userEntityObject
ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(JavaNetCookieJar(CookieManager())).build()).build().create(NcApi::class.java)
ncApi!!.getCapabilities(ApiUtils.getCredentials(internalUserEntity.username,
internalUserEntity.token),
ApiUtils.getUrlForCapabilities(internalUserEntity.baseUrl))
.retry(3)
.blockingSubscribe(object : Observer<CapabilitiesOverall> {
override fun onSubscribe(d: Disposable) {}
override fun onNext(capabilitiesOverall: CapabilitiesOverall) {
updateUser(capabilitiesOverall, internalUserEntity)
}
override fun onError(e: Throwable) {
eventBus.post(EventStatus(internalUserEntity.id,
EventStatus.EventType.CAPABILITIES_FETCH, false))
}
override fun onComplete() {}
})
}
return Result.success()
}
companion object {
const val TAG = "CapabilitiesWorker"
}
}

View File

@ -1,117 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import autodagger.AutoInjector;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.events.EventStatus;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.generic.GenericOverall;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import java.net.CookieManager;
import javax.inject.Inject;
import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient;
import org.greenrobot.eventbus.EventBus;
import retrofit2.Retrofit;
@AutoInjector(NextcloudTalkApplication.class)
public class LeaveConversationWorker extends Worker {
@Inject
Retrofit retrofit;
@Inject
OkHttpClient okHttpClient;
@Inject
UserUtils userUtils;
@Inject
EventBus eventBus;
NcApi ncApi;
public LeaveConversationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication()
.inject(this);
}
@NonNull
@Override
public Result doWork() {
Data data = getInputData();
long operationUserId = data.getLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), -1);
String conversationToken = data.getString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN());
UserEntity operationUser = userUtils.getUserWithId(operationUserId);
if (operationUser != null) {
String credentials =
ApiUtils.getCredentials(operationUser.getUsername(), operationUser.getToken());
ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new
JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class);
EventStatus eventStatus = new EventStatus(operationUser.getId(),
EventStatus.EventType.CONVERSATION_UPDATE, true);
ncApi.removeSelfFromRoom(credentials,
ApiUtils.getUrlForRemoveSelfFromRoom(operationUser.getBaseUrl(), conversationToken))
.subscribeOn(Schedulers.io())
.blockingSubscribe(new Observer<GenericOverall>() {
Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
disposable = d;
}
@Override
public void onNext(GenericOverall genericOverall) {
eventBus.postSticky(eventStatus);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
disposable.dispose();
}
});
}
return Result.success();
}
}

View File

@ -0,0 +1,85 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import autodagger.AutoInjector
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.local.models.getCredentials
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import okhttp3.JavaNetCookieJar
import okhttp3.OkHttpClient
import org.greenrobot.eventbus.EventBus
import org.koin.core.KoinComponent
import org.koin.core.inject
import retrofit2.Retrofit
import java.net.CookieManager
@AutoInjector(NextcloudTalkApplication::class)
class LeaveConversationWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams), KoinComponent {
val retrofit: Retrofit by inject()
val okHttpClient: OkHttpClient by inject()
val eventBus: EventBus by inject()
val usersRepository: UsersRepository by inject()
var ncApi: NcApi? = null
override fun doWork(): Result {
val data = inputData
val operationUserId = data.getLong(KEY_INTERNAL_USER_ID, -1)
val conversationToken = data.getString(KEY_ROOM_TOKEN)
val operationUser: UserNgEntity? = usersRepository.getUserWithId(operationUserId)
if (operationUser != null) {
val credentials = operationUser.getCredentials()
ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(JavaNetCookieJar(CookieManager())).build()).build().create(NcApi::class.java)
val eventStatus = EventStatus(operationUser.id,
EventStatus.EventType.CONVERSATION_UPDATE, true)
ncApi!!.removeSelfFromRoom(credentials,
ApiUtils.getUrlForRemoveSelfFromRoom(operationUser.baseUrl, conversationToken))
.subscribeOn(Schedulers.io())
.blockingSubscribe(object : Observer<GenericOverall?> {
var disposable: Disposable? = null
override fun onSubscribe(d: Disposable) {
disposable = d
}
override fun onNext(t: GenericOverall) {
eventBus.postSticky(eventStatus)
}
override fun onError(e: Throwable) {}
override fun onComplete() {
disposable!!.dispose()
}
})
}
return Result.success()
}
}

View File

@ -67,7 +67,6 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
import com.nextcloud.talk.models.RingtoneSettings import com.nextcloud.talk.models.RingtoneSettings
import com.nextcloud.talk.models.SignatureVerification import com.nextcloud.talk.models.SignatureVerification
import com.nextcloud.talk.models.database.ArbitraryStorageEntity import com.nextcloud.talk.models.database.ArbitraryStorageEntity
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.chat.ChatUtils import com.nextcloud.talk.models.json.chat.ChatUtils
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.GROUP_CONVERSATION import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.GROUP_CONVERSATION

View File

@ -1,160 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import autodagger.AutoInjector;
import com.bluelinelabs.logansquare.LoganSquare;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.events.EventStatus;
import com.nextcloud.talk.models.ExternalSignalingServer;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.database.user.UserUtils;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.greenrobot.eventbus.EventBus;
@AutoInjector(NextcloudTalkApplication.class)
public class SignalingSettingsWorker extends Worker {
private static final String TAG = "SignalingSettingsJob";
@Inject
UserUtils userUtils;
@Inject
NcApi ncApi;
@Inject
EventBus eventBus;
public SignalingSettingsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication()
.inject(this);
Data data = getInputData();
long internalUserId = data.getLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), -1);
List<UserEntity> userEntityList = new ArrayList<>();
UserEntity userEntity;
if (internalUserId == -1
|| (userEntity = userUtils.getUserWithInternalId(internalUserId)) == null) {
userEntityList = userUtils.getUsers();
} else {
userEntityList.add(userEntity);
}
for (int i = 0; i < userEntityList.size(); i++) {
userEntity = userEntityList.get(i);
UserEntity finalUserEntity = userEntity;
ncApi.getSignalingSettings(
ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()),
ApiUtils.getUrlForSignalingSettings(userEntity.getBaseUrl()))
.blockingSubscribe(new Observer<SignalingSettingsOverall>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(SignalingSettingsOverall signalingSettingsOverall) {
ExternalSignalingServer externalSignalingServer;
externalSignalingServer = new ExternalSignalingServer();
externalSignalingServer.setExternalSignalingServer(
signalingSettingsOverall.getOcs().getSettings().getExternalSignalingServer());
externalSignalingServer.setExternalSignalingTicket(
signalingSettingsOverall.getOcs().getSettings().getExternalSignalingTicket());
try {
userUtils.createOrUpdateUser(null, null, null, null, null,
null, null, finalUserEntity.getId(), null, null,
LoganSquare.serialize(externalSignalingServer))
.subscribe(new Observer<UserEntity>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(UserEntity userEntity) {
eventBus.post(new EventStatus(finalUserEntity.getId(),
EventStatus.EventType.SIGNALING_SETTINGS, true));
}
@Override
public void onError(Throwable e) {
eventBus.post(new EventStatus(finalUserEntity.getId(),
EventStatus.EventType.SIGNALING_SETTINGS, false));
}
@Override
public void onComplete() {
}
});
} catch (IOException e) {
Log.e(TAG, "Failed to serialize external signaling server");
}
}
@Override
public void onError(Throwable e) {
eventBus.post(
new EventStatus(finalUserEntity.getId(), EventStatus.EventType.SIGNALING_SETTINGS,
false));
}
@Override
public void onComplete() {
}
});
}
OneTimeWorkRequest websocketConnectionsWorker =
new OneTimeWorkRequest.Builder(WebsocketConnectionsWorker.class).build();
WorkManager.getInstance().enqueue(websocketConnectionsWorker);
return Result.success();
}
}

View File

@ -0,0 +1,109 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs
import android.content.Context
import android.util.Log
import androidx.work.*
import autodagger.AutoInjector
import com.bluelinelabs.logansquare.LoganSquare
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.jobs.WebsocketConnectionsWorker
import com.nextcloud.talk.models.ExternalSignalingServer
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.local.models.getCredentials
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.database.user.UserUtils
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.greenrobot.eventbus.EventBus
import org.koin.core.KoinComponent
import org.koin.core.inject
import java.io.IOException
import java.util.*
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class SignalingSettingsWorker(context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams), KoinComponent {
@JvmField @Inject
var ncApi: NcApi? = null
val eventBus: EventBus by inject()
val usersRepository: UsersRepository by inject()
override suspend fun doWork(): Result {
sharedApplication
?.componentApplication
?.inject(this)
val data = inputData
val internalUserId = data.getLong(KEY_INTERNAL_USER_ID, -1)
var userEntityList: MutableList<UserNgEntity?> = ArrayList<UserNgEntity?>()
var userEntity: UserNgEntity?
if (internalUserId == -1L || usersRepository.getUserWithId(internalUserId) == null) {
userEntityList = usersRepository.getUsers().toMutableList()
} else {
userEntity = usersRepository.getUserWithId(internalUserId)
userEntityList.add(userEntity)
}
for (i in userEntityList.indices) {
userEntity = userEntityList[i]
val finalUserEntity: UserNgEntity? = userEntity
ncApi!!.getSignalingSettings(
userEntity!!.getCredentials(),
ApiUtils.getUrlForSignalingSettings(userEntity.baseUrl))
.blockingSubscribe(object : Observer<SignalingSettingsOverall> {
override fun onSubscribe(d: Disposable) {}
override fun onNext(signalingSettingsOverall: SignalingSettingsOverall) {
val externalSignalingServer: ExternalSignalingServer
externalSignalingServer = ExternalSignalingServer()
externalSignalingServer.externalSignalingServer = signalingSettingsOverall.ocs.settings.externalSignalingServer
externalSignalingServer.externalSignalingTicket = signalingSettingsOverall.ocs.settings.externalSignalingTicket
val user = usersRepository.getUserWithId(userEntity.id)
user.externalSignaling = externalSignalingServer
runBlocking {
val result = usersRepository.updateUser(user)
eventBus.post(EventStatus(user.id,
EventStatus.EventType.SIGNALING_SETTINGS, result > 0))
}
}
override fun onError(e: Throwable) {
eventBus.post(EventStatus(finalUserEntity!!.id,
EventStatus.EventType.SIGNALING_SETTINGS, false))
}
override fun onComplete() {}
})
}
val websocketConnectionsWorker = OneTimeWorkRequest.Builder(WebsocketConnectionsWorker::class.java).build()
WorkManager.getInstance().enqueue(websocketConnectionsWorker)
return Result.success()
}
}

View File

@ -62,7 +62,7 @@ class WebsocketConnectionsWorker(
if (!userEntity.externalSignaling!!.externalSignalingServer.isNullOrEmpty() && if (!userEntity.externalSignaling!!.externalSignalingServer.isNullOrEmpty() &&
!userEntity.externalSignaling!!.externalSignalingTicket.isNullOrEmpty()) { !userEntity.externalSignaling!!.externalSignalingTicket.isNullOrEmpty()) {
WebSocketConnectionHelper.getExternalSignalingInstanceForServer( WebSocketConnectionHelper.getExternalSignalingInstanceForServer(
userEntity.externalSignaling!!.externalSignalingServer, userEntity.externalSignaling!!.externalSignalingServer!!,
userEntity, userEntity.externalSignaling!!.externalSignalingTicket, userEntity, userEntity.externalSignaling!!.externalSignalingTicket,
false false
) )

View File

@ -29,12 +29,12 @@ import org.parceler.Parcel;
@JsonObject @JsonObject
public class Mention { public class Mention {
@JsonField(name = "id") @JsonField(name = "id")
String id; public String id;
@JsonField(name = "label") @JsonField(name = "label")
String label; public String label;
// type of user (guests or users or calls) // type of user (guests or users or calls)
@JsonField(name = "source") @JsonField(name = "source")
String source; public String source;
} }

View File

@ -31,5 +31,5 @@ import org.parceler.Parcel;
@JsonObject @JsonObject
public class MentionOCS extends GenericOCS { public class MentionOCS extends GenericOCS {
@JsonField(name = "data") @JsonField(name = "data")
List<Mention> data; public List<Mention> data;
} }

View File

@ -29,5 +29,5 @@ import org.parceler.Parcel;
@JsonObject @JsonObject
public class MentionOverall { public class MentionOverall {
@JsonField(name = "ocs") @JsonField(name = "ocs")
MentionOCS ocs; public MentionOCS ocs;
} }

View File

@ -30,8 +30,8 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class AuthParametersWebSocketMessage { public class AuthParametersWebSocketMessage {
@JsonField(name = "userid") @JsonField(name = "userid")
String userid; public String userid;
@JsonField(name = "ticket") @JsonField(name = "ticket")
String ticket; public String ticket;
} }

View File

@ -30,8 +30,8 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class AuthWebSocketMessage { public class AuthWebSocketMessage {
@JsonField(name = "url") @JsonField(name = "url")
String url; public String url;
@JsonField(name = "params") @JsonField(name = "params")
AuthParametersWebSocketMessage authParametersWebSocketMessage; public AuthParametersWebSocketMessage authParametersWebSocketMessage;
} }

View File

@ -30,5 +30,5 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class HelloOverallWebSocketMessage extends BaseWebSocketMessage { public class HelloOverallWebSocketMessage extends BaseWebSocketMessage {
@JsonField(name = "hello") @JsonField(name = "hello")
HelloWebSocketMessage helloWebSocketMessage; public HelloWebSocketMessage helloWebSocketMessage;
} }

View File

@ -30,11 +30,11 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class HelloWebSocketMessage { public class HelloWebSocketMessage {
@JsonField(name = "version") @JsonField(name = "version")
String version; public String version;
@JsonField(name = "resumeid") @JsonField(name = "resumeid")
String resumeid; public String resumeid;
@JsonField(name = "auth") @JsonField(name = "auth")
AuthWebSocketMessage authWebSocketMessage; public AuthWebSocketMessage authWebSocketMessage;
} }

View File

@ -30,5 +30,5 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class RequestOfferOverallWebSocketMessage extends BaseWebSocketMessage { public class RequestOfferOverallWebSocketMessage extends BaseWebSocketMessage {
@JsonField(name = "message") @JsonField(name = "message")
RequestOfferSignalingMessage requestOfferOverallWebSocketMessage; public RequestOfferSignalingMessage requestOfferOverallWebSocketMessage;
} }

View File

@ -30,8 +30,8 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class RequestOfferSignalingMessage { public class RequestOfferSignalingMessage {
@JsonField(name = "recipient") @JsonField(name = "recipient")
ActorWebSocketMessage actorWebSocketMessage; public ActorWebSocketMessage actorWebSocketMessage;
@JsonField(name = "data") @JsonField(name = "data")
SignalingDataWebSocketMessageForOffer signalingDataWebSocketMessageForOffer; public SignalingDataWebSocketMessageForOffer signalingDataWebSocketMessageForOffer;
} }

View File

@ -30,5 +30,5 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class RoomOverallWebSocketMessage extends BaseWebSocketMessage { public class RoomOverallWebSocketMessage extends BaseWebSocketMessage {
@JsonField(name = "room") @JsonField(name = "room")
RoomWebSocketMessage roomWebSocketMessage; public RoomWebSocketMessage roomWebSocketMessage;
} }

View File

@ -30,8 +30,8 @@ import org.parceler.Parcel;
@Parcel @Parcel
public class SignalingDataWebSocketMessageForOffer { public class SignalingDataWebSocketMessageForOffer {
@JsonField(name = "type") @JsonField(name = "type")
String type; public String type;
@JsonField(name = "roomType") @JsonField(name = "roomType")
String roomType; public String roomType;
} }

View File

@ -64,7 +64,7 @@ class ConversationsListViewModel constructor(
val searchQuery = MutableLiveData<String>() val searchQuery = MutableLiveData<String>()
val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData() val currentUserLiveData: LiveData<UserNgEntity> = usersRepository.getActiveUserLiveData()
val conversationsLiveData = Transformations.switchMap(currentUserLiveData) { val conversationsLiveData = Transformations.switchMap(currentUserLiveData) {
if (!LOADING.equals(viewState.value)) { if (LOADING != viewState.value) {
viewState.value = LOADING viewState.value = LOADING
} }
conversationsRepository.getConversationsForUser(it.id) conversationsRepository.getConversationsForUser(it.id)
@ -192,8 +192,7 @@ class ConversationsListViewModel constructor(
// TODO, make sure we ask for password if needed // TODO, make sure we ask for password if needed
putExtra( putExtra(
Intent.EXTRA_TEXT, ShareUtils.getStringForIntent( Intent.EXTRA_TEXT, ShareUtils.getStringForIntent(
context, null, context, null, conversation
userUtils, conversation
) )
) )

View File

@ -21,7 +21,6 @@
package com.nextcloud.talk.newarch.utils package com.nextcloud.talk.newarch.utils
import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
fun UserEntity.getCredentials() = ApiUtils.getCredentials(username, token) fun UserEntity.getCredentials() = ApiUtils.getCredentials(username, token)

View File

@ -1,159 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.presenters;
import android.content.Context;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import autodagger.AutoInjector;
import com.nextcloud.talk.adapters.items.MentionAutocompleteItem;
import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.mention.Mention;
import com.nextcloud.talk.models.json.mention.MentionOverall;
import com.nextcloud.talk.utils.ApiUtils;
import com.nextcloud.talk.utils.database.user.UserUtils;
import com.otaliastudios.autocomplete.RecyclerViewPresenter;
import eu.davidea.flexibleadapter.FlexibleAdapter;
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@AutoInjector(NextcloudTalkApplication.class)
public class MentionAutocompletePresenter extends RecyclerViewPresenter<Mention>
implements FlexibleAdapter.OnItemClickListener {
@Inject
NcApi ncApi;
@Inject
UserUtils userUtils;
private UserEntity currentUser;
private FlexibleAdapter<AbstractFlexibleItem> adapter;
private Context context;
private String roomToken;
private List<AbstractFlexibleItem> abstractFlexibleItemList = new ArrayList<>();
public MentionAutocompletePresenter(Context context) {
super(context);
this.context = context;
NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication()
.inject(this);
currentUser = userUtils.getCurrentUser();
}
public MentionAutocompletePresenter(Context context, String roomToken) {
super(context);
this.roomToken = roomToken;
this.context = context;
NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication()
.inject(this);
currentUser = userUtils.getCurrentUser();
}
@Override
protected RecyclerView.Adapter instantiateAdapter() {
adapter = new FlexibleAdapter<>(abstractFlexibleItemList, context, false);
adapter.addListener(this);
return adapter;
}
@Override
protected void onQuery(@Nullable CharSequence query) {
String queryString;
if (query != null && query.length() > 1) {
queryString = String.valueOf(query.subSequence(1, query.length()));
} else {
queryString = "";
}
adapter.setFilter(queryString);
ncApi.getMentionAutocompleteSuggestions(
ApiUtils.getCredentials(currentUser.getUsername(), currentUser
.getToken()), ApiUtils.getUrlForMentionSuggestions(currentUser.getBaseUrl(), roomToken),
queryString, 5)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry(3)
.subscribe(new Observer<MentionOverall>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(MentionOverall mentionOverall) {
List<Mention> mentionsList = mentionOverall.getOcs().getData();
if (mentionsList.size() == 0) {
adapter.clear();
} else {
List<AbstractFlexibleItem> internalAbstractFlexibleItemList = new ArrayList<>();
for (Mention mention : mentionsList) {
internalAbstractFlexibleItemList.add(
new MentionAutocompleteItem(mention.getId(),
mention.getLabel(), mention.getSource(),
currentUser));
}
if (adapter.getItemCount() != 0) {
adapter.clear();
}
adapter.updateDataSet(internalAbstractFlexibleItemList);
}
}
@Override
public void onError(Throwable e) {
adapter.clear();
}
@Override
public void onComplete() {
}
});
}
@Override
public boolean onItemClick(View view, int position) {
Mention mention = new Mention();
MentionAutocompleteItem mentionAutocompleteItem =
(MentionAutocompleteItem) adapter.getItem(position);
if (mentionAutocompleteItem != null) {
mention.setId(mentionAutocompleteItem.getObjectId());
mention.setLabel(mentionAutocompleteItem.getDisplayName());
mention.setSource(mentionAutocompleteItem.getSource());
dispatchClick(mention);
}
return true;
}
}

View File

@ -0,0 +1,136 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.presenters
import android.content.Context
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import autodagger.AutoInjector
import com.nextcloud.talk.adapters.items.MentionAutocompleteItem
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.models.json.mention.Mention
import com.nextcloud.talk.models.json.mention.MentionOverall
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.local.models.getCredentials
import com.nextcloud.talk.utils.ApiUtils
import com.otaliastudios.autocomplete.RecyclerViewPresenter
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.koin.core.KoinComponent
import org.koin.core.inject
import java.util.*
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class MentionAutocompletePresenter : RecyclerViewPresenter<Mention?>, FlexibleAdapter.OnItemClickListener, KoinComponent {
@JvmField @Inject
var ncApi: NcApi? = null
val usersRepository: UsersRepository by inject()
private var currentUser: UserNgEntity?
private var adapter: FlexibleAdapter<AbstractFlexibleItem<*>>? = null
private var internalContext: Context
private var roomToken: String? = null
private val abstractFlexibleItemList: List<AbstractFlexibleItem<*>> = ArrayList()
constructor(context: Context) : super(context) {
this.internalContext = context
sharedApplication
?.componentApplication
?.inject(this)
currentUser = usersRepository.getActiveUser()
}
constructor(context: Context, roomToken: String?) : super(context) {
this.roomToken = roomToken
this.internalContext = context
sharedApplication
?.componentApplication
?.inject(this)
currentUser = usersRepository.getActiveUser()
}
override fun instantiateAdapter(): RecyclerView.Adapter<*> {
adapter = FlexibleAdapter(abstractFlexibleItemList, context, false)
adapter!!.addListener(this)
return adapter!!
}
override fun onQuery(query: CharSequence?) {
val queryString: String
queryString = if (query != null && query.length > 1) {
query.subSequence(1, query.length).toString()
} else {
""
}
adapter!!.setFilter(queryString)
ncApi!!.getMentionAutocompleteSuggestions(
currentUser!!.getCredentials(), ApiUtils.getUrlForMentionSuggestions(currentUser!!.baseUrl, roomToken),
queryString, 5)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry(3)
.subscribe(object : io.reactivex.Observer<MentionOverall> {
override fun onSubscribe(d: Disposable) {}
override fun onNext(mentionOverall: MentionOverall) {
val mentionsList: List<Mention> = mentionOverall.ocs.data
if (mentionsList.isEmpty()) {
adapter!!.clear()
} else {
val internalAbstractFlexibleItemList: MutableList<AbstractFlexibleItem<*>> = ArrayList()
for (mention in mentionsList) {
internalAbstractFlexibleItemList.add(
MentionAutocompleteItem(mention.id,
mention.label, mention.source,
currentUser!!))
}
if (adapter!!.itemCount != 0) {
adapter!!.clear()
}
adapter!!.updateDataSet(internalAbstractFlexibleItemList)
}
}
override fun onError(e: Throwable) {
adapter!!.clear()
}
override fun onComplete() {}
})
}
override fun onItemClick(view: View, position: Int): Boolean {
val mention = Mention()
val mentionAutocompleteItem = adapter!!.getItem(position) as MentionAutocompleteItem?
if (mentionAutocompleteItem != null) {
mention.id = mentionAutocompleteItem.objectId
mention.label = mentionAutocompleteItem.displayName
mention.source = mentionAutocompleteItem.source
dispatchClick(mention)
}
return true
}
}

View File

@ -1,51 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.nextcloud.talk.utils;
import android.content.Context;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import com.nextcloud.talk.R;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.conversations.Conversation;
import com.nextcloud.talk.utils.database.user.UserUtils;
public class ShareUtils {
public static String getStringForIntent(Context context, @Nullable String password,
UserUtils userUtils, Conversation conversation) {
UserEntity userEntity = userUtils.getCurrentUser();
String shareString = "";
if (userEntity != null && context != null) {
shareString = String.format(context.getResources().getString(R.string.nc_share_text),
userEntity.getBaseUrl(), conversation.getToken());
if (!TextUtils.isEmpty(password)) {
shareString +=
String.format(context.getResources().getString(R.string.nc_share_text_pass), password);
}
}
return shareString;
}
}

View File

@ -0,0 +1,48 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.nextcloud.talk.utils
import android.content.Context
import android.text.TextUtils
import com.nextcloud.talk.R
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import org.koin.core.KoinComponent
import org.koin.core.inject
object ShareUtils: KoinComponent {
val usersRepository: UsersRepository by inject()
@JvmStatic
fun getStringForIntent(context: Context?, password: String?, conversation: Conversation): String {
val userEntity: UserNgEntity? = usersRepository.getActiveUser()
var shareString = ""
if (userEntity != null && context != null) {
shareString = java.lang.String.format(context.resources.getString(R.string.nc_share_text),
userEntity.baseUrl, conversation.token)
if (!TextUtils.isEmpty(password)) {
shareString += String.format(context.resources.getString(R.string.nc_share_text_pass), password)
}
}
return shareString
}
}

View File

@ -1,184 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.webrtc;
import autodagger.AutoInjector;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.signaling.NCMessageWrapper;
import com.nextcloud.talk.models.json.websocket.ActorWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.AuthParametersWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.AuthWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.CallOverallWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.CallWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.HelloOverallWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.HelloWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.RequestOfferOverallWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.RequestOfferSignalingMessage;
import com.nextcloud.talk.models.json.websocket.RoomOverallWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.RoomWebSocketMessage;
import com.nextcloud.talk.models.json.websocket.SignalingDataWebSocketMessageForOffer;
import com.nextcloud.talk.newarch.local.models.UserNgEntity;
import com.nextcloud.talk.utils.ApiUtils;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import okhttp3.OkHttpClient;
@AutoInjector(NextcloudTalkApplication.class)
public class WebSocketConnectionHelper {
private static Map<Long, MagicWebSocketInstance> magicWebSocketInstanceMap = new HashMap<>();
@Inject
OkHttpClient okHttpClient;
public WebSocketConnectionHelper() {
NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication()
.inject(this);
}
public static synchronized MagicWebSocketInstance getMagicWebSocketInstanceForUserId(
long userId) {
if (userId != -1 && magicWebSocketInstanceMap.containsKey(userId)) {
return magicWebSocketInstanceMap.get(userId);
}
return null;
}
public static synchronized MagicWebSocketInstance getExternalSignalingInstanceForServer(
String url, UserNgEntity userEntity, String webSocketTicket, boolean isGuest) {
String generatedURL = url.replace("https://", "wss://").replace("http://", "ws://");
if (generatedURL.endsWith("/")) {
generatedURL += "spreed";
} else {
generatedURL += "/spreed";
}
long userId = isGuest ? -1 : userEntity.getId();
MagicWebSocketInstance magicWebSocketInstance;
if (userId != -1
&& magicWebSocketInstanceMap.containsKey(userEntity.getId())
&& (magicWebSocketInstance = magicWebSocketInstanceMap.get(userEntity.getId())) != null) {
return magicWebSocketInstance;
} else {
if (userId == -1) {
deleteExternalSignalingInstanceForUserEntity(userId);
}
magicWebSocketInstance =
new MagicWebSocketInstance(userEntity, generatedURL, webSocketTicket);
magicWebSocketInstanceMap.put(userEntity.getId(), magicWebSocketInstance);
return magicWebSocketInstance;
}
}
public static synchronized void deleteExternalSignalingInstanceForUserEntity(long id) {
MagicWebSocketInstance magicWebSocketInstance;
if ((magicWebSocketInstance = magicWebSocketInstanceMap.get(id)) != null) {
if (magicWebSocketInstance.isConnected()) {
magicWebSocketInstance.sendBye();
magicWebSocketInstanceMap.remove(id);
}
}
}
HelloOverallWebSocketMessage getAssembledHelloModel(UserNgEntity userEntity, String ticket) {
HelloOverallWebSocketMessage helloOverallWebSocketMessage = new HelloOverallWebSocketMessage();
helloOverallWebSocketMessage.setType("hello");
HelloWebSocketMessage helloWebSocketMessage = new HelloWebSocketMessage();
helloWebSocketMessage.setVersion("1.0");
AuthWebSocketMessage authWebSocketMessage = new AuthWebSocketMessage();
authWebSocketMessage.setUrl(
ApiUtils.getUrlForExternalServerAuthBackend(userEntity.getBaseUrl()));
AuthParametersWebSocketMessage authParametersWebSocketMessage =
new AuthParametersWebSocketMessage();
authParametersWebSocketMessage.setTicket(ticket);
authParametersWebSocketMessage.setUserid(userEntity.getUserId());
authWebSocketMessage.setAuthParametersWebSocketMessage(authParametersWebSocketMessage);
helloWebSocketMessage.setAuthWebSocketMessage(authWebSocketMessage);
helloOverallWebSocketMessage.setHelloWebSocketMessage(helloWebSocketMessage);
return helloOverallWebSocketMessage;
}
HelloOverallWebSocketMessage getAssembledHelloModelForResume(String resumeId) {
HelloOverallWebSocketMessage helloOverallWebSocketMessage = new HelloOverallWebSocketMessage();
helloOverallWebSocketMessage.setType("hello");
HelloWebSocketMessage helloWebSocketMessage = new HelloWebSocketMessage();
helloWebSocketMessage.setVersion("1.0");
helloWebSocketMessage.setResumeid(resumeId);
helloOverallWebSocketMessage.setHelloWebSocketMessage(helloWebSocketMessage);
return helloOverallWebSocketMessage;
}
RoomOverallWebSocketMessage getAssembledJoinOrLeaveRoomModel(String roomId, String sessionId) {
RoomOverallWebSocketMessage roomOverallWebSocketMessage = new RoomOverallWebSocketMessage();
roomOverallWebSocketMessage.setType("room");
RoomWebSocketMessage roomWebSocketMessage = new RoomWebSocketMessage();
roomWebSocketMessage.setRoomId(roomId);
roomWebSocketMessage.setSessiondId(sessionId);
roomOverallWebSocketMessage.setRoomWebSocketMessage(roomWebSocketMessage);
return roomOverallWebSocketMessage;
}
RequestOfferOverallWebSocketMessage getAssembledRequestOfferModel(String sessionId,
String roomType) {
RequestOfferOverallWebSocketMessage requestOfferOverallWebSocketMessage =
new RequestOfferOverallWebSocketMessage();
requestOfferOverallWebSocketMessage.setType("message");
RequestOfferSignalingMessage requestOfferSignalingMessage = new RequestOfferSignalingMessage();
ActorWebSocketMessage actorWebSocketMessage = new ActorWebSocketMessage();
actorWebSocketMessage.setType("session");
actorWebSocketMessage.setSessionId(sessionId);
requestOfferSignalingMessage.setActorWebSocketMessage(actorWebSocketMessage);
SignalingDataWebSocketMessageForOffer signalingDataWebSocketMessageForOffer =
new SignalingDataWebSocketMessageForOffer();
signalingDataWebSocketMessageForOffer.setRoomType(roomType);
signalingDataWebSocketMessageForOffer.setType("requestoffer");
requestOfferSignalingMessage.setSignalingDataWebSocketMessageForOffer(
signalingDataWebSocketMessageForOffer);
requestOfferOverallWebSocketMessage.setRequestOfferOverallWebSocketMessage(
requestOfferSignalingMessage);
return requestOfferOverallWebSocketMessage;
}
CallOverallWebSocketMessage getAssembledCallMessageModel(NCMessageWrapper ncMessageWrapper) {
CallOverallWebSocketMessage callOverallWebSocketMessage = new CallOverallWebSocketMessage();
callOverallWebSocketMessage.setType("message");
CallWebSocketMessage callWebSocketMessage = new CallWebSocketMessage();
ActorWebSocketMessage actorWebSocketMessage = new ActorWebSocketMessage();
actorWebSocketMessage.setType("session");
actorWebSocketMessage.setSessionId(ncMessageWrapper.getSignalingMessage().getTo());
callWebSocketMessage.setRecipientWebSocketMessage(actorWebSocketMessage);
callWebSocketMessage.setNcSignalingMessage(ncMessageWrapper.getSignalingMessage());
callOverallWebSocketMessage.setCallWebSocketMessage(callWebSocketMessage);
return callOverallWebSocketMessage;
}
}

View File

@ -0,0 +1,148 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.webrtc
import com.nextcloud.talk.models.json.signaling.NCMessageWrapper
import com.nextcloud.talk.models.json.websocket.*
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.utils.ApiUtils
import okhttp3.OkHttpClient
import org.koin.core.KoinComponent
import org.koin.core.inject
import java.util.*
class WebSocketConnectionHelper: KoinComponent {
val okHttpClient: OkHttpClient by inject()
fun getAssembledHelloModel(userEntity: UserNgEntity, ticket: String?): HelloOverallWebSocketMessage {
val helloOverallWebSocketMessage = HelloOverallWebSocketMessage()
helloOverallWebSocketMessage.type = "hello"
val helloWebSocketMessage = HelloWebSocketMessage()
helloWebSocketMessage.version = "1.0"
val authWebSocketMessage = AuthWebSocketMessage()
authWebSocketMessage.url =
ApiUtils.getUrlForExternalServerAuthBackend(userEntity.baseUrl)
val authParametersWebSocketMessage = AuthParametersWebSocketMessage()
authParametersWebSocketMessage.ticket = ticket
authParametersWebSocketMessage.userid = userEntity.userId
authWebSocketMessage.authParametersWebSocketMessage = authParametersWebSocketMessage
helloWebSocketMessage.authWebSocketMessage = authWebSocketMessage
helloOverallWebSocketMessage.helloWebSocketMessage = helloWebSocketMessage
return helloOverallWebSocketMessage
}
fun getAssembledHelloModelForResume(resumeId: String?): HelloOverallWebSocketMessage {
val helloOverallWebSocketMessage = HelloOverallWebSocketMessage()
helloOverallWebSocketMessage.type = "hello"
val helloWebSocketMessage = HelloWebSocketMessage()
helloWebSocketMessage.version = "1.0"
helloWebSocketMessage.resumeid = resumeId
helloOverallWebSocketMessage.helloWebSocketMessage = helloWebSocketMessage
return helloOverallWebSocketMessage
}
fun getAssembledJoinOrLeaveRoomModel(roomId: String?, sessionId: String?): RoomOverallWebSocketMessage {
val roomOverallWebSocketMessage = RoomOverallWebSocketMessage()
roomOverallWebSocketMessage.type = "room"
val roomWebSocketMessage = RoomWebSocketMessage()
roomWebSocketMessage.roomId = roomId
roomWebSocketMessage.sessiondId = sessionId
roomOverallWebSocketMessage.roomWebSocketMessage = roomWebSocketMessage
return roomOverallWebSocketMessage
}
fun getAssembledRequestOfferModel(sessionId: String?,
roomType: String?): RequestOfferOverallWebSocketMessage {
val requestOfferOverallWebSocketMessage = RequestOfferOverallWebSocketMessage()
requestOfferOverallWebSocketMessage.type = "message"
val requestOfferSignalingMessage = RequestOfferSignalingMessage()
val actorWebSocketMessage = ActorWebSocketMessage()
actorWebSocketMessage.type = "session"
actorWebSocketMessage.sessionId = sessionId
requestOfferSignalingMessage.actorWebSocketMessage = actorWebSocketMessage
val signalingDataWebSocketMessageForOffer = SignalingDataWebSocketMessageForOffer()
signalingDataWebSocketMessageForOffer.roomType = roomType
signalingDataWebSocketMessageForOffer.type = "requestoffer"
requestOfferSignalingMessage.signalingDataWebSocketMessageForOffer =
signalingDataWebSocketMessageForOffer
requestOfferOverallWebSocketMessage.requestOfferOverallWebSocketMessage =
requestOfferSignalingMessage
return requestOfferOverallWebSocketMessage
}
fun getAssembledCallMessageModel(ncMessageWrapper: NCMessageWrapper): CallOverallWebSocketMessage {
val callOverallWebSocketMessage = CallOverallWebSocketMessage()
callOverallWebSocketMessage.type = "message"
val callWebSocketMessage = CallWebSocketMessage()
val actorWebSocketMessage = ActorWebSocketMessage()
actorWebSocketMessage.type = "session"
actorWebSocketMessage.sessionId = ncMessageWrapper.signalingMessage.to
callWebSocketMessage.recipientWebSocketMessage = actorWebSocketMessage
callWebSocketMessage.ncSignalingMessage = ncMessageWrapper.signalingMessage
callOverallWebSocketMessage.callWebSocketMessage = callWebSocketMessage
return callOverallWebSocketMessage
}
companion object {
private val magicWebSocketInstanceMap: MutableMap<Long, MagicWebSocketInstance> = HashMap()
@Synchronized
fun getMagicWebSocketInstanceForUserId(
userId: Long): MagicWebSocketInstance? {
return if (userId != -1L && magicWebSocketInstanceMap.containsKey(userId)) {
magicWebSocketInstanceMap[userId]
} else null
}
@Synchronized
fun getExternalSignalingInstanceForServer(
url: String, userEntity: UserNgEntity, webSocketTicket: String?, isGuest: Boolean): MagicWebSocketInstance? {
var generatedURL = url.replace("https://", "wss://").replace("http://", "ws://")
generatedURL += if (generatedURL.endsWith("/")) {
"spreed"
} else {
"/spreed"
}
val userId = if (isGuest) -1 else userEntity.id
var magicWebSocketInstance: MagicWebSocketInstance
if (userId != -1L && magicWebSocketInstanceMap.containsKey(userEntity.id)) {
return magicWebSocketInstanceMap[userEntity.id] as MagicWebSocketInstance
} else {
if (userId == -1L) {
deleteExternalSignalingInstanceForUserEntity(userId)
}
magicWebSocketInstance = MagicWebSocketInstance(userEntity, generatedURL, webSocketTicket!!)
magicWebSocketInstanceMap[userEntity.id] = magicWebSocketInstance
return magicWebSocketInstance
}
}
@JvmStatic
@Synchronized
fun deleteExternalSignalingInstanceForUserEntity(id: Long) {
var magicWebSocketInstance: MagicWebSocketInstance
if (magicWebSocketInstanceMap[id].also { magicWebSocketInstance = it!! } != null) {
if (magicWebSocketInstance.isConnected) {
magicWebSocketInstance.sendBye()
magicWebSocketInstanceMap.remove(id)
}
}
}
}
}

View File

@ -22,7 +22,7 @@
buildscript { buildscript {
ext { ext {
kotlin_version = '1.3.50' kotlin_version = '1.3.61'
} }
repositories { repositories {
@ -33,9 +33,8 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.2' classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}"
classpath "io.realm:realm-gradle-plugin:6.0.0"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
@ -44,7 +43,7 @@ buildscript {
configurations.all { configurations.all {
// check for updates every build // check for updates every build
resolutionStrategy.cacheChangingModulesFor 3600, 'seconds' //resolutionStrategy.cacheChangingModulesFor 3600, 'seconds'
} }
allprojects { allprojects {

View File

@ -29,7 +29,7 @@
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=2048m
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true