├── beetle
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── values-night
│ │ │ └── colors.xml
│ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── themes.xml
│ │ │ ├── attrs.xml
│ │ │ └── strings.xml
│ │ ├── drawable
│ │ │ ├── ic_check.xml
│ │ │ ├── ic_back.xml
│ │ │ ├── ic_close.xml
│ │ │ ├── ic_send.xml
│ │ │ ├── ic_undo.xml
│ │ │ ├── bg_paint_yellow.xml
│ │ │ ├── ic_article.xml
│ │ │ ├── bg_paint_black.xml
│ │ │ ├── bg_chip.xml
│ │ │ └── ic_beetle.xml
│ │ ├── menu
│ │ │ └── menu_feedback.xml
│ │ └── layout
│ │ │ ├── item_label.xml
│ │ │ ├── item_assignee.xml
│ │ │ ├── activity_edit.xml
│ │ │ └── activity_feedback.xml
│ │ ├── kotlin
│ │ └── com
│ │ │ └── karacca
│ │ │ └── beetle
│ │ │ ├── data
│ │ │ ├── model
│ │ │ │ ├── IssueRequest.kt
│ │ │ │ ├── RepositoryInstallation.kt
│ │ │ │ ├── Issue.kt
│ │ │ │ ├── Image.kt
│ │ │ │ ├── Label.kt
│ │ │ │ ├── Collaborator.kt
│ │ │ │ └── AccessToken.kt
│ │ │ ├── repository
│ │ │ │ ├── ImageRepository.kt
│ │ │ │ └── GitHubRepository.kt
│ │ │ └── service
│ │ │ │ ├── ImageService.kt
│ │ │ │ └── GitHubService.kt
│ │ │ ├── utils
│ │ │ ├── ReflectionUtils.kt
│ │ │ ├── LifecycleHandler.kt
│ │ │ ├── MarkdownUtils.kt
│ │ │ ├── CollectDataTask.kt
│ │ │ ├── NotificationUtils.kt
│ │ │ ├── DeviceUtils.kt
│ │ │ ├── BitmapUtils.kt
│ │ │ └── ShakeDetector.kt
│ │ │ ├── BeetleConfig.kt
│ │ │ ├── ui
│ │ │ ├── widget
│ │ │ │ ├── HorizontalItemDecorator.kt
│ │ │ │ └── FingerPaintImageView.kt
│ │ │ ├── adapter
│ │ │ │ ├── AssigneeAdapter.kt
│ │ │ │ └── LabelAdapter.kt
│ │ │ ├── EditScreenshotActivity.kt
│ │ │ └── FeedbackActivity.kt
│ │ │ └── Beetle.kt
│ │ └── AndroidManifest.xml
├── proguard-rules.pro
└── build.gradle.kts
├── local.defaults.properties
├── docs
├── images
│ ├── badge.png
│ ├── edit.png
│ └── feedback.png
├── terms.md
└── privacy_policy.md
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── .editorconfig
├── settings.gradle.kts
├── CHANGELOG.md
├── spotless
├── copyright.kt
├── copyright.kts
└── copyright.xml
├── .github
└── workflows
│ ├── Build.yaml
│ └── Publish.yaml
├── README.md
├── gradlew.bat
├── .gitignore
├── gradlew
└── LICENSE
/beetle/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/local.defaults.properties:
--------------------------------------------------------------------------------
1 | GITHUB_APP_ID=ID
2 | FREE_IMAGE_API_KEY=KEY
3 |
--------------------------------------------------------------------------------
/docs/images/badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karacca/beetle/HEAD/docs/images/badge.png
--------------------------------------------------------------------------------
/docs/images/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karacca/beetle/HEAD/docs/images/edit.png
--------------------------------------------------------------------------------
/docs/images/feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karacca/beetle/HEAD/docs/images/feedback.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/karacca/beetle/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
2 | android.useAndroidX=true
3 | kotlin.code.style=official
4 | android.nonTransitiveRClass=true
5 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig: http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | insert_final_newline = true
6 |
7 | [*.{yml, json}]
8 | indent_style = space
9 | indent_size = 2
10 |
11 | [*.{kt, kts, java}]
12 | indent_size = 4
13 | max_line_length = 100
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 |
9 | rootProject.name = "beetle"
10 | include(":beetle")
11 | include(":sample", ":sample-compose")
12 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Jul 07 14:37:07 TRT 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [2.0.1] - August 18, 2022
4 |
5 | - Add App ID, App Version and BuildType fields
6 |
7 | ## [2.0.0] - August 15, 2022
8 |
9 | - Beetle is completely refactored
10 | - GitHub API integration added
11 | - Feedback & Edit Screenshot screens redesigned
12 |
--------------------------------------------------------------------------------
/spotless/copyright.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright $YEAR Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
--------------------------------------------------------------------------------
/spotless/copyright.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright $YEAR Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
--------------------------------------------------------------------------------
/spotless/copyright.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/beetle/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 | #424242
16 |
17 |
--------------------------------------------------------------------------------
/beetle/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.kts.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/beetle/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 | #E0E0E0
16 | #1976D2
17 | #FFEE58
18 | #80FFEE58
19 |
20 |
--------------------------------------------------------------------------------
/beetle/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/.github/workflows/Build.yaml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | concurrency:
9 | group: build-${{ github.ref }}
10 | cancel-in-progress: true
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 | timeout-minutes: 60
16 |
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v3
20 |
21 | - name: Validate Gradle Wrapper
22 | uses: gradle/wrapper-validation-action@v1
23 |
24 | - name: Set up JDK 11
25 | uses: actions/setup-java@v1
26 | with:
27 | java-version: 11
28 |
29 | - name: Setup Gradle
30 | uses: gradle/gradle-build-action@v2
31 |
32 | - name: Check spotless
33 | run: ./gradlew spotlessCheck --stacktrace
34 |
35 | - name: Check lint
36 | run: ./gradlew lintDebug --stacktrace
37 |
38 | - name: Build all build type and flavor permutations
39 | run: ./gradlew assemble --stacktrace
40 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/model/IssueRequest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.model
18 |
19 | /**
20 | * @author karacca
21 | * @date 28.07.2022
22 | */
23 |
24 | internal data class IssueRequest(
25 | val title: String,
26 | val body: String,
27 | val assignees: List,
28 | val labels: List
29 | )
30 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/model/RepositoryInstallation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.model
18 |
19 | import com.google.gson.annotations.SerializedName
20 |
21 | /**
22 | * @author karacca
23 | * @date 20.07.2022
24 | */
25 |
26 | internal data class RepositoryInstallation(
27 | @SerializedName("id")
28 | val id: Int? = null
29 | )
30 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/model/Issue.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.model
18 |
19 | import com.google.gson.annotations.SerializedName
20 |
21 | /**
22 | * @author karacca
23 | * @date 28.07.2022
24 | */
25 |
26 | internal data class Issue(
27 | @SerializedName("number")
28 | val number: Int? = null,
29 | @SerializedName("html_url")
30 | val htmlUrl: String?
31 | )
32 |
--------------------------------------------------------------------------------
/beetle/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/ic_check.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/ic_back.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/beetle/src/main/res/menu/menu_feedback.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
23 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/model/Image.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.model
18 |
19 | import com.google.gson.annotations.SerializedName
20 |
21 | /**
22 | * @author karacca
23 | * @date 28.07.2022
24 | */
25 |
26 | internal data class Image(
27 | @SerializedName("image")
28 | val image: Image?,
29 | ) {
30 |
31 | data class Image(
32 | @SerializedName("url")
33 | val url: String?
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/.github/workflows/Publish.yaml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | env:
8 | ORG_GRADLE_PROJECT_signingKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }}
9 | ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }}
10 | MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
11 | BEETLE_VERSION: ${{ github.ref_name }}
12 |
13 | jobs:
14 | publish:
15 | runs-on: ubuntu-latest
16 | timeout-minutes: 45
17 |
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v3
21 |
22 | - name: Validate Gradle Wrapper
23 | uses: gradle/wrapper-validation-action@v1
24 |
25 | - name: Set up JDK 11
26 | uses: actions/setup-java@v1
27 | with:
28 | java-version: 11
29 |
30 | - name: Setup Gradle
31 | uses: gradle/gradle-build-action@v2
32 |
33 | - name: Check spotless
34 | run: ./gradlew spotlessCheck --stacktrace
35 |
36 | - name: Check lint
37 | run: ./gradlew lintDebug --stacktrace
38 |
39 | - name: Publish
40 | run: ./gradlew publish
41 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/ic_close.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/model/Label.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.model
18 |
19 | import com.google.gson.annotations.SerializedName
20 |
21 | /**
22 | * @author karacca
23 | * @date 25.07.2022
24 | */
25 |
26 | internal data class Label(
27 | @SerializedName("id")
28 | val id: Long? = null,
29 | @SerializedName("name")
30 | val name: String,
31 | @SerializedName("color")
32 | val color: String? = null
33 | ) {
34 | var selected = false
35 | }
36 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/ic_send.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
21 |
24 |
25 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/ic_undo.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/model/Collaborator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.model
18 |
19 | import com.google.gson.annotations.SerializedName
20 |
21 | /**
22 | * @author karacca
23 | * @date 22.07.2022
24 | */
25 |
26 | internal data class Collaborator(
27 | @SerializedName("login")
28 | val login: String,
29 | @SerializedName("id")
30 | val id: Int? = null,
31 | @SerializedName("avatar_url")
32 | val avatarUrl: String? = null
33 | ) {
34 |
35 | var selected = false
36 | }
37 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/bg_paint_yellow.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/ic_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
20 |
23 |
24 |
--------------------------------------------------------------------------------
/beetle/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
16 |
17 |
18 |
19 |
20 |
23 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/bg_paint_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/beetle/src/main/res/drawable/bg_chip.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/utils/ReflectionUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.utils
18 |
19 | import android.content.Context
20 |
21 | /**
22 | * @author karacca
23 | * @date 15.08.2022
24 | */
25 |
26 | internal object ReflectionUtils {
27 |
28 | fun getBuildConfigValues(context: Context): HashMap {
29 | val result = hashMapOf()
30 | try {
31 | val clazz = Class.forName(context.packageName + ".BuildConfig")
32 | for (field in clazz.fields) {
33 | val fieldName = field.name
34 | val fieldValue = clazz.getField(fieldName).get(null)
35 | if (fieldValue != null) {
36 | result[field.name] = fieldValue
37 | }
38 | }
39 | } catch (exception: Exception) {
40 | }
41 |
42 | return result
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/utils/LifecycleHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.utils
18 |
19 | import android.app.Activity
20 | import android.app.Application
21 | import android.os.Bundle
22 | import com.karacca.beetle.Beetle
23 |
24 | /**
25 | * @author karacca
26 | * @date 12.07.2022
27 | */
28 |
29 | internal class LifecycleHandler(private val beetle: Beetle) :
30 | Application.ActivityLifecycleCallbacks {
31 |
32 | override fun onActivityResumed(p0: Activity) {
33 | beetle.setActivity(p0)
34 | }
35 |
36 | override fun onActivityPaused(p0: Activity) {
37 | beetle.setActivity(null)
38 | }
39 |
40 | override fun onActivityCreated(p0: Activity, p1: Bundle?) {}
41 |
42 | override fun onActivityStarted(p0: Activity) {}
43 |
44 | override fun onActivityStopped(p0: Activity) {}
45 |
46 | override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) {}
47 |
48 | override fun onActivityDestroyed(p0: Activity) {}
49 | }
50 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/BeetleConfig.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle
18 |
19 | /**
20 | * @author karacca
21 | * @date 9.08.2022
22 | */
23 |
24 | class BeetleConfig {
25 | val userAttributes = arrayListOf>()
26 |
27 | var organization: String? = null
28 | var repository: String? = null
29 | val initialized: Boolean
30 | get() = organization != null && repository != null
31 |
32 | var enableAssignees = true
33 | var enableLabels = true
34 |
35 | fun key(key: String, value: String) {
36 | userAttributes.add(key to value)
37 | }
38 |
39 | fun key(key: String, value: Boolean) {
40 | userAttributes.add(key to value)
41 | }
42 |
43 | fun key(key: String, value: Double) {
44 | userAttributes.add(key to value)
45 | }
46 |
47 | fun key(key: String, value: Float) {
48 | userAttributes.add(key to value)
49 | }
50 |
51 | fun key(key: String, value: Int) {
52 | userAttributes.add(key to value)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/model/AccessToken.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.model
18 |
19 | import com.google.gson.annotations.SerializedName
20 | import java.text.SimpleDateFormat
21 | import java.util.Date
22 | import java.util.Locale
23 | import java.util.TimeZone
24 |
25 | /**
26 | * @author karacca
27 | * @date 22.07.2022
28 | */
29 |
30 | internal data class AccessToken(
31 | @SerializedName("token")
32 | val token: String? = null,
33 | @SerializedName("expires_at")
34 | val expiresAt: String? = null
35 | ) {
36 |
37 | fun isValid(): Boolean {
38 | if (token == null || expiresAt == null) {
39 | return false
40 | }
41 |
42 | val dateFormat = SimpleDateFormat(DATE_PATTERN, Locale.getDefault())
43 | dateFormat.timeZone = TimeZone.getTimeZone("UTC")
44 | return dateFormat.parse(expiresAt)!! > Date()
45 | }
46 |
47 | companion object {
48 | @Suppress("SpellCheckingInspection")
49 | private const val DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/ui/widget/HorizontalItemDecorator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.ui.widget
18 |
19 | import android.graphics.Rect
20 | import android.view.View
21 | import androidx.recyclerview.widget.RecyclerView
22 |
23 | /**
24 | * @author karacca
25 | * @date 28.07.2022
26 | */
27 |
28 | internal class HorizontalItemDecorator(
29 | private val spacing: Int
30 | ) : RecyclerView.ItemDecoration() {
31 |
32 | override fun getItemOffsets(
33 | outRect: Rect,
34 | view: View,
35 | parent: RecyclerView,
36 | state: RecyclerView.State
37 | ) {
38 | super.getItemOffsets(outRect, view, parent, state)
39 |
40 | val position = parent.getChildLayoutPosition(view)
41 | val isFirstItem = position == 0
42 |
43 | @Suppress("UNUSED_VARIABLE")
44 | val isLastItem = position == (parent.adapter?.itemCount ?: 1) - 1
45 |
46 | outRect.right = spacing
47 | outRect.left = if (!isFirstItem) {
48 | spacing
49 | } else {
50 | 0
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/repository/ImageRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.repository
18 |
19 | import android.net.Uri
20 | import androidx.core.net.toFile
21 | import com.karacca.beetle.BuildConfig
22 | import com.karacca.beetle.data.model.Image
23 | import com.karacca.beetle.data.service.ImageService
24 | import okhttp3.MediaType.Companion.toMediaType
25 | import okhttp3.MultipartBody
26 | import okhttp3.RequestBody.Companion.asRequestBody
27 | import okhttp3.RequestBody.Companion.toRequestBody
28 |
29 | /**
30 | * @author karacca
31 | * @date 8.08.2022
32 | */
33 |
34 | internal class ImageRepository {
35 | private val imageService = ImageService.newInstance()
36 |
37 | suspend fun uploadImage(screenshot: Uri): Image {
38 | val file = screenshot.toFile()
39 | return imageService.uploadImage(
40 | BuildConfig.FREE_IMAGE_API_KEY.toRequestBody(),
41 | MultipartBody.Part.createFormData(
42 | "source",
43 | file.name,
44 | file.asRequestBody("image/*".toMediaType())
45 | )
46 | )
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/beetle/src/main/res/layout/item_label.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
23 |
24 |
29 |
30 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/beetle/src/main/res/layout/item_assignee.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
23 |
24 |
29 |
30 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/data/service/ImageService.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.data.service
18 |
19 | import com.google.gson.Gson
20 | import com.karacca.beetle.BuildConfig
21 | import com.karacca.beetle.data.model.Image
22 | import okhttp3.MultipartBody
23 | import okhttp3.OkHttpClient
24 | import okhttp3.RequestBody
25 | import okhttp3.logging.HttpLoggingInterceptor
26 | import retrofit2.Retrofit
27 | import retrofit2.converter.gson.GsonConverterFactory
28 | import retrofit2.http.Multipart
29 | import retrofit2.http.POST
30 | import retrofit2.http.Part
31 |
32 | /**
33 | * @author karacca
34 | * @date 28.07.2022
35 | */
36 |
37 | internal interface ImageService {
38 |
39 | @Multipart
40 | @POST("upload")
41 | suspend fun uploadImage(
42 | @Part("key") key: RequestBody,
43 | @Part image: MultipartBody.Part
44 | ): Image
45 |
46 | companion object {
47 | private const val BASE_URL = "https://freeimage.host/api/1/"
48 |
49 | fun newInstance(): ImageService {
50 | val loggingInterceptor = HttpLoggingInterceptor().apply {
51 | setLevel(
52 | if (BuildConfig.DEBUG) {
53 | HttpLoggingInterceptor.Level.BODY
54 | } else {
55 | HttpLoggingInterceptor.Level.NONE
56 | }
57 | )
58 | }
59 |
60 | val okHttpClient = OkHttpClient.Builder()
61 | .addInterceptor(loggingInterceptor)
62 | .build()
63 |
64 | return Retrofit.Builder()
65 | .client(okHttpClient)
66 | .baseUrl(BASE_URL)
67 | .addConverterFactory(GsonConverterFactory.create(Gson()))
68 | .build()
69 | .create(ImageService::class.java)
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/utils/MarkdownUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.utils
18 |
19 | import android.content.Context
20 | import com.karacca.beetle.R
21 |
22 | /**
23 | * @author karacca
24 | * @date 8.08.2022
25 | */
26 |
27 | internal object MarkdownUtils {
28 |
29 | fun createDescription(
30 | context: Context,
31 | description: String,
32 | imageUrl: String?,
33 | appAndDeviceData: List>,
34 | userAttributes: List>
35 | ): String {
36 | val sb = StringBuilder()
37 | sb.appendLine("## ${context.getString(R.string.description)}")
38 | sb.appendLine(description)
39 |
40 | if (appAndDeviceData.isNotEmpty()) {
41 | sb.appendLine("## ${context.getString(R.string.app_and_device_data)}")
42 | val property = context.getString(R.string.key)
43 | val value = context.getString(R.string.value)
44 | sb.appendLine("|$property|$value|")
45 | sb.appendLine("|:-|:-|")
46 |
47 | for ((k, v) in appAndDeviceData) {
48 | sb.appendLine("|**$k**|$v|")
49 | }
50 | }
51 |
52 | if (userAttributes.isNotEmpty()) {
53 | sb.appendLine("## ${context.getString(R.string.user_attributes)}")
54 | val key = context.getString(R.string.key)
55 | val value = context.getString(R.string.value)
56 | sb.appendLine("|$key|$value|")
57 | sb.appendLine("|:-|:-|")
58 |
59 | for ((k, v) in userAttributes) {
60 | sb.appendLine("|**$k**|$v|")
61 | }
62 | }
63 |
64 | if (imageUrl != null) {
65 | sb.appendLine("## ${context.getString(R.string.feedback_screenshot_title)}")
66 | sb.appendLine("")
67 | }
68 |
69 | return sb.toString()
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/beetle/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 | Send Feedback
16 | Tap here to send feedback
17 | Thank you for your feedback #%1$d
18 | Tap here to see the details
19 |
20 | Title:
21 | Assignees:
22 | Labels:
23 | Give a short description
24 | Describe the issue you are experiencing.
25 | Please detail as much information as possible regarding your issue.
26 | Screenshot
27 | Tap here to highlight or hide info
28 | System Logs
29 | Tap here to view
30 |
31 | Description
32 | Key
33 | Value
34 | App & Device Data
35 | User Attributes
36 | App ID
37 | App Version
38 | Build Type
39 | Device
40 | OS Version
41 | Language
42 | Display
43 | Landscape
44 | Portrait
45 |
46 | Something went wrong
47 | Feedback Results
48 | Providing extra information
49 | to users about their feedbacks
50 |
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Beetle
2 |
3 | [](https://github.com/karacca/beetle/actions/workflows/Build.yaml)
4 | [](https://search.maven.org/artifact/com.karacca/beetle)
5 | [](https://www.apache.org/licenses/LICENSE-2.0)
6 |
7 | Collect feedback & bug reports on your Android apps into your GitHub Issues.
8 |
9 | ## Introduction & Features
10 |
11 | Beetle is a lightweight Android library that enables your users to submit feedback from their applications. It uses GitHub API and collect users feedbacks as GitHub Issues like [this one](https://github.com/karacca/beetle/issues/30).
12 |
13 | * Shake gesture detection for starting a feedback process
14 | * Collect information about the device. You can also add extra information you may add using `Beetle.configure()`
15 | * Users can add Title & Description about the Issue they are having
16 | * Users can assign developers & labels to the Issue
17 | * Current screenshot will be added to the Issue and also can be edited by the user
18 | * JIRA Integration (Coming soon 🚀)
19 |
20 | ## Screenshots
21 |
22 |
23 |
24 | ## Download & Quick Start
25 |
26 | 1. Install [Beetle](https://github.com/marketplace/beetle-app) to your GitHub repository so it can take action on your behalf and create Issues
27 | 2. Add Beetle dependency to your Android app
28 | ```kotlin
29 | dependencies {
30 | implementation("com.karacca:beetle:2.0.1")
31 | }
32 | ```
33 | 3. Initialize Beetle inside your Application
34 | ```kotlin
35 | class MyApplication : Application() {
36 |
37 | override fun onCreate() {
38 | super.onCreate()
39 | Beetle.init(this, "username", "repository")
40 | }
41 | }
42 | ```
43 | 4. [Optional] Make configurations and add additional data
44 | ```kotlin
45 | Beetle.configure {
46 | enableAssignees = true
47 | enableLabels = true
48 | key("user_id", user.id)
49 | }
50 | ```
51 |
52 | ## License
53 |
54 | Copyright 2022 Omer Karaca
55 |
56 | Licensed under the Apache License, Version 2.0 (the "License");
57 | you may not use this file except in compliance with the License.
58 | You may obtain a copy of the License at
59 |
60 | https://www.apache.org/licenses/LICENSE-2.0
61 |
62 | Unless required by applicable law or agreed to in writing, software
63 | distributed under the License is distributed on an "AS IS" BASIS,
64 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65 | See the License for the specific language governing permissions and
66 | limitations under the License.
67 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/utils/CollectDataTask.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | @file:Suppress("DEPRECATION")
18 |
19 | package com.karacca.beetle.utils
20 |
21 | /**
22 | * @author karacca
23 | * @date 17.07.2022
24 | */
25 |
26 | import android.annotation.SuppressLint
27 | import android.app.Activity
28 | import android.content.Context
29 | import android.graphics.Bitmap
30 | import android.net.Uri
31 | import android.os.AsyncTask
32 | import android.util.Log
33 | import androidx.annotation.WorkerThread
34 | import java.io.File
35 |
36 | @Suppress("DEPRECATION")
37 | @SuppressLint("StaticFieldLeak")
38 | internal class CollectDataTask(
39 | private var activity: Activity?,
40 | private var listener: OnCollectDataTaskListener
41 | ) : AsyncTask() {
42 |
43 | @Deprecated("Deprecated in Java")
44 | override fun doInBackground(vararg params: Bitmap?): Uri? {
45 | if (activity == null)
46 | return null
47 |
48 | val root = getScreenshotDirectoryRoot(activity!!) ?: return null
49 | val directory = File(root)
50 | if (directory.exists()) {
51 | val oldFiles = directory.listFiles()
52 | if (oldFiles != null && oldFiles.isNotEmpty()) {
53 | for (oldScreenShot in oldFiles) {
54 | if (!oldScreenShot.delete()) {
55 | Log.e(TAG, "Could not delete old screenshot: $oldScreenShot")
56 | }
57 | }
58 | }
59 | }
60 |
61 | var uri: Uri? = null
62 | val bitmap = if (params.isEmpty()) null else params[0]
63 |
64 | bitmap?.let {
65 | val screenShotFile = BitmapUtils.writeBitmapToFile(bitmap, directory)
66 | uri = Uri.fromFile(screenShotFile)
67 | }
68 |
69 | return uri
70 | }
71 |
72 | @Deprecated("Deprecated in Java")
73 | override fun onPostExecute(result: Uri?) {
74 | super.onPostExecute(result)
75 | listener.onDataReady(result)
76 | }
77 |
78 | interface OnCollectDataTaskListener {
79 | fun onDataReady(data: Uri?)
80 | }
81 |
82 | companion object {
83 | const val TAG = "CollectDataTask"
84 | private const val SCREENSHOT_DIRECTORY = "/screenshots"
85 |
86 | @WorkerThread
87 | fun getScreenshotDirectoryRoot(context: Context) =
88 | if (context.filesDir != null) "${context.filesDir}$SCREENSHOT_DIRECTORY" else null
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/ui/adapter/AssigneeAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.ui.adapter
18 |
19 | import android.view.LayoutInflater
20 | import android.view.View
21 | import android.view.ViewGroup
22 | import androidx.appcompat.widget.AppCompatImageView
23 | import androidx.appcompat.widget.LinearLayoutCompat
24 | import androidx.recyclerview.widget.DiffUtil
25 | import androidx.recyclerview.widget.ListAdapter
26 | import androidx.recyclerview.widget.RecyclerView
27 | import coil.load
28 | import coil.transform.RoundedCornersTransformation
29 | import com.google.android.material.textview.MaterialTextView
30 | import com.karacca.beetle.R
31 | import com.karacca.beetle.data.model.Collaborator
32 |
33 | /**
34 | * @author karacca
35 | * @date 27.07.2022
36 | */
37 |
38 | internal class AssigneeAdapter(
39 | private val listener: (Int) -> Unit
40 | ) : ListAdapter(CollaboratorDiff) {
41 |
42 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
43 | LayoutInflater.from(parent.context).inflate(
44 | R.layout.item_assignee,
45 | parent,
46 | false
47 | )
48 | )
49 |
50 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
51 | holder.bind(getItem(position))
52 | holder.itemView.setOnClickListener { listener.invoke(position) }
53 | }
54 |
55 | inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
56 |
57 | private val rootLayout = itemView.findViewById(R.id.layout_root)
58 | private val textView = itemView.findViewById(R.id.text_view)
59 | private val imageView = itemView.findViewById(R.id.image_view)
60 |
61 | fun bind(collaborator: Collaborator) {
62 | rootLayout.isSelected = collaborator.selected
63 | textView.text = collaborator.login
64 | imageView.load(collaborator.avatarUrl) {
65 | transformations(RoundedCornersTransformation(24f))
66 | }
67 | }
68 | }
69 |
70 | object CollaboratorDiff : DiffUtil.ItemCallback() {
71 | override fun areItemsTheSame(oldItem: Collaborator, newItem: Collaborator): Boolean {
72 | return oldItem.id == newItem.id
73 | }
74 |
75 | override fun areContentsTheSame(oldItem: Collaborator, newItem: Collaborator): Boolean {
76 | return false
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/beetle/src/main/kotlin/com/karacca/beetle/ui/adapter/LabelAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Omer Karaca
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.karacca.beetle.ui.adapter
18 |
19 | import android.graphics.Color
20 | import android.view.LayoutInflater
21 | import android.view.View
22 | import android.view.ViewGroup
23 | import androidx.appcompat.widget.AppCompatImageView
24 | import androidx.appcompat.widget.LinearLayoutCompat
25 | import androidx.core.graphics.drawable.toDrawable
26 | import androidx.recyclerview.widget.DiffUtil
27 | import androidx.recyclerview.widget.ListAdapter
28 | import androidx.recyclerview.widget.RecyclerView
29 | import coil.load
30 | import coil.transform.RoundedCornersTransformation
31 | import com.google.android.material.textview.MaterialTextView
32 | import com.karacca.beetle.R
33 | import com.karacca.beetle.data.model.Label
34 |
35 | /**
36 | * @author karacca
37 | * @date 28.07.2022
38 | */
39 |
40 | internal class LabelAdapter(
41 | private val listener: (Int) -> Unit
42 | ) : ListAdapter