Skip to content

Commit 7fd82e1

Browse files
authored
Merge pull request #29 from stanwood/develop
Master merge 1.1
2 parents 1bf233d + 97394de commit 7fd82e1

21 files changed

+129
-193
lines changed

app/build.gradle

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ apply plugin: 'com.android.application'
22
apply plugin: 'kotlin-android'
33
apply plugin: 'kotlin-kapt'
44
apply plugin: 'project-report'
5+
apply plugin: 'kotlin-android-extensions'
6+
7+
8+
Properties properties = new Properties()
9+
def propertiesFile = project.rootProject.file('local.properties')
10+
if (propertiesFile.exists()) {
11+
properties.load(propertiesFile.newDataInputStream())
12+
}
13+
def bitriseApiToken = properties.getProperty('bitrise.api.token')
514

615
android {
716
compileSdkVersion sdk_version
@@ -10,20 +19,24 @@ android {
1019
minSdkVersion 21
1120
targetSdkVersion sdk_version
1221
versionCode 1
13-
versionName "1.0"
22+
versionName "1.1"
1423
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1524
multiDexEnabled true
1625

1726
buildConfigField "String", "BITRISE_API_BASE_URL", "\"https://api.bitrise.io/\""
1827
buildConfigField "int", "DEFAULT_PAGE_SIZE", "10"
1928
buildConfigField "int", "PAGE_LOAD_THRESHOLD", "2"
29+
buildConfigField "String", "BITRISE_API_TOKEN", "\"$bitriseApiToken\""
2030
buildConfigField "long", "DOWNLOAD_STATUS_REFRESH_DELAY", "500L"
2131
}
2232
kotlin {
2333
experimental {
2434
coroutines 'enable'
2535
}
2636
}
37+
androidExtensions {
38+
experimental = true
39+
}
2740
dataBinding {
2841
enabled = true
2942
}

app/src/main/java/io/stanwood/bitrise/MainActivity.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import io.stanwood.bitrise.ui.logs.di.logsModule
1717
import org.koin.android.ext.android.inject
1818
import org.koin.android.ext.android.setProperty
1919
import org.koin.android.ext.koin.with
20+
import org.koin.error.AlreadyStartedException
2021
import org.koin.standalone.StandAloneContext
2122
import ru.terrakok.cicerone.NavigatorHolder
2223
import ru.terrakok.cicerone.Router
@@ -57,14 +58,19 @@ class MainActivity: PermissionActivity() {
5758
}
5859

5960
private fun startKoin() {
60-
StandAloneContext.startKoin(listOf(
61-
applicationModule,
62-
errorModule,
63-
loginModule,
64-
dashboardModule,
65-
buildsModule,
66-
buildModule,
67-
logsModule,
68-
artifactsModule)) with application
61+
try {
62+
StandAloneContext.startKoin(listOf(
63+
applicationModule,
64+
errorModule,
65+
loginModule,
66+
dashboardModule,
67+
buildsModule,
68+
buildModule,
69+
logsModule,
70+
artifactsModule)) with application
71+
} catch (exception: AlreadyStartedException) {
72+
// Can be safely ignored
73+
Timber.e(exception)
74+
}
6975
}
7076
}

app/src/main/java/io/stanwood/bitrise/data/model/App.kt

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package io.stanwood.bitrise.data.model
33
import android.os.Parcel
44
import android.os.Parcelable
55
import com.google.gson.annotations.SerializedName
6+
import kotlinx.android.parcel.Parcelize
67

7-
8+
@Parcelize
89
data class App(
910
@SerializedName("is_disabled") val isDisabled: Boolean, //false
1011
@SerializedName("project_type") val projectType: Platform, //xamarin
@@ -14,36 +15,4 @@ data class App(
1415
@SerializedName("repo_url") val repoUrl: String, //https://github.com/bitrise-samples/sample-apps-xamarin-cross-platform.git
1516
@SerializedName("slug") val slug: String, //f46e89061e967f27
1617
@SerializedName("title") val title: String //sample-apps-xamarin-cross-platform
17-
) : Parcelable {
18-
companion object {
19-
@JvmField
20-
val CREATOR: Parcelable.Creator<App> = object : Parcelable.Creator<App> {
21-
override fun createFromParcel(source: Parcel): App = App(source)
22-
override fun newArray(size: Int): Array<App?> = arrayOfNulls(size)
23-
}
24-
}
25-
26-
constructor(source: Parcel) : this(
27-
1 == source.readInt(),
28-
Platform.valueOf(source.readString()),
29-
source.readString(),
30-
source.readString(),
31-
source.readString(),
32-
source.readString(),
33-
source.readString(),
34-
source.readString()
35-
)
36-
37-
override fun describeContents() = 0
38-
39-
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
40-
writeInt((if (isDisabled) 1 else 0))
41-
writeString(projectType.toString())
42-
writeString(provider)
43-
writeString(repoOwner)
44-
writeString(repoSlug)
45-
writeString(repoUrl)
46-
writeString(slug)
47-
writeString(title)
48-
}
49-
}
18+
) : Parcelable
Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,17 @@
11
package io.stanwood.bitrise.data.model
22

