Skip to content

Commit

Permalink
Merge pull request #3 from Archrahkshi/translate
Browse files Browse the repository at this point in the history
Trailing spaces in a mock, kinda necessary
  • Loading branch information
Archrahkshi authored Dec 2, 2020
2 parents 2d6d27e + f5523d9 commit 6254d0e
Show file tree
Hide file tree
Showing 73 changed files with 181 additions and 769 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
/captures
.externalNativeBuild
.cxx

/spotify-app-remote/build/
/spotify-auth/build/
5 changes: 3 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ dependencies {
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

implementation("com.squareup.okhttp3:okhttp:4.9.0")
implementation "com.squareup.okhttp3:okhttp:4.9.0"
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.4.1'

implementation('com.ibm.watson:ibm-watson:8.6.3')
implementation 'com.ibm.watson:ibm-watson:8.6.3'
}
9 changes: 6 additions & 3 deletions app/src/main/java/com/archrahkshi/spotifine/data/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const val ALBUM_FROM_PLAYLIST_DISTINCTION = 5
const val ALBUMS = "albums"
const val ARTIST_FROM_ME_DISTINCTION = 2
const val ARTISTS = "artists"
const val CLIENT_ID = "fbe0ec189f0247f99909e75530bac38e"
const val DURATION = "duration"
const val FROM_ARTIST = "from_artist"
const val FROM_ME = "from_me"
Expand All @@ -15,6 +14,10 @@ const val LIST_TYPE = "list_type"
const val NAME = "name"
const val ONE_DIGIT = 9
const val PLAYLISTS = "playlists"
const val REDIRECT_URI = "http://localhost:8888/callback/"
const val REQUEST_CODE = 1337
const val SPOTIFY_CLIENT_ID = "fbe0ec189f0247f99909e75530bac38e"
const val SPOTIFY_REDIRECT_URI = "http://localhost:8888/callback/"
const val SPOTIFY_REQUEST_CODE = 1337
const val URL = "url"
const val TRANSLATOR_API_KEY = "Nbo7_ne4t1F0JTjcmCS_06yGOuJNdEc7efawvtOHS9i_"
const val TRANSLATOR_URL = "https://api.eu-gb.language-translator.watson.cloud.ibm.com"
const val TRANSLATOR_VERSION = "2018-05-01"
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ class TracksAdapter(
textViewTrackDuration.text = track.duration.milliseconds.toComponents { HH, mm, ss, _ ->
var duration = ""
if (HH > 0) duration += "$HH:"
if (duration.isNotEmpty() && mm < ONE_DIGIT) duration += '0'
if (duration.isNotEmpty() && mm <= ONE_DIGIT) duration += '0'
duration += "$mm:"
if (duration.isNotEmpty() && ss < ONE_DIGIT) duration += '0'
if (duration.isNotEmpty() && ss <= ONE_DIGIT) duration += '0'
"$duration$ss"
}
layoutItemList.setOnClickListener { clickListener(track) }
Expand Down
153 changes: 114 additions & 39 deletions app/src/main/java/com/archrahkshi/spotifine/ui/LyricsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.archrahkshi.spotifine.R
import com.archrahkshi.spotifine.data.LyricsAdapter
import com.archrahkshi.spotifine.data.TRANSLATOR_API_KEY
import com.archrahkshi.spotifine.data.TRANSLATOR_URL
import com.archrahkshi.spotifine.data.TRANSLATOR_VERSION
import com.ibm.cloud.sdk.core.security.IamAuthenticator
import com.ibm.watson.language_translator.v3.LanguageTranslator
import com.ibm.watson.language_translator.v3.model.TranslateOptions
import com.ibm.watson.language_translator.v3.util.Language.RUSSIAN
import kotlinx.android.synthetic.main.fragment_lyrics.buttonTranslate
import kotlinx.android.synthetic.main.fragment_lyrics.recyclerViewLyrics
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Locale
import kotlin.coroutines.CoroutineContext

class LyricsFragment(private var isLyricsTranslated: Boolean) : Fragment() {
class LyricsFragment(
private val isLyricsTranslated: Boolean,
override val coroutineContext: CoroutineContext = Dispatchers.Main.immediate
) : Fragment(), CoroutineScope {

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -21,46 +37,105 @@ class LyricsFragment(private var isLyricsTranslated: Boolean) : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val lyricsOriginal = listOf(
"Hoort u mij toe",
"Als ik u verhaal",
"Van oude sagen",
"Van reuzentijd",
"",
"Vertel ons de sagen",
"Van oeroude machten",
"In 't Gelderse land",
"Wat weet u nog meer?",
)
val lyricsTranslated = listOf(
"Послушай меня",
"Если я скажу тебе",
"Из старых саг",
"Из гигантских времен",
"",
"Расскажи нам саги",
"Древних сил",
"В стране Гелдерланд",
"Что еще ты знаешь?",
)
val lyrics = if (isLyricsTranslated) lyricsTranslated else lyricsOriginal
launch {
val originalLyrics = getOriginalLyrics()
if (isLyricsTranslated) {
val (detectedLanguage, translatedLyrics) = getTranslatedLyrics(originalLyrics)
val appLocale = Locale(RUSSIAN)
buttonTranslate.text = getString(
R.string.detected_language,
Locale(detectedLanguage).getDisplayLanguage(appLocale),
appLocale.getDisplayLanguage(appLocale)
)
recyclerViewLyrics.adapter = LyricsAdapter(translatedLyrics.split('\n'))
} else {
buttonTranslate.text = getString(R.string.translate)
recyclerViewLyrics.adapter = LyricsAdapter(originalLyrics.split('\n'))
}

val detectedLanguage = "..." // TODO
val toRussian = "$detectedLanguage > ${resources.getString(R.string.russian)}"
buttonTranslate.text =
if (isLyricsTranslated)
toRussian
else
resources.getString(R.string.translate)

buttonTranslate.setOnClickListener {
isLyricsTranslated = !isLyricsTranslated
fragmentManager?.beginTransaction()?.replace(
R.id.frameLayoutPlayer,
LyricsFragment(isLyricsTranslated)
)?.commit()
buttonTranslate.setOnClickListener {
fragmentManager?.beginTransaction()?.replace(
R.id.frameLayoutPlayer,
LyricsFragment(!isLyricsTranslated)
)?.commit()
}
}
}

recyclerViewLyrics.adapter = LyricsAdapter(lyrics)
private suspend fun getOriginalLyrics() = withContext(Dispatchers.IO) {
"""
Flying over darkened skies the battle will call
Distant angels crying in the eye of the storm
And the world falls under the starlight shining from heavens below
Long years of pain and sorrow searching for more
Cry for the touch of angels never before
And the stars fall on the horizon onwards and up through the pain
Ride the wind and fight the demon steel shining bright
Standing together forever onwards flames burning strong
Hot wind in hell of pain and sorrow now and ever onwards
We stare into the dawn of a new world
[Pre-Chorus]
Cry out for the fallen heroes
Lost in time ago
In our minds they still belong
When the sands of time are gone
[Chorus]
Rise over shadow mountains blazing with power
Crossing valleys endless tears in unity we stand
Far and wide across the land the victory is ours
On towards the gates of reason
Fight for the truth and the freedom
Gloria
Searching through the memories to open the door
Living on the edge of life like never before
And the ground chants under the moonlight facing their fears all the same
Heavens fear now open wide and up for the the call
All in stark reality the angels will fall
And the world cries out for the silence lost in the voices unknown
Blinded by the force of evil cries into the night
Never before have they seen the darkness now they are all gone
Out from the shadows storming on the wings of revelations
Your soul will feel no mercy come the dawn
Hold on for the morning after
Never to let go
In the fire's burning strong
When the tides of time roll on
[Chorus]
[Pre-Chorus]
[Chorus]
""".trimIndent()
}

private suspend fun getTranslatedLyrics(
lyricsOriginal: String
) = withContext(Dispatchers.IO) {
val result = LanguageTranslator(
TRANSLATOR_VERSION,
IamAuthenticator(TRANSLATOR_API_KEY)
).apply {
serviceUrl = TRANSLATOR_URL
}.translate(
TranslateOptions.Builder()
// Line separators must be doubled for the lyrics to be translated line by line,
// not as a uniform text
.addText(lyricsOriginal.replace("\n", "\n\n"))
.target(RUSSIAN)
.build()
).execute().result
Pair(
result.detectedLanguage,
// Returning to the original line separators
result.translations.first().translation.replace("\n\n", "\n")
)
}
}
14 changes: 7 additions & 7 deletions app/src/main/java/com/archrahkshi/spotifine/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.archrahkshi.spotifine.R
import com.archrahkshi.spotifine.data.ACCESS_TOKEN
import com.archrahkshi.spotifine.data.CLIENT_ID
import com.archrahkshi.spotifine.data.REDIRECT_URI
import com.archrahkshi.spotifine.data.REQUEST_CODE
import com.archrahkshi.spotifine.data.SPOTIFY_CLIENT_ID
import com.archrahkshi.spotifine.data.SPOTIFY_REDIRECT_URI
import com.archrahkshi.spotifine.data.SPOTIFY_REQUEST_CODE
import com.spotify.sdk.android.auth.AuthorizationClient
import com.spotify.sdk.android.auth.AuthorizationRequest
import com.spotify.sdk.android.auth.AuthorizationResponse
Expand All @@ -21,11 +21,11 @@ class MainActivity : AppCompatActivity() {

AuthorizationClient.openLoginActivity(
this,
REQUEST_CODE,
SPOTIFY_REQUEST_CODE,
AuthorizationRequest.Builder(
CLIENT_ID,
SPOTIFY_CLIENT_ID,
AuthorizationResponse.Type.TOKEN,
REDIRECT_URI
SPOTIFY_REDIRECT_URI
).apply {
setScopes(arrayOf("streaming", "user-library-read", "user-follow-read"))
}.build()
Expand All @@ -35,7 +35,7 @@ class MainActivity : AppCompatActivity() {
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)

if (requestCode == REQUEST_CODE) {
if (requestCode == SPOTIFY_REQUEST_CODE) {
val response: AuthorizationResponse? =
AuthorizationClient.getResponse(resultCode, intent)
when (response?.type) {
Expand Down
18 changes: 8 additions & 10 deletions app/src/main/java/com/archrahkshi/spotifine/ui/PlayerActivity.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.archrahkshi.spotifine.ui

import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener
import androidx.appcompat.app.AppCompatActivity
import com.archrahkshi.spotifine.R
import com.archrahkshi.spotifine.data.CLIENT_ID
import com.archrahkshi.spotifine.data.DURATION
import com.archrahkshi.spotifine.data.ID
import com.archrahkshi.spotifine.data.REDIRECT_URI
import com.archrahkshi.spotifine.data.SPOTIFY_CLIENT_ID
import com.archrahkshi.spotifine.data.SPOTIFY_REDIRECT_URI
import com.spotify.android.appremote.api.ConnectionParams
import com.spotify.android.appremote.api.Connector
import com.spotify.android.appremote.api.SpotifyAppRemote
Expand All @@ -35,15 +34,14 @@ class PlayerActivity : AppCompatActivity() {
val duration = intent.getLongExtra(DURATION, 0)
Log.wtf("id", id?.toString())
Log.wtf("duration", duration.toString())
val connectionParams = ConnectionParams.Builder(CLIENT_ID)
.setRedirectUri(REDIRECT_URI)
val connectionParams = ConnectionParams.Builder(SPOTIFY_CLIENT_ID)
.setRedirectUri(SPOTIFY_REDIRECT_URI)
.showAuthView(true)
.build()
SpotifyAppRemote.connect(
this,
connectionParams,
object : Connector.ConnectionListener {
@SuppressLint("SetTextI18n")
override fun onConnected(spotifyAppRemote: SpotifyAppRemote) {
this@PlayerActivity.pSpotifyAppRemote = spotifyAppRemote
val appRemote = this@PlayerActivity.pSpotifyAppRemote!!
Expand All @@ -52,7 +50,7 @@ class PlayerActivity : AppCompatActivity() {
val seekBar = findViewById<SeekBar>(R.id.seekBar)
seekBar.max = duration.toInt()
var flag = 0
buttonPlay.text = "PLAY"
buttonPlay.text = getString(R.string.play)
seekBar.setOnSeekBarChangeListener(
object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
Expand Down Expand Up @@ -81,17 +79,17 @@ class PlayerActivity : AppCompatActivity() {
0 -> {
appRemote.playerApi.play("spotify:track:$id")
flag = 1
buttonPlay.text = "PAUSE"
buttonPlay.text = getString(R.string.pause)
}
1 -> {
appRemote.playerApi.pause()
flag = 2
buttonPlay.text = "PLAY"
buttonPlay.text = getString(R.string.play)
}
2 -> {
appRemote.playerApi.resume()
flag = 1
buttonPlay.text = "PAUSE"
buttonPlay.text = getString(R.string.pause)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class TracksFragment(
recyclerViewTracks.adapter = TracksAdapter(
createTrackLists(args?.getString(URL), args?.getString(ACCESS_TOKEN))
) {
Log.i("Track", it.toString())
Log.i("Track clicked", it.toString())
startActivity(
Intent(activity, PlayerActivity::class.java).apply {
putExtra(ID, it.id)
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/layout/fragment_library_lists.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
android:id="@+id/recyclerViewLists"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarThumbVertical="@android:color/white"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="20"
tools:listitem="@layout/item_library_list" />

</FrameLayout>
4 changes: 4 additions & 0 deletions app/src/main/res/layout/fragment_lyrics.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:scrollbarThumbVertical="@android:color/white"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:itemCount="50"
tools:listitem="@layout/item_lyrics_line" />

<Button
android:id="@+id/buttonTranslate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:text="@string/loading"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/res/layout/fragment_tracks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:padding="4dp">
android:padding="4dp"
android:scrollbarThumbVertical="@android:color/white"
android:scrollbars="vertical">

<LinearLayout
android:layout_width="match_parent"
Expand Down Expand Up @@ -74,6 +76,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="20"
tools:listitem="@layout/item_track" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
Loading

0 comments on commit 6254d0e

Please sign in to comment.