From 01b760f97e951be1dc5e2c076022fbd90665c7dd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 4 May 2021 09:39:08 +0200 Subject: [PATCH 1/7] Add a warning when the server version is (almost) EOL Signed-off-by: Joas Schilling --- .../talk/controllers/SettingsController.java | 14 ++++++++++++++ app/src/main/res/layout/controller_settings.xml | 14 ++++++++++++-- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 4 ++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java index 12e9fb678..bf85b1a88 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java @@ -144,6 +144,8 @@ public class SettingsController extends BaseController { EmojiTextView displayNameTextView; @BindView(R.id.base_url_text) TextView baseUrlTextView; + @BindView(R.id.server_age_warning_text) + TextView serverAgeTextView; @BindView(R.id.settings_call_sound) MaterialStandardPreference settingsCallSound; @BindView(R.id.settings_message_sound) @@ -551,6 +553,18 @@ public class SettingsController extends BaseController { baseUrlTextView.setText(Uri.parse(currentUser.getBaseUrl()).getHost()); + if (!currentUser.hasSpreedFeatureCapability("no-ping")) { + // Talk 4+ + serverAgeTextView.setTextColor(getResources().getColor(R.color.nc_darkRed)); + serverAgeTextView.setText(R.string.nc_settings_server_eol); + } else if (!currentUser.hasSpreedFeatureCapability("chat-replies")) { + // Talk 8+ + serverAgeTextView.setTextColor(getResources().getColor(R.color.nc_darkYellow)); + serverAgeTextView.setText(R.string.nc_settings_server_almost_eol); + } else { + serverAgeTextView.setVisibility(View.GONE); + } + reauthorizeButton.addPreferenceClickListener(view14 -> { getRouter().pushController(RouterTransaction.with( new WebViewLoginController(currentUser.getBaseUrl(), true)) diff --git a/app/src/main/res/layout/controller_settings.xml b/app/src/main/res/layout/controller_settings.xml index f49e4492a..fe23dbf78 100644 --- a/app/src/main/res/layout/controller_settings.xml +++ b/app/src/main/res/layout/controller_settings.xml @@ -71,7 +71,17 @@ android:layout_centerHorizontal="true" android:layout_margin="4dp" android:textColor="@color/medium_emphasis_text" - tools:text="jane@nextcloud.com" /> + tools:text="nextcloud.com" /> + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f847fe189..c1ad8456c 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -50,6 +50,7 @@ #222222 #D32F2F + #FF9800 #006400 #E8E8E8 #757575 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index edfb50d7a..f6daad2d0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,6 +85,10 @@ Please confirm your intent to remove the current account. Remove account Add a new account + The server version is too old and not supported by this version of the + Android app + The server version is very old and will not be supported in the next + release! Add Only current account can be reauthorized Talk app is not installed on the server you tried to authenticate against From 37dc7d1df02ada180bb0aa7301ac4dcdd477be7d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 4 May 2021 10:05:40 +0200 Subject: [PATCH 2/7] Add a warning on the conversations list as well Signed-off-by: Joas Schilling --- .../ConversationsListController.java | 39 +++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 2 files changed, 40 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index 95b7e665d..de9c9b43b 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -270,6 +270,45 @@ public class ConversationsListController extends BaseController implements Searc currentUser = userUtils.getCurrentUser(); if (currentUser != null) { + if (!currentUser.hasSpreedFeatureCapability("no-ping")) { + // Talk 4+ + new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) + .setTopColorRes(R.color.nc_darkRed) + .setIcon(DisplayUtils.getTintedDrawable(context.getResources(), + R.drawable.ic_timer_black_24dp, R.color.bg_default)) + .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed)) + .setCancelable(false) + .setTitle(R.string.nc_settings_server_eol_title) + .setMessage(R.string.nc_settings_server_eol) + .setPositiveButton(R.string.nc_settings_remove_account, new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId()); + + OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build(); + WorkManager.getInstance().enqueue(accountRemovalWork); + + if (otherUserExists && getView() != null) { + onViewBound(getView()); + onAttach(getView()); + } else if (!otherUserExists) { + getRouter().setRoot(RouterTransaction.with( + new ServerSelectionController()) + .pushChangeHandler(new VerticalChangeHandler()) + .popChangeHandler(new VerticalChangeHandler())); + } + } + }) + .setNegativeButton(R.string.nc_cancel, new View.OnClickListener() { + @Override + public void onClick(View v) { + getRouter().pushController(RouterTransaction.with(new SwitchAccountController())); + } + }) + .setInstanceStateHandler(ID_DELETE_CONVERSATION_DIALOG, saveStateHandler) + .show(); + } + credentials = ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()); shouldUseLastMessageLayout = currentUser.hasSpreedFeatureCapability("last-room-activity"); if (getActivity() != null && getActivity() instanceof MainActivity) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6daad2d0..aa79b6cbf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,6 +85,7 @@ Please confirm your intent to remove the current account. Remove account Add a new account + Unsupported server The server version is too old and not supported by this version of the Android app The server version is very old and will not be supported in the next From 1f8905394e5bd1cb190e57e16bda9f2797d63ec8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 4 May 2021 10:09:08 +0200 Subject: [PATCH 3/7] Add dedicated methods for the EOL version checks Signed-off-by: Joas Schilling --- .../talk/controllers/ConversationsListController.java | 3 +-- .../nextcloud/talk/controllers/SettingsController.java | 6 ++---- .../java/com/nextcloud/talk/models/database/User.java | 10 ++++++++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index de9c9b43b..9a6fefeae 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -270,8 +270,7 @@ public class ConversationsListController extends BaseController implements Searc currentUser = userUtils.getCurrentUser(); if (currentUser != null) { - if (!currentUser.hasSpreedFeatureCapability("no-ping")) { - // Talk 4+ + if (currentUser.isServerEOL()) { new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) .setTopColorRes(R.color.nc_darkRed) .setIcon(DisplayUtils.getTintedDrawable(context.getResources(), diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java index bf85b1a88..b8f44629e 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java @@ -553,12 +553,10 @@ public class SettingsController extends BaseController { baseUrlTextView.setText(Uri.parse(currentUser.getBaseUrl()).getHost()); - if (!currentUser.hasSpreedFeatureCapability("no-ping")) { - // Talk 4+ + if (currentUser.isServerEOL()) { serverAgeTextView.setTextColor(getResources().getColor(R.color.nc_darkRed)); serverAgeTextView.setText(R.string.nc_settings_server_eol); - } else if (!currentUser.hasSpreedFeatureCapability("chat-replies")) { - // Talk 8+ + } else if (currentUser.isServerAlmostEOL()) { serverAgeTextView.setTextColor(getResources().getColor(R.color.nc_darkYellow)); serverAgeTextView.setText(R.string.nc_settings_server_almost_eol); } else { diff --git a/app/src/main/java/com/nextcloud/talk/models/database/User.java b/app/src/main/java/com/nextcloud/talk/models/database/User.java index 1d02b0e9a..7e599f782 100644 --- a/app/src/main/java/com/nextcloud/talk/models/database/User.java +++ b/app/src/main/java/com/nextcloud/talk/models/database/User.java @@ -92,6 +92,16 @@ public interface User extends Parcelable, Persistable, Serializable { return false; } + default boolean isServerEOL() { + // Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018 + return !hasSpreedFeatureCapability("no-ping"); + } + + default boolean isServerAlmostEOL() { + // Capability is available since Talk 8 => Nextcloud 18 => January 2020 + return !hasSpreedFeatureCapability("chat-replies"); + } + default boolean hasSpreedFeatureCapability(String capabilityName) { if (getCapabilities() != null) { try { From c7891521220e85b91620403a7303914ad74324cc Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 5 May 2021 09:02:28 +0200 Subject: [PATCH 4/7] Exit the app when there is only this EOL account Signed-off-by: Joas Schilling --- .../talk/controllers/ConversationsListController.java | 7 ++++++- .../com/nextcloud/talk/utils/database/user/UserUtils.java | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index 9a6fefeae..a5b564c64 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -301,7 +301,12 @@ public class ConversationsListController extends BaseController implements Searc .setNegativeButton(R.string.nc_cancel, new View.OnClickListener() { @Override public void onClick(View v) { - getRouter().pushController(RouterTransaction.with(new SwitchAccountController())); + if (userUtils.hasMultipleUsers()) { + getRouter().pushController(RouterTransaction.with(new SwitchAccountController())); + } else { + getActivity().finishAffinity(); + getActivity().finish(); + } } }) .setInstanceStateHandler(ID_DELETE_CONVERSATION_DIALOG, saveStateHandler) diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java b/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java index 6871a740a..cf3458353 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/database/user/UserUtils.java @@ -48,6 +48,11 @@ public class UserUtils { .limit(1).get().value() > 0); } + public boolean hasMultipleUsers() { + return (dataStore.count(User.class).where(UserEntity.SCHEDULED_FOR_DELETION.notEqual(Boolean.TRUE)) + .get().value() > 1); + } + public List getUsers() { Result findUsersQueryResult = dataStore.select(User.class).where (UserEntity.SCHEDULED_FOR_DELETION.notEqual(true)).get(); From c368af6bab8ba8a988268bc71ba84b277e7d5f6e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 5 May 2021 09:18:59 +0200 Subject: [PATCH 5/7] Move dialog into a new function Signed-off-by: Joas Schilling --- .../ConversationsListController.java | 85 ++++++++++--------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index a5b564c64..900a6e2cd 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -271,46 +271,8 @@ public class ConversationsListController extends BaseController implements Searc if (currentUser != null) { if (currentUser.isServerEOL()) { - new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) - .setTopColorRes(R.color.nc_darkRed) - .setIcon(DisplayUtils.getTintedDrawable(context.getResources(), - R.drawable.ic_timer_black_24dp, R.color.bg_default)) - .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed)) - .setCancelable(false) - .setTitle(R.string.nc_settings_server_eol_title) - .setMessage(R.string.nc_settings_server_eol) - .setPositiveButton(R.string.nc_settings_remove_account, new View.OnClickListener() { - @Override - public void onClick(View v) { - boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId()); - - OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build(); - WorkManager.getInstance().enqueue(accountRemovalWork); - - if (otherUserExists && getView() != null) { - onViewBound(getView()); - onAttach(getView()); - } else if (!otherUserExists) { - getRouter().setRoot(RouterTransaction.with( - new ServerSelectionController()) - .pushChangeHandler(new VerticalChangeHandler()) - .popChangeHandler(new VerticalChangeHandler())); - } - } - }) - .setNegativeButton(R.string.nc_cancel, new View.OnClickListener() { - @Override - public void onClick(View v) { - if (userUtils.hasMultipleUsers()) { - getRouter().pushController(RouterTransaction.with(new SwitchAccountController())); - } else { - getActivity().finishAffinity(); - getActivity().finish(); - } - } - }) - .setInstanceStateHandler(ID_DELETE_CONVERSATION_DIALOG, saveStateHandler) - .show(); + showServerEOLDialog(); + return; } credentials = ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()); @@ -906,6 +868,49 @@ public class ConversationsListController extends BaseController implements Searc } } + private void showServerEOLDialog() { + new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) + .setTopColorRes(R.color.nc_darkRed) + .setIcon(DisplayUtils.getTintedDrawable(context.getResources(), + R.drawable.ic_timer_black_24dp, R.color.bg_default)) + .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed)) + .setCancelable(false) + .setTitle(R.string.nc_settings_server_eol_title) + .setMessage(R.string.nc_settings_server_eol) + .setPositiveButton(R.string.nc_settings_remove_account, new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean otherUserExists = userUtils.scheduleUserForDeletionWithId(currentUser.getId()); + + OneTimeWorkRequest accountRemovalWork = new OneTimeWorkRequest.Builder(AccountRemovalWorker.class).build(); + WorkManager.getInstance().enqueue(accountRemovalWork); + + if (otherUserExists && getView() != null) { + onViewBound(getView()); + onAttach(getView()); + } else if (!otherUserExists) { + getRouter().setRoot(RouterTransaction.with( + new ServerSelectionController()) + .pushChangeHandler(new VerticalChangeHandler()) + .popChangeHandler(new VerticalChangeHandler())); + } + } + }) + .setNegativeButton(R.string.nc_cancel, new View.OnClickListener() { + @Override + public void onClick(View v) { + if (userUtils.hasMultipleUsers()) { + getRouter().pushController(RouterTransaction.with(new SwitchAccountController())); + } else { + getActivity().finishAffinity(); + getActivity().finish(); + } + } + }) + .setInstanceStateHandler(ID_DELETE_CONVERSATION_DIALOG, saveStateHandler) + .show(); + } + private void deleteConversation(Data data) { OneTimeWorkRequest deleteConversationWorker = new OneTimeWorkRequest.Builder(DeleteConversationWorker.class).setInputData(data).build(); From 202d98d47806254c44b8bf8b816acb86c8925c23 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 5 May 2021 15:43:15 +0200 Subject: [PATCH 6/7] wrap warning in cardview and add warning icon for extra visual Signed-off-by: Andy Scherzinger --- .../ConversationsListController.java | 3 +- .../talk/controllers/SettingsController.java | 18 ++++++-- .../main/res/layout/controller_settings.xml | 45 +++++++++++++++---- app/src/main/res/values/strings.xml | 7 ++- 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index 900a6e2cd..2fb61a98e 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -872,7 +872,8 @@ public class ConversationsListController extends BaseController implements Searc new LovelyStandardDialog(getActivity(), LovelyStandardDialog.ButtonLayout.HORIZONTAL) .setTopColorRes(R.color.nc_darkRed) .setIcon(DisplayUtils.getTintedDrawable(context.getResources(), - R.drawable.ic_timer_black_24dp, R.color.bg_default)) + R.drawable.ic_warning_white, + R.color.bg_default)) .setPositiveButtonColor(context.getResources().getColor(R.color.nc_darkRed)) .setCancelable(false) .setTitle(R.string.nc_settings_server_eol_title) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java index b8f44629e..3af9b8cd8 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java @@ -29,6 +29,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.ColorStateList; +import android.graphics.PorterDuff; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -45,6 +46,7 @@ import android.view.WindowManager; import android.widget.Button; import android.widget.Checkable; import android.widget.EditText; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; @@ -56,6 +58,7 @@ import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler; import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler; import com.bluelinelabs.logansquare.LoganSquare; import com.facebook.drawee.view.SimpleDraweeView; +import com.google.android.material.card.MaterialCardView; import com.google.android.material.textfield.TextInputLayout; import com.nextcloud.talk.BuildConfig; import com.nextcloud.talk.R; @@ -103,6 +106,7 @@ import javax.inject.Inject; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import androidx.core.content.ContextCompat; import androidx.core.view.ViewCompat; import androidx.emoji.widget.EmojiTextView; import androidx.work.OneTimeWorkRequest; @@ -144,8 +148,12 @@ public class SettingsController extends BaseController { EmojiTextView displayNameTextView; @BindView(R.id.base_url_text) TextView baseUrlTextView; + @BindView(R.id.server_age_warning_text_card) + MaterialCardView serverAgeCardView; @BindView(R.id.server_age_warning_text) TextView serverAgeTextView; + @BindView(R.id.server_age_warning_icon) + ImageView serverAgeIcon; @BindView(R.id.settings_call_sound) MaterialStandardPreference settingsCallSound; @BindView(R.id.settings_message_sound) @@ -554,13 +562,17 @@ public class SettingsController extends BaseController { baseUrlTextView.setText(Uri.parse(currentUser.getBaseUrl()).getHost()); if (currentUser.isServerEOL()) { - serverAgeTextView.setTextColor(getResources().getColor(R.color.nc_darkRed)); + serverAgeTextView.setTextColor(ContextCompat.getColor(context, R.color.nc_darkRed)); serverAgeTextView.setText(R.string.nc_settings_server_eol); + serverAgeIcon.setColorFilter(ContextCompat.getColor(context, R.color.nc_darkRed), + PorterDuff.Mode.SRC_IN); } else if (currentUser.isServerAlmostEOL()) { - serverAgeTextView.setTextColor(getResources().getColor(R.color.nc_darkYellow)); + serverAgeTextView.setTextColor(ContextCompat.getColor(context, R.color.nc_darkYellow)); serverAgeTextView.setText(R.string.nc_settings_server_almost_eol); + serverAgeIcon.setColorFilter(ContextCompat.getColor(context, R.color.nc_darkYellow), + PorterDuff.Mode.SRC_IN); } else { - serverAgeTextView.setVisibility(View.GONE); + serverAgeCardView.setVisibility(View.GONE); } reauthorizeButton.addPreferenceClickListener(view14 -> { diff --git a/app/src/main/res/layout/controller_settings.xml b/app/src/main/res/layout/controller_settings.xml index fe23dbf78..d459ef2f0 100644 --- a/app/src/main/res/layout/controller_settings.xml +++ b/app/src/main/res/layout/controller_settings.xml @@ -22,6 +22,7 @@ - + app:cardCornerRadius="8dp" + app:cardElevation="2dp" + app:strokeWidth="0dp"> + + + + + + + + + + - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aa79b6cbf..54aa13108 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -86,10 +86,9 @@ Remove account Add a new account Unsupported server - The server version is too old and not supported by this version of the - Android app - The server version is very old and will not be supported in the next - release! + The server version is too old and not supported by this version of the Android app + The server version is very old and will not be supported in the next release! + Warning Add Only current account can be reauthorized Talk app is not installed on the server you tried to authenticate against From 98848ad72fa4b1b8ae8bdb38a2476c4cbb85685e Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Wed, 5 May 2021 15:54:59 +0200 Subject: [PATCH 7/7] bump lint score due to additional butterknife view bindings Signed-off-by: Andy Scherzinger --- scripts/analysis/lint-results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt index 83c84a5b9..21a6df58f 100644 --- a/scripts/analysis/lint-results.txt +++ b/scripts/analysis/lint-results.txt @@ -1,2 +1,2 @@ DO NOT TOUCH; GENERATED BY DRONE - Lint Report: 3 errors and 346 warnings + Lint Report: 3 errors and 348 warnings