3-
import android.os.Parcel
43
import android.os.Parcelable
54
import com.google.gson.annotations.SerializedName
5+
import kotlinx.android.parcel.Parcelize
66

77

8+
@Parcelize
89
data class Artifact(
9-
@SerializedName("artifact_type") val artifactType: ArtifactType, //android-apk
10+
@SerializedName("artifact_type") val artifactType: ArtifactType?, //android-apk
1011
@SerializedName("expiring_download_url") val expiringDownloadUrl: String, //https://bitrise-prod-build-storage.s3.amazonaws.com/builds/ddf4134555e833d8/artifacts/3205846/app-debug.apk?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAIOC7N256G7J2W2TQ%2F20171122%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20171122T135501Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host&X-Amz-Signature=bad4467b83a1d98a6046b59a1b232bb0888decf203e039c9b3798f7b4950b68c
1112
@SerializedName("file_size_bytes") val fileSizeBytes: Int, //607185
1213
@SerializedName("is_public_page_enabled") val isPublicPageEnabled: Boolean, //true
1314
@SerializedName("public_install_page_url") val publicInstallPageUrl: String?, //https://www.bitrise.io/artifact/3205846/p/300e0121b50985fd631fe304d549006f
1415
@SerializedName("slug") val slug: String, //5a9f5da8d5f1057c
1516
@SerializedName("title") val title: String //app-debug.apk
16-
) : Parcelable {
17-
constructor(source: Parcel) : this(
18-
ArtifactType.values()[source.readInt()],
19-
source.readString(),
20-
source.readInt(),
21-
1 == source.readInt(),
22-
source.readString(),
23-
source.readString(),
24-
source.readString()
25-
)
26-
27-
override fun describeContents() = 0
28-
29-
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
30-
writeInt(artifactType.ordinal)
31-
writeString(expiringDownloadUrl)
32-
writeInt(fileSizeBytes)
33-
writeInt((if (isPublicPageEnabled) 1 else 0))
34-
writeString(publicInstallPageUrl)
35-
writeString(slug)
36-
writeString(title)
37-
}
38-
39-
companion object {
40-
@JvmField
41-
val CREATOR: Parcelable.Creator<Artifact> = object : Parcelable.Creator<Artifact> {
42-
override fun createFromParcel(source: Parcel): Artifact = Artifact(source)
43-
override fun newArray(size: Int): Array<Artifact?> = arrayOfNulls(size)
44-
}
45-
}
46-
}
17+
): Parcelable

