Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
### 環境

- IDE:Android Studio Ladybug | 2024.2.1 Patch 3
- Kotlin: 2.0.0
- Kotlin: 2.0.21
- Java:17
- Gradle:8.9
- minSdk:23
Expand Down
13 changes: 10 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
id 'kotlin-parcelize'
id 'androidx.navigation.safeargs.kotlin'
id("org.jlleitschuh.gradle.ktlint") version "12.1.2"
id 'com.google.dagger.hilt.android'
}

android {
Expand All @@ -28,11 +29,11 @@ android {
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '17'
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
Expand Down Expand Up @@ -63,10 +64,16 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
implementation "com.google.dagger:hilt-android:2.55"
kapt "com.google.dagger:hilt-compiler:2.55"

// Retrofit
implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.squareup.moshi:moshi-kotlin:1.14.0")
}

kapt {
correctErrorTypes true
}
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AndroidEngineerCodeCheck"
android:fullBackupContent="@xml/backup_descriptor">
android:fullBackupContent="@xml/backup_descriptor"
android:name=".CodeCheckApplication">
<activity
android:name="jp.co.yumemi.android.code_check.TopActivity"
android:exported="true">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package jp.co.yumemi.android.code_check

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class CodeCheckApplication : Application()
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package jp.co.yumemi.android.code_check

import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import jp.co.yumemi.android.code_check.features.github.api.GitHubServiceApi
import jp.co.yumemi.android.code_check.features.github.api.GitHubServiceApiImpl
import jp.co.yumemi.android.code_check.features.github.reposiotory.GitHubServiceRepository
import jp.co.yumemi.android.code_check.features.github.reposiotory.GitHubServiceRepositoryImpl
import jp.co.yumemi.android.code_check.features.github.usecase.GitHubServiceUsecase
import jp.co.yumemi.android.code_check.features.github.usecase.GitHubServiceUsecaseImpl
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
abstract class GitHubUsecaseModule {
@Singleton
@Binds
abstract fun provideGitHubServiceUsecase(impl: GitHubServiceUsecaseImpl): GitHubServiceUsecase
}

@Module
@InstallIn(SingletonComponent::class)
abstract class GitHubRepositoryModule {
@Singleton
@Binds
abstract fun provideGitHubServiceRepository(impl: GitHubServiceRepositoryImpl): GitHubServiceRepository

companion object {
@Provides
@Singleton
fun provideGitHubServiceApi(): GitHubServiceApi {
return GitHubServiceApiImpl()
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
package jp.co.yumemi.android.code_check

import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class TopActivity : AppCompatActivity(R.layout.activity_top)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package jp.co.yumemi.android.code_check
package jp.co.yumemi.android.code_check.core.entity

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
/*
* Copyright © 2021 YUMEMI Inc. All rights reserved.
*/
package jp.co.yumemi.android.code_check
package jp.co.yumemi.android.code_check.core.presenter.detail

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import coil.load
import dagger.hilt.android.AndroidEntryPoint
import jp.co.yumemi.android.code_check.R
import jp.co.yumemi.android.code_check.core.entity.RepositoryItem
import jp.co.yumemi.android.code_check.databinding.FragmentRepositoryDetailBinding

@AndroidEntryPoint
class RepositoryDetailFragment : Fragment(R.layout.fragment_repository_detail) {
private val args: RepositoryDetailFragmentArgs by navArgs()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package jp.co.yumemi.android.code_check
package jp.co.yumemi.android.code_check.core.presenter.search

import android.view.LayoutInflater
import android.view.View
Expand All @@ -7,6 +7,8 @@ import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import jp.co.yumemi.android.code_check.R
import jp.co.yumemi.android.code_check.core.entity.RepositoryItem

/**
* DiffUtilの実装
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
/*
* Copyright © 2021 YUMEMI Inc. All rights reserved.
*/
package jp.co.yumemi.android.code_check
package jp.co.yumemi.android.code_check.core.presenter.search

import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import jp.co.yumemi.android.code_check.R
import jp.co.yumemi.android.code_check.core.entity.RepositoryItem
import jp.co.yumemi.android.code_check.core.utils.DialogHelper
import jp.co.yumemi.android.code_check.databinding.FragmentRepositorySearchBinding

@AndroidEntryPoint
class RepositorySearchFragment : Fragment(R.layout.fragment_repository_search) {
private var _binding: FragmentRepositorySearchBinding? = null
private val binding get() = _binding ?: throw IllegalStateException("Binding is null")
private lateinit var viewModel: RepositorySearchViewModel
private val viewModel: RepositorySearchViewModel by viewModels()

private val adapter by lazy {
RepositoryListRecyclerViewAdapter(
Expand All @@ -34,7 +36,7 @@ class RepositorySearchFragment : Fragment(R.layout.fragment_repository_search) {
) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentRepositorySearchBinding.bind(view)
viewModel = ViewModelProvider(this)[RepositorySearchViewModel::class.java]
// viewModel = ViewModelProvider(this)[RepositorySearchViewModel::class.java]

observeViewModel()
setupRecyclerView()
Expand All @@ -52,7 +54,8 @@ class RepositorySearchFragment : Fragment(R.layout.fragment_repository_search) {

private fun setupRecyclerView() {
val layoutManager = LinearLayoutManager(requireContext())
val dividerItemDecoration = DividerItemDecoration(requireContext(), layoutManager.orientation)
val dividerItemDecoration =
DividerItemDecoration(requireContext(), layoutManager.orientation)

binding.recyclerView.apply {
this.layoutManager = layoutManager
Expand All @@ -64,7 +67,7 @@ class RepositorySearchFragment : Fragment(R.layout.fragment_repository_search) {
private fun setupSearchInput() {
binding.searchInputText.setOnEditorActionListener { editText, action, _ ->
if (action == EditorInfo.IME_ACTION_SEARCH) {
viewModel.searchRepositories(editText.text.toString().trim())
viewModel.searchRepositories(editText.text.toString().trim(), requireContext())
true
} else {
false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package jp.co.yumemi.android.code_check.core.presenter.search

import android.content.Context
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import jp.co.yumemi.android.code_check.core.entity.RepositoryItem
import jp.co.yumemi.android.code_check.features.github.reposiotory.NetworkException
import jp.co.yumemi.android.code_check.features.github.usecase.GitHubServiceUsecaseImpl
import jp.co.yumemi.android.code_check.features.github.utils.NetworkResult
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
* RepositorySearchFragmentで利用するリポジトリ検索用のViewModel
*/
@HiltViewModel
class RepositorySearchViewModel
@Inject
constructor(
private val networkRepository: GitHubServiceUsecaseImpl,
) : ViewModel() {
private val _errorMessage = MutableLiveData<String?>()
val errorMessage: LiveData<String?> get() = _errorMessage

private val _searchResults = MutableLiveData<List<RepositoryItem>>()
val searchResults: LiveData<List<RepositoryItem>> get() = _searchResults

/**
* GitHubのレポジトリ検索を行う
* @param query 検索キーワード
*/
fun searchRepositories(
query: String,
context: Context,
) {
if (query.isBlank()) {
_errorMessage.postValue("検索キーワードを入力してください。")
return
}
viewModelScope.launch {
try {
val results = networkRepository.fetchSearchResults(query, context)
if (results is NetworkResult.Error) {
_errorMessage.postValue(results.exception.message)
return@launch
}
if (results is NetworkResult.Success) {
_searchResults.postValue(results.data)
}
} catch (e: NetworkException) {
Log.e("NetworkException", e.message, e)
_errorMessage.postValue(e.message)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package jp.co.yumemi.android.code_check
package jp.co.yumemi.android.code_check.core.utils

import android.app.AlertDialog
import android.content.Context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ package jp.co.yumemi.android.code_check.features.github.api

import jp.co.yumemi.android.code_check.features.github.entity.RepositoryList

interface GitHubRepositoryApi {
interface GitHubServiceApi {
suspend fun getRepository(searchWord: String): RepositoryList
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Query

interface GitHubRepositoryApiBuilderInterface {
interface GitHubServiceApiBuilderInterface {
@GET("/search/repositories")
suspend fun getRepository(
@Query("q") searchWord: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory

class GitHubRepositoryApiImpl : GitHubRepositoryApi {
class GitHubServiceApiImpl : GitHubServiceApi {
companion object {
val client =
OkHttpClient.Builder()
Expand All @@ -37,7 +37,7 @@ class GitHubRepositoryApiImpl : GitHubRepositoryApi {
.client(client)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
.create(GitHubRepositoryApiBuilderInterface::class.java)
.create(GitHubServiceApiBuilderInterface::class.java)
}

override suspend fun getRepository(searchWord: String): RepositoryList {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package jp.co.yumemi.android.code_check.features.github.reposiotory

import jp.co.yumemi.android.code_check.core.entity.RepositoryItem
import jp.co.yumemi.android.code_check.features.github.utils.NetworkResult

interface GitHubServiceRepository {
suspend fun fetchSearchResults(inputText: String): NetworkResult<List<RepositoryItem>>
}
Loading
Loading