Move first run and whats new to onboarding package

Signed-off-by: Chris Narkiewicz <hello@ezaquarii.com>
This commit is contained in:
Chris Narkiewicz 2019-05-19 11:07:39 +01:00
parent 2b36d693ee
commit b6fc62fb87
No known key found for this signature in database
GPG Key ID: 30D28CA4CCC665C6
19 changed files with 723 additions and 149 deletions

View File

@ -26,16 +26,21 @@ buildscript {
}
classpath 'gradle.plugin.com.github.spotbugs:spotbugs-gradle-plugin:1.6.6'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.0.0-RC14"
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'checkstyle'
apply plugin: 'pmd'
apply plugin: 'jacoco-android'
apply plugin: "com.github.spotbugs"
apply plugin: "io.gitlab.arturbosch.detekt"
configurations {
ktlint
@ -257,7 +262,8 @@ dependencies {
implementation 'commons-io:commons-io:2.6'
implementation 'com.github.tobiaskaminsky:android-job:v1.2.6.1' // 'com.github.evernote:android-job:v1.2.5'
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
kapt 'com.jakewharton:butterknife-compiler:10.1.0'
implementation 'org.greenrobot:eventbus:3.1.1'
implementation 'com.googlecode.ez-vcard:ez-vcard:0.10.5'
implementation 'org.lukhnos:nnio:0.2'
@ -280,12 +286,12 @@ dependencies {
spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0'
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.5'
implementation 'com.google.dagger:dagger:2.23.1'
implementation 'com.google.dagger:dagger-android:2.23.1'
implementation 'com.google.dagger:dagger-android-support:2.23.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.23.1'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.23.1'
kapt 'com.google.dagger:dagger-compiler:2.23.1'
kapt 'com.google.dagger:dagger-android-processor:2.23.1'
compileOnly "org.projectlombok:lombok:1.18.8"
annotationProcessor "org.projectlombok:lombok:1.18.8"
@ -368,7 +374,7 @@ task ktlint(type: JavaExec, group: "verification") {
description = "Check Kotlin code style."
main = "com.pinterest.ktlint.Main"
classpath = configurations.ktlint
args "--reporter=plain,output=${buildDir}/ktlint.txt,src/**/*.kt"
args "--reporter=plain", "--reporter=plain,output=${buildDir}/ktlint.txt,src/**/*.kt"
}
task ktlintFormat(type: JavaExec, group: "formatting") {
@ -377,3 +383,13 @@ task ktlintFormat(type: JavaExec, group: "formatting") {
classpath = configurations.ktlint
args "-F", "src/**/*.kt"
}
detekt {
reports {
xml {
enabled = false
}
}
config = files("detekt.yml")
input = files("src/")
}

523
detekt.yml Normal file
View File

@ -0,0 +1,523 @@
autoCorrect: true
test-pattern: # Configure exclusions for test sources
active: true
patterns: # Test file regexes
- '.*/test/.*'
- '.*/androidTest/.*'
- '.*Test.kt'
- '.*Spec.kt'
- '.*Spek.kt'
exclude-rule-sets:
- 'comments'
exclude-rules:
- 'NamingRules'
- 'WildcardImport'
- 'MagicNumber'
- 'MaxLineLength'
- 'LateinitUsage'
- 'StringLiteralDuplication'
- 'SpreadOperator'
- 'TooManyFunctions'
- 'ForEachOnRange'
- 'FunctionMaxLength'
- 'TooGenericExceptionCaught'
- 'InstanceOfCheckForException'
build:
maxIssues: 10
weights:
# complexity: 2
# LongParameterList: 1
# style: 1
# comments: 1
processors:
active: true
exclude:
# - 'FunctionCountProcessor'
# - 'PropertyCountProcessor'
# - 'ClassCountProcessor'
# - 'PackageCountProcessor'
# - 'KtFileCountProcessor'
console-reports:
active: true
exclude:
# - 'ProjectStatisticsReport'
# - 'ComplexityReport'
# - 'NotificationReport'
# - 'FindingsReport'
# - 'BuildFailureReport'
comments:
active: true
CommentOverPrivateFunction:
active: false
CommentOverPrivateProperty:
active: false
EndOfSentenceFormat:
active: false
endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!]$)
UndocumentedPublicClass:
active: false
searchInNestedClass: true
searchInInnerClass: true
searchInInnerObject: true
searchInInnerInterface: true
UndocumentedPublicFunction:
active: false
complexity:
active: true
ComplexCondition:
active: true
threshold: 4
ComplexInterface:
active: false
threshold: 10
includeStaticDeclarations: false
ComplexMethod:
active: true
threshold: 10
ignoreSingleWhenExpression: false
ignoreSimpleWhenEntries: false
LabeledExpression:
active: false
ignoredLabels: ""
LargeClass:
active: true
threshold: 600
LongMethod:
active: true
threshold: 60
LongParameterList:
active: true
threshold: 6
ignoreDefaultParameters: false
MethodOverloading:
active: false
threshold: 6
NestedBlockDepth:
active: true
threshold: 4
StringLiteralDuplication:
active: false
threshold: 3
ignoreAnnotation: true
excludeStringsWithLessThan5Characters: true
ignoreStringsRegex: '$^'
TooManyFunctions:
active: true
thresholdInFiles: 11
thresholdInClasses: 11
thresholdInInterfaces: 11
thresholdInObjects: 11
thresholdInEnums: 11
ignoreDeprecated: false
ignorePrivate: false
ignoreOverridden: false
empty-blocks:
active: true
EmptyCatchBlock:
active: true
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
EmptyClassBlock:
active: true
EmptyDefaultConstructor:
active: true
EmptyDoWhileBlock:
active: true
EmptyElseBlock:
active: true
EmptyFinallyBlock:
active: true
EmptyForBlock:
active: true
EmptyFunctionBlock:
active: true
ignoreOverriddenFunctions: false
EmptyIfBlock:
active: true
EmptyInitBlock:
active: true
EmptyKtFile:
active: true
EmptySecondaryConstructor:
active: true
EmptyWhenBlock:
active: true
EmptyWhileBlock:
active: true
exceptions:
active: true
ExceptionRaisedInUnexpectedLocation:
active: false
methodNames: 'toString,hashCode,equals,finalize'
InstanceOfCheckForException:
active: false
NotImplementedDeclaration:
active: false
PrintStackTrace:
active: false
RethrowCaughtException:
active: false
ReturnFromFinally:
active: false
SwallowedException:
active: false
ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException'
ThrowingExceptionFromFinally:
active: false
ThrowingExceptionInMain:
active: false
ThrowingExceptionsWithoutMessageOrCause:
active: false
exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
ThrowingNewInstanceOfSameException:
active: false
TooGenericExceptionCaught:
active: true
exceptionNames:
- ArrayIndexOutOfBoundsException
- Error
- Exception
- IllegalMonitorStateException
- NullPointerException
- IndexOutOfBoundsException
- RuntimeException
- Throwable
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
TooGenericExceptionThrown:
active: true
exceptionNames:
- Error
- Exception
- Throwable
- RuntimeException
formatting:
active: true
android: false
autoCorrect: true
ChainWrapping:
active: true
autoCorrect: true
CommentSpacing:
active: true
autoCorrect: true
Filename:
active: true
FinalNewline:
active: true
autoCorrect: true
ImportOrdering:
active: false
Indentation:
active: true
autoCorrect: true
indentSize: 4
continuationIndentSize: 4
MaximumLineLength:
active: true
maxLineLength: 120
ModifierOrdering:
active: true
autoCorrect: true
NoBlankLineBeforeRbrace:
active: true
autoCorrect: true
NoConsecutiveBlankLines:
active: true
autoCorrect: true
NoEmptyClassBody:
active: true
autoCorrect: true
NoItParamInMultilineLambda:
active: false
NoLineBreakAfterElse:
active: true
autoCorrect: true
NoLineBreakBeforeAssignment:
active: true
autoCorrect: true
NoMultipleSpaces:
active: true
autoCorrect: true
NoSemicolons:
active: true
autoCorrect: true
NoTrailingSpaces:
active: true
autoCorrect: true
NoUnitReturn:
active: true
autoCorrect: true
NoUnusedImports:
active: true
autoCorrect: true
NoWildcardImports:
active: true
autoCorrect: true
PackageName:
active: true
autoCorrect: true
ParameterListWrapping:
active: true
autoCorrect: true
indentSize: 4
SpacingAroundColon:
active: true
autoCorrect: true
SpacingAroundComma:
active: true
autoCorrect: true
SpacingAroundCurly:
active: true
autoCorrect: true
SpacingAroundKeyword:
active: true
autoCorrect: true
SpacingAroundOperators:
active: true
autoCorrect: true
SpacingAroundParens:
active: true
autoCorrect: true
SpacingAroundRangeOperator:
active: true
autoCorrect: true
StringTemplate:
active: true
autoCorrect: true
naming:
active: true
ClassNaming:
active: true
classPattern: '[A-Z$][a-zA-Z0-9$]*'
ConstructorParameterNaming:
active: true
parameterPattern: '[a-z][A-Za-z0-9]*'
privateParameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
EnumNaming:
active: true
enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
ForbiddenClassName:
active: false
forbiddenName: ''
FunctionMaxLength:
active: false
maximumFunctionNameLength: 30
FunctionMinLength:
active: false
minimumFunctionNameLength: 3
FunctionNaming:
active: true
functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
excludeClassPattern: '$^'
ignoreOverridden: true
FunctionParameterNaming:
active: true
parameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverriddenFunctions: true
MatchingDeclarationName:
active: true
MemberNameEqualsClassName:
active: false
ignoreOverriddenFunction: true
ObjectPropertyNaming:
active: true
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
PackageNaming:
active: true
packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$'
TopLevelPropertyNaming:
active: true
constantPattern: '[A-Z][_A-Z0-9]*'
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern: '(_)?[A-Za-z][A-Za-z0-9]*'
VariableMaxLength:
active: false
maximumVariableNameLength: 64
VariableMinLength:
active: false
minimumVariableNameLength: 1
VariableNaming:
active: true
variablePattern: '[a-z][A-Za-z0-9]*'
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverridden: true
performance:
active: true
ArrayPrimitive:
active: false
ForEachOnRange:
active: true
SpreadOperator:
active: true
UnnecessaryTemporaryInstantiation:
active: true
potential-bugs:
active: true
DuplicateCaseInWhenExpression:
active: true
EqualsAlwaysReturnsTrueOrFalse:
active: false
EqualsWithHashCodeExist:
active: true
ExplicitGarbageCollectionCall:
active: true
InvalidRange:
active: false
IteratorHasNextCallsNextMethod:
active: false
IteratorNotThrowingNoSuchElementException:
active: false
LateinitUsage:
active: false
excludeAnnotatedProperties: ""
ignoreOnClassesPattern: ""
UnconditionalJumpStatementInLoop:
active: false
UnreachableCode:
active: true
UnsafeCallOnNullableType:
active: false
UnsafeCast:
active: false
UselessPostfixExpression:
active: false
WrongEqualsTypeParameter:
active: false
style:
active: true
CollapsibleIfStatements:
active: false
DataClassContainsFunctions:
active: false
conversionFunctionPrefix: 'to'
EqualsNullCall:
active: false
EqualsOnSignatureLine:
active: false
ExplicitItLambdaParameter:
active: false
ExpressionBodySyntax:
active: false
includeLineWrapping: false
ForbiddenComment:
active: true
values: 'TODO:,FIXME:,STOPSHIP:'
ForbiddenImport:
active: false
imports: ''
ForbiddenVoid:
active: false
FunctionOnlyReturningConstant:
active: false
ignoreOverridableFunction: true
excludedFunctions: 'describeContents'
LoopWithTooManyJumpStatements:
active: false
maxJumpCount: 1
MagicNumber:
active: true
ignoreNumbers: '-1,0,1,2'
ignoreHashCodeFunction: true
ignorePropertyDeclaration: false
ignoreConstantDeclaration: true
ignoreCompanionObjectPropertyDeclaration: true
ignoreAnnotation: false
ignoreNamedArgument: true
ignoreEnums: false
MandatoryBracesIfStatements:
active: false
MaxLineLength:
active: true
maxLineLength: 120
excludePackageStatements: true
excludeImportStatements: true
excludeCommentStatements: false
MayBeConst:
active: false
ModifierOrder:
active: true
NestedClassesVisibility:
active: false
NewLineAtEndOfFile:
active: true
NoTabs:
active: false
OptionalAbstractKeyword:
active: true
OptionalUnit:
active: false
OptionalWhenBraces:
active: false
PreferToOverPairSyntax:
active: false
ProtectedMemberInFinalClass:
active: false
RedundantVisibilityModifierRule:
active: false
ReturnCount:
active: true
max: 2
excludedFunctions: "equals"
excludeLabeled: false
excludeReturnFromLambda: true
SafeCast:
active: true
SerialVersionUIDInSerializableClass:
active: false
SpacingBetweenPackageAndImports:
active: false
ThrowsCount:
active: true
max: 2
TrailingWhitespace:
active: false
UnderscoresInNumericLiterals:
active: false
acceptableDecimalLength: 5
UnnecessaryAbstractClass:
active: false
excludeAnnotatedClasses: "dagger.Module"
UnnecessaryApply:
active: false
UnnecessaryInheritance:
active: false
UnnecessaryLet:
active: false
UnnecessaryParentheses:
active: false
UntilInsteadOfRangeTo:
active: false
UnusedImports:
active: false
UnusedPrivateClass:
active: false
UnusedPrivateMember:
active: false
allowedNames: "(_|ignored|expected|serialVersionUID)"
UseDataClass:
active: false
excludeAnnotatedClasses: ""
UtilityClassWithPublicConstructor:
active: false
VarCouldBeVal:
active: false
WildcardImport:
active: true
excludeImports: 'java.util.*,kotlinx.android.synthetic.*'

View File

@ -17,9 +17,13 @@ lintValue=$?
ruby scripts/analysis/findbugs-up.rb $1 $2 $3
findbugsValue=$?
./gradlew ktlint
ktlintValue=$?
./gradlew detekt
detektValue=$?
# exit codes:
# 0: count was reduced
# 1: count was increased
@ -129,6 +133,11 @@ else
ktlintMessage="<h1>Kotlin lint found errors</h1><a href='https://www.kaminsky.me/nc-dev/android-ktlint/$6.html'>Lint</a>"
fi
if ( [ $detektValue -eq 1 ] ) ; then
curl -u $4:$5 -X PUT https://nextcloud.kaminsky.me/remote.php/webdav/android-detekt/$6.html --upload-file build/reports/detekt/detekt.html
detektMessage="<h1>Detekt errors found</h1><a href='https://www.kaminsky.me/nc-dev/android-detekt/$6.html'>Lint</a>"
fi
# check gplay limitation: all changelog files must only have 500 chars
gplayLimitation=$(scripts/checkGplayLimitation.sh)
@ -136,7 +145,7 @@ else
gplayLimitation="<h1>Following files are beyond 500 char limit:</h1><br><br>"$gplayLimitation
fi
curl -u $1:$2 -X POST https://api.github.com/repos/nextcloud/android/issues/$7/comments -d "{ \"body\" : \"$codacyResult $lintResult $findbugsResultNew $findbugsResultOld $checkLibraryMessage $lintMessage $findbugsMessage $ktlintMessage $gplayLimitation \" }"
curl -u $1:$2 -X POST https://api.github.com/repos/nextcloud/android/issues/$7/comments -d "{ \"body\" : \"$codacyResult $lintResult $findbugsResultNew $findbugsResultOld $checkLibraryMessage $lintMessage $findbugsMessage $ktlintMessage $detektMessage $gplayLimitation \" }"
if [ ! -z "$gplayLimitation" ]; then
exit 1
@ -150,10 +159,15 @@ else
exit $lintValue
fi
if [ $ktlintValue -eq 1 ]; then
exit 1
fi
if [ $detektValue -eq 1 ]; then
exit 1
fi
if [ $findbugsValue -eq 2 ]; then
exit 0
else

View File

@ -2,7 +2,7 @@ package com.owncloud.android.ui.activity;
import android.app.Activity;
import com.nextcloud.client.whatsnew.WhatsNewActivity;
import com.nextcloud.client.onboarding.WhatsNewActivity;
import com.owncloud.android.AbstractIT;
import org.junit.Rule;

View File

@ -314,10 +314,10 @@
<activity
android:name=".ui.trashbin.TrashbinActivity"
android:configChanges="orientation|screenSize|keyboardHidden"/>
<activity android:name="com.nextcloud.client.whatsnew.WhatsNewActivity"
<activity android:name="com.nextcloud.client.onboarding.WhatsNewActivity"
android:theme="@style/Theme.ownCloud.noActionBar.Login" />
<activity
android:name=".ui.activity.FirstRunActivity"
android:name="com.nextcloud.client.onboarding.FirstRunActivity"
android:theme="@style/Theme.ownCloud.noActionBar.Login"
android:configChanges="orientation|screenSize"/>

View File

@ -33,6 +33,11 @@ public interface UserAccountManager extends CurrentAccountProvider {
@Nullable
OwnCloudAccount getCurrentOwnCloudAccount();
/**
* Remove all NextCloud accounts from OS account manager.
*/
void removeAllAccounts();
/**
* Get configured NextCloud's user accounts.
*

View File

@ -69,6 +69,13 @@ public class UserAccountManagerImpl implements UserAccountManager {
this.accountManager = accountManager;
}
@Override
public void removeAllAccounts() {
for (Account account : accountManager.getAccounts()) {
accountManager.removeAccount(account, null, null);
}
}
@Override
@NonNull
public Account[] getAccounts() {

View File

@ -25,7 +25,7 @@ import android.app.Application;
import com.nextcloud.client.appinfo.AppInfoModule;
import com.nextcloud.client.device.DeviceModule;
import com.nextcloud.client.network.NetworkModule;
import com.nextcloud.client.whatsnew.WhatsNewModule;
import com.nextcloud.client.onboarding.OnboardingModule;
import com.owncloud.android.MainApp;
import javax.inject.Singleton;
@ -38,9 +38,9 @@ import dagger.android.support.AndroidSupportInjectionModule;
AndroidSupportInjectionModule.class,
AppModule.class,
AppInfoModule.class,
WhatsNewModule.class,
NetworkModule.class,
DeviceModule.class
DeviceModule.class,
OnboardingModule.class
})
@Singleton
public interface AppComponent {

View File

@ -20,7 +20,7 @@
package com.nextcloud.client.di;
import com.nextcloud.client.whatsnew.WhatsNewActivity;
import com.nextcloud.client.onboarding.WhatsNewActivity;
import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.authentication.DeepLinkLoginActivity;
import com.owncloud.android.files.BootupBroadcastReceiver;
@ -42,7 +42,7 @@ import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity;
import com.owncloud.android.ui.activity.ExternalSiteWebView;
import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.activity.FilePickerActivity;
import com.owncloud.android.ui.activity.FirstRunActivity;
import com.nextcloud.client.onboarding.FirstRunActivity;
import com.owncloud.android.ui.activity.FolderPickerActivity;
import com.owncloud.android.ui.activity.LogHistoryActivity;
import com.owncloud.android.ui.activity.ManageAccountsActivity;

View File

@ -22,7 +22,7 @@
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.activity;
package com.nextcloud.client.onboarding;
import android.accounts.Account;
import android.accounts.AccountManager;
@ -42,12 +42,13 @@ import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.appinfo.AppInfo;
import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.preferences.AppPreferences;
import com.nextcloud.client.whatsnew.WhatsNewService;
import com.owncloud.android.BuildConfig;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AccountUtils;
import com.owncloud.android.authentication.AuthenticatorActivity;
import com.owncloud.android.features.FeatureItem;
import com.owncloud.android.ui.activity.BaseActivity;
import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.adapter.FeaturesViewAdapter;
import com.owncloud.android.ui.whatsnew.ProgressIndicator;
import com.owncloud.android.utils.DisplayUtils;
@ -70,7 +71,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
@Inject UserAccountManager userAccountManager;
@Inject AppPreferences preferences;
@Inject AppInfo appInfo;
@Inject WhatsNewService whatsNew;
@Inject OnboardingService onboarding;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -119,13 +120,8 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
ViewPager viewPager = findViewById(R.id.contentPanel);
// Sometimes, accounts are not deleted when you uninstall the application so we'll do it now
if (whatsNew.isFirstRun()) {
AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
if (am != null) {
for (Account account : userAccountManager.getAccounts()) {
am.removeAccount(account, null, null);
}
}
if (onboarding.isFirstRun()) {
userAccountManager.removeAllAccounts();
}
FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(), getFirstRun());
@ -190,31 +186,6 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
super.onStop();
}
private static boolean isFirstRun(Context context) {
return AccountUtils.getCurrentOwnCloudAccount(context) == null;
}
public static boolean runIfNeeded(Context context) {
boolean isProviderOrOwnInstallationVisible = context.getResources()
.getBoolean(R.bool.show_provider_or_own_installation);
if (!isProviderOrOwnInstallationVisible) {
return false;
}
if (context instanceof FirstRunActivity) {
return false;
}
if (isFirstRun(context) && context instanceof AuthenticatorActivity) {
((AuthenticatorActivity) context).startActivityForResult(new Intent(context, FirstRunActivity.class),
AuthenticatorActivity.REQUEST_CODE_FIRST_RUN);
return true;
} else {
return false;
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// unused but to be implemented due to abstract parent
@ -248,7 +219,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
}
setAccount(account);
accountManager.setCurrentOwnCloudAccount(account.name);
userAccountManager.setCurrentOwnCloudAccount(account.name);
onAccountSet(false);
Intent i = new Intent(this, FileDisplayActivity.class);

View File

@ -16,26 +16,25 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.client.whatsnew;
package com.nextcloud.client.onboarding
import android.content.res.Resources;
import com.nextcloud.client.account.CurrentAccountProvider;
import com.nextcloud.client.preferences.AppPreferences;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import android.content.res.Resources
import com.nextcloud.client.account.CurrentAccountProvider
import com.nextcloud.client.preferences.AppPreferences
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
@Module
public class WhatsNewModule {
class OnboardingModule {
@Provides
@Singleton
WhatsNewService whatsNewService(Resources resources,
AppPreferences preferences,
CurrentAccountProvider accountProvider) {
return new WhatsNewService(resources, preferences, accountProvider);
internal fun onboardingService(
resources: Resources,
preferences: AppPreferences,
accountProvider: CurrentAccountProvider
): OnboardingService {
return OnboardingServiceImpl(resources, preferences, accountProvider)
}
}

View File

@ -0,0 +1,31 @@
/* Nextcloud Android client application
*
* @author Chris Narkiewicz
* Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.client.onboarding
import android.app.Activity
import android.content.Context
import com.owncloud.android.features.FeatureItem
interface OnboardingService {
val whatsNew: Array<FeatureItem>
val isFirstRun: Boolean
fun launchActivityIfNeeded(activity: Activity)
fun launchFirstRunIfNeeded(activity: Activity): Boolean
fun shouldShowWhatsNew(callingContext: Context): Boolean
}

View File

@ -0,0 +1,80 @@
/* Nextcloud Android client application
*
* @author Chris Narkiewicz
* Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.client.onboarding
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import com.nextcloud.client.account.CurrentAccountProvider
import com.nextcloud.client.preferences.AppPreferences
import com.owncloud.android.BuildConfig
import com.owncloud.android.R
import com.owncloud.android.authentication.AuthenticatorActivity
import com.owncloud.android.features.FeatureItem
import com.owncloud.android.ui.activity.PassCodeActivity
internal class OnboardingServiceImpl constructor(
private val resources: Resources,
private val preferences: AppPreferences,
accountProvider: CurrentAccountProvider
) : OnboardingService {
private companion object {
const val ITEM_VERSION_CODE = 99999999
}
private val notSeenYet: Boolean get() {
return BuildConfig.VERSION_CODE >= ITEM_VERSION_CODE && preferences.lastSeenVersionCode < ITEM_VERSION_CODE
}
override val whatsNew: Array<FeatureItem>
get() = if (!isFirstRun && notSeenYet) {
emptyArray()
} else {
emptyArray()
}
override val isFirstRun: Boolean = accountProvider.currentAccount == null
override fun shouldShowWhatsNew(callingContext: Context): Boolean {
return callingContext !is PassCodeActivity && whatsNew.size > 0
}
override fun launchActivityIfNeeded(activity: Activity) {
if (!resources.getBoolean(R.bool.show_whats_new) || activity is WhatsNewActivity) {
return
}
if (shouldShowWhatsNew(activity)) {
activity.startActivity(Intent(activity, WhatsNewActivity::class.java))
}
}
override fun launchFirstRunIfNeeded(activity: Activity): Boolean {
val isProviderOrOwnInstallationVisible = resources.getBoolean(R.bool.show_provider_or_own_installation)
val canLaunch = isProviderOrOwnInstallationVisible && isFirstRun && activity is AuthenticatorActivity
if (canLaunch) {
val intent = Intent(activity, FirstRunActivity::class.java)
activity.startActivityForResult(intent, AuthenticatorActivity.REQUEST_CODE_FIRST_RUN)
}
return canLaunch
}
}

View File

@ -21,7 +21,7 @@
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.client.whatsnew;
package com.nextcloud.client.onboarding;
import android.os.Build;
import android.os.Bundle;
@ -56,7 +56,7 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
private ViewPager mPager;
@Inject AppPreferences preferences;
@Inject AppInfo appInfo;
@Inject WhatsNewService whatsNew;
@Inject OnboardingService onboarding;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -78,7 +78,7 @@ public class WhatsNewActivity extends FragmentActivity implements ViewPager.OnPa
mPager.setAdapter(featuresWebViewAdapter);
} else {
FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(),
whatsNew.getWhatsNew());
onboarding.getWhatsNew());
mProgress.setNumberOfSteps(featuresViewAdapter.getCount());
mPager.setAdapter(featuresViewAdapter);
}

View File

@ -1,75 +0,0 @@
/* Nextcloud Android client application
*
* @author Chris Narkiewicz
* Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.client.whatsnew;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import com.nextcloud.client.account.CurrentAccountProvider;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.BuildConfig;
import com.owncloud.android.R;
import com.owncloud.android.features.FeatureItem;
import com.owncloud.android.ui.activity.PassCodeActivity;
public class WhatsNewService {
private Resources resources;
private AppPreferences preferences;
private CurrentAccountProvider accountProvider;
WhatsNewService(Resources resources,
AppPreferences preferences,
CurrentAccountProvider accountProvider) {
this.resources = resources;
this.preferences = preferences;
this.accountProvider = accountProvider;
}
public void launchActivityIfNeeded(Activity activity) {
if (!resources.getBoolean(R.bool.show_whats_new) || activity instanceof WhatsNewActivity) {
return;
}
if (shouldShow(activity)) {
activity.startActivity(new Intent(activity, WhatsNewActivity.class));
}
}
FeatureItem[] getWhatsNew() {
int itemVersionCode = 99999999;
if (!isFirstRun() && BuildConfig.VERSION_CODE >= itemVersionCode
&& preferences.getLastSeenVersionCode() < itemVersionCode) {
return new FeatureItem[0];
} else {
return new FeatureItem[0];
}
}
private boolean shouldShow(Context callingContext) {
return !(callingContext instanceof PassCodeActivity) && getWhatsNew().length > 0;
}
public boolean isFirstRun() {
return accountProvider.getCurrentAccount() == null;
}
}

View File

@ -49,9 +49,9 @@ import com.nextcloud.client.appinfo.AppInfo;
import com.nextcloud.client.di.ActivityInjector;
import com.nextcloud.client.di.DaggerAppComponent;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.client.onboarding.OnboardingService;
import com.nextcloud.client.preferences.AppPreferences;
import com.nextcloud.client.preferences.AppPreferencesImpl;
import com.nextcloud.client.whatsnew.WhatsNewService;
import com.owncloud.android.authentication.PassCodeManager;
import com.owncloud.android.datamodel.ArbitraryDataProvider;
import com.owncloud.android.datamodel.MediaFolder;
@ -156,7 +156,7 @@ public class MainApp extends MultiDexApplication implements
protected AppInfo appInfo;
@Inject
protected WhatsNewService whatsNew;
protected OnboardingService onboarding;
@Inject
ConnectivityService connectivityService;
@ -258,7 +258,7 @@ public class MainApp extends MultiDexApplication implements
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log_OC.d(activity.getClass().getSimpleName(), "onCreate(Bundle) starting");
whatsNew.launchActivityIfNeeded(activity);
onboarding.launchActivityIfNeeded(activity);
}
@Override

View File

@ -89,6 +89,7 @@ import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.onboarding.OnboardingService;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
@ -113,7 +114,7 @@ import com.owncloud.android.operations.GetServerInfoOperation;
import com.owncloud.android.services.OperationsService;
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.activity.FirstRunActivity;
import com.nextcloud.client.onboarding.FirstRunActivity;
import com.owncloud.android.ui.components.CustomEditText;
import com.owncloud.android.ui.dialog.CredentialsDialogFragment;
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
@ -252,6 +253,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
@Inject UserAccountManager accountManager;
@Inject AppPreferences preferences;
@Inject OnboardingService onboarding;
/**
* {@inheritDoc}
@ -266,7 +268,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
Uri data = getIntent().getData();
boolean directLogin = data != null && data.toString().startsWith(getString(R.string.login_data_own_scheme));
if (savedInstanceState == null && !directLogin) {
FirstRunActivity.runIfNeeded(this);
onboarding.launchFirstRunIfNeeded(this);
}
// delete cookies for webView

View File

@ -57,6 +57,7 @@ import com.bumptech.glide.request.target.SimpleTarget;
import com.google.android.material.navigation.NavigationView;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.onboarding.FirstRunActivity;
import com.nextcloud.client.preferences.AppPreferences;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;

View File

@ -42,9 +42,9 @@ import android.widget.ListView;
import com.evernote.android.job.JobRequest;
import com.evernote.android.job.util.support.PersistableBundleCompat;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.onboarding.FirstRunActivity;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AccountUtils;
import com.owncloud.android.datamodel.ArbitraryDataProvider;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.files.services.FileDownloader;