app/src/main/java/io/stanwood/bitrise/data/model/ArtifactType.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ enum class ArtifactType(
1212
@DrawableRes private val iconResId: Int) {
1313

1414
@SerializedName("file") FILE(R.string.artifact_type_file, R.drawable.ic_artifact_file),
15-
@SerializedName("android-apk") APK(R.string.artifact_type_apk, R.drawable.ic_artifact_apk);
15+
@SerializedName("android-apk") APK(R.string.artifact_type_ipa, R.drawable.ic_artifact_apk),
16+
@SerializedName("ios-ipa") IPA(R.string.artifact_type_ipa, R.drawable.ic_artifact_ipa);
1617

1718
fun getTitle(resources: Resources) = resources.getString(titleResId)
1819
fun getIcon(resources: Resources) = resources.getDrawable(iconResId)
Lines changed: 3 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package io.stanwood.bitrise.data.model
22

3-
import android.os.Parcel
43
import android.os.Parcelable
54
import com.google.gson.annotations.SerializedName
5+
import kotlinx.android.parcel.Parcelize
66
import java.util.*
77

8+
@Parcelize
89
data class Build(
910
@SerializedName("abort_reason") val abortReason: String?,
1011
@SerializedName("branch") val branch: String, //master
@@ -29,94 +30,4 @@ data class Build(
2930
@SerializedName("triggered_at") val triggeredAt: Date, //2017-11-08T13:24:33Z
3031
@SerializedName("triggered_by") val triggeredBy: String, //manual-api-demo
3132
@SerializedName("triggered_workflow") val triggeredWorkflow: String //gen-apk
32-
) : Parcelable {
33-
constructor(source: Parcel) : this(
34-
source.readString(),
35-
source.readString(),
36-
source.readInt(),
37-
source.readString(),
38-
source.readString(),
39-
source.readString(),
40-
source.readSerializable() as Date?,
41-
source.readSerializable() as Date?,
42-
1 == source.readInt(),
43-
source.readParcelable<OriginalBuildParams>(OriginalBuildParams::class.java.classLoader),
44-
source.readInt(),
45-
source.readString(),
46-
source.readString(),
47-
source.readString(),
48-
source.readString(),
49-
source.readString(),
50-
source.readString(),
51-
BuildStatus.values()[source.readInt()],
52-
source.readString(),
53-
source.readString(),
54-
source.readSerializable() as Date,
55-
source.readString(),
56-
source.readString()
57-
)
58-
59-
override fun describeContents() = 0
60-
61-
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
62-
writeString(abortReason)
63-
writeString(branch)
64-
writeInt(number)
65-
writeString(commitHash)
66-
writeString(commitMessage)
67-
writeString(commitViewUrl)
68-
writeSerializable(environmentPrepareFinishedAt)
69-
writeSerializable(finishedAt)
70-
writeInt((if (isOnHold) 1 else 0))
71-
writeParcelable(originalBuildParams, 0)
72-
writeInt(pullRequestId)
73-
writeString(pullRequestTargetBranch)
74-
writeString(pullRequestViewUrl)
75-
writeString(slug)
76-
writeString(stackConfigType)
77-
writeString(stackIdentifier)
78-
writeString(startedOnWorkerAt)
79-
writeInt(status.ordinal)
80-
writeString(statusText)
81-
writeString(tag)
82-
writeSerializable(triggeredAt)
83-
writeString(triggeredBy)
84-
writeString(triggeredWorkflow)
85-
}
86-
87-
companion object {
88-
@JvmField
89-
val CREATOR: Parcelable.Creator<Build> = object : Parcelable.Creator<Build> {
90-
override fun createFromParcel(source: Parcel): Build = Build(source)
91-
override fun newArray(size: Int): Array<Build?> = arrayOfNulls(size)
92-
}
93-
}
94-
}
95-
96-
data class OriginalBuildParams(
97-
@SerializedName("branch") val branch: String, //master
98-
@SerializedName("commit_message") val commitMessage: String, //generate an APK
99-
@SerializedName("workflow_id") val workflowId: String //gen-apk
100-
) : Parcelable {
101-
constructor(source: Parcel) : this(
102-
source.readString(),
103-
source.readString(),
104-
source.readString()
105-
)
106-
107-
override fun describeContents() = 0
108-
109-
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
110-
writeString(branch)
111-
writeString(commitMessage)
112-
writeString(workflowId)
113-
}
114-
115-
companion object {
116-
@JvmField
117-
val CREATOR: Parcelable.Creator<OriginalBuildParams> = object : Parcelable.Creator<OriginalBuildParams> {
118-
override fun createFromParcel(source: Parcel): OriginalBuildParams = OriginalBuildParams(source)
119-
override fun newArray(size: Int): Array<OriginalBuildParams?> = arrayOfNulls(size)
120-
}
121-
}
122-
}
33+
): Parcelable
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.stanwood.bitrise.data.model
2+
3+
import android.os.Parcelable
4+
import com.google.gson.annotations.SerializedName
5+
import kotlinx.android.parcel.Parcelize
6+
7+
8+
@Parcelize
9+
data class OriginalBuildParams(
10+
@SerializedName("branch") val branch: String, //master
11+
@SerializedName("commit_message") val commitMessage: String, //generate an APK
12+
@SerializedName("workflow_id") val workflowId: String //gen-apk
13+
): Parcelable

app/src/main/java/io/stanwood/bitrise/ui/artifacts/vm/ArtifactItemViewModel.kt

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class ArtifactItemViewModel(
3838
private val router: Router,
3939
private val artifact: Artifact) : BaseObservable() {
4040

41-
val icon: Drawable
42-
get() = artifact.artifactType.getIcon(activity.resources)
41+
val icon: Drawable?
42+
get() = artifact.artifactType?.getIcon(activity.resources)
4343

4444
val title: String
4545
get() = artifact.title
@@ -67,7 +67,7 @@ class ArtifactItemViewModel(
6767
val isAwaitingDownload
6868
get() = isDownloading.get() && downloadedSize.get() == 0
6969

70-
val downloadUri: Uri
70+
private val downloadUri: Uri
7171
get() = Uri.parse(artifact.expiringDownloadUrl)
7272

7373
private val downloadErrorMessage: String
@@ -103,7 +103,7 @@ class ArtifactItemViewModel(
103103
}
104104
}
105105

106-
suspend private fun download() {
106+
private suspend fun download() {
107107
isDownloading.set(true)
108108
val request = Request(downloadUri).apply {
109109
setTitle(title)
@@ -156,8 +156,22 @@ class ArtifactItemViewModel(
156156
return DownloadStatus.FAILED
157157
}
158158

159+
private fun getDownloadedApkUri(downloadId: Long): Uri {
160+
return if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
161+
downloadManager.getUriForDownloadedFile(downloadId)
162+
} else {
163+
val query = DownloadManager.Query()
164+
query.setFilterById(downloadId)
165+
downloadManager.query(query).use {
166+
it.moveToFirst()
167+
val path = it.getString(it.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))
168+
Uri.parse(path)
169+
}
170+
}
171+
}
172+
159173
private fun installApk(downloadId: Long) {
160-
val uri = downloadManager.getUriForDownloadedFile(downloadId)
174+
val uri = getDownloadedApkUri(downloadId)
161175
Intent(Intent.ACTION_VIEW).apply {
162176
setDataAndType(uri, "application/vnd.android.package-archive")
163177
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

0 commit comments

Comments
 (0)