diff --git a/app/build.gradle b/app/build.gradle index 7f2c100e1..fad8265a0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,6 +43,7 @@ android { buildConfigField 'String', 'APP_SECRET', credentialsProperties['apiSecret'] buildConfigField 'String', 'APP_KEY', credentialsProperties['apiKey'] buildConfigField 'String', 'GOOGLE_KEY', credentialsProperties['googleKey'] + resValue 'string', 'GOOGLE_API_KEY', credentialsProperties['googleKey'] } signingConfigs { @@ -98,13 +99,13 @@ dependencies { // Support library implementation 'androidx.appcompat:appcompat:1.1.0-alpha01' - implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha01' - implementation "android.arch.work:work-runtime:1.0.0-beta02" + implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha02' + implementation "android.arch.work:work-runtime:1.0.0-beta03" implementation 'androidx.exifinterface:exifinterface:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.preference:preference:1.1.0-alpha02' implementation 'androidx.legacy:legacy-preference-v14:1.0.0' - implementation 'com.google.android.material:material:1.1.0-alpha02' + implementation 'com.google.android.material:material:1.1.0-alpha03' implementation "androidx.preference:preference:1.1.0-alpha02" implementation 'com.takisoft.preferencex:preferencex:1.0.0-alpha2' implementation 'androidx.legacy:legacy-support-v4:1.0.0' @@ -116,7 +117,7 @@ dependencies { implementation 'com.google.android.exoplayer:extension-okhttp:2.6.0' implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0' implementation 'com.google.code.gson:gson:2.8.2' - implementation 'androidx.core:core-ktx:1.1.0-alpha03' + implementation 'androidx.core:core-ktx:1.1.0-alpha04' // Utils implementation 'com.bugsnag:bugsnag-android:4.5.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b879f9648..ca58d1371 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -141,10 +141,7 @@ - + @@ -175,6 +172,12 @@ + + + diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksApi.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksApi.kt index d511e480e..17e6646b9 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksApi.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksApi.kt @@ -38,6 +38,12 @@ interface LinksApi { inputStream: WykopImageFile, linkId: Int, linkComment: Int ): Single + fun relatedAdd( + title: String, + url: String, + plus18: Boolean, + linkId: Int + ): Single fun commentAdd( body: String, embed: String?, diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRepository.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRepository.kt index 3a9176fe2..9b5ec0e84 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRepository.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRepository.kt @@ -164,6 +164,17 @@ class LinksRepository( .compose(ErrorHandlerTransformer()) .map { LinkCommentMapper.map(it, owmContentFilter) } + override fun relatedAdd( + title: String, + url: String, + plus18: Boolean, + linkId: Int + ): Single = + linksApi.addRelated(title, linkId, url, plus18) + .retryWhen(userTokenRefresher) + .compose(ErrorHandlerTransformer()) + .map { RelatedMapper.map(it) } + override fun commentAdd( body: String, plus18: Boolean, diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRetrofitApi.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRetrofitApi.kt index 006073610..910e4081e 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRetrofitApi.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/api/links/LinksRetrofitApi.kt @@ -120,6 +120,15 @@ interface LinksRetrofitApi { @Field("adultmedia") plus18: Boolean ): Single> + @FormUrlEncoded + @POST("/links/relatedadd/{linkId}/appkey/$APP_KEY") + fun addRelated( + @Field("title") body: String, + @Path("linkId") linkId: Int, + @Field("url") url: String, + @Field("plus18") plus18: Boolean + ): Single> + @FormUrlEncoded @POST("/links/commentedit/{linkId}/appkey/$APP_KEY") fun editComment( diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/di/ActivityBuilder.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/di/ActivityBuilder.kt index e05ab8297..fa6517338 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/di/ActivityBuilder.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/di/ActivityBuilder.kt @@ -99,9 +99,6 @@ abstract class ActivityBuilder { @ContributesAndroidInjector(modules = [RelatedModule::class]) abstract fun bindRelatedActivity(): RelatedActivity - @ContributesAndroidInjector(modules = []) - abstract fun bindYoutubeActivity(): YoutubeActivity - @ContributesAndroidInjector(modules = [ProfileModule::class, ProfileFragmentProvider::class]) abstract fun bindProfileActivity(): ProfileActivity diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/dataclass/Notification.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/dataclass/Notification.kt index 3589bed1d..833562818 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/dataclass/Notification.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/dataclass/Notification.kt @@ -1,7 +1,7 @@ package io.github.feelfreelinux.wykopmobilny.models.dataclass open class Notification( - val id: Int, + val id: Long, val author: Author?, val body: String, val date: String, @@ -19,6 +19,6 @@ open class Notification( } override fun hashCode(): Int { - return id + return id.toInt() } } \ No newline at end of file diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/pojo/apiv2/models/NotificationResponse.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/pojo/apiv2/models/NotificationResponse.kt index d978817fd..6794ca0ff 100755 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/pojo/apiv2/models/NotificationResponse.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/models/pojo/apiv2/models/NotificationResponse.kt @@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty @JsonIgnoreProperties(ignoreUnknown = true) data class NotificationResponse( - @JsonProperty("id") val id: Int, + @JsonProperty("id") val id: Long, @JsonProperty("author") val author: AuthorResponse?, @JsonProperty("date") val date: String, @JsonProperty("body") val body: String, diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/LinkHeaderViewHolder.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/LinkHeaderViewHolder.kt index b52b247c8..9eac1ad79 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/LinkHeaderViewHolder.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/adapters/viewholders/LinkHeaderViewHolder.kt @@ -112,9 +112,7 @@ class LinkHeaderViewHolder( description.text = link.description.removeHtml() relatedCountTextView.text = link.relatedCount.toString() relatedCountTextView.setOnClickListener { - if (link.relatedCount > 0) { - navigatorApi.openLinkRelatedActivity(link.id) - } + navigatorApi.openLinkRelatedActivity(link.id) } containerView.setOnClickListener { linkHandlerApi.handleUrl(link.sourceUrl) @@ -179,9 +177,7 @@ class LinkHeaderViewHolder( } link_related.setOnClickListener { - if (link.relatedCount > 0) { - navigatorApi.openLinkRelatedActivity(link.id) - } + navigatorApi.openLinkRelatedActivity(link.id) dialog.dismiss() } link_bury.isVisible = userManagerApi.isUserAuthorized() diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/dialogs/Dialogs.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/dialogs/Dialogs.kt index f1164e0f2..a3f982c8f 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/dialogs/Dialogs.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/dialogs/Dialogs.kt @@ -5,8 +5,10 @@ import android.content.Context import android.view.View import io.github.feelfreelinux.wykopmobilny.R import kotlinx.android.synthetic.main.dialog_edittext.view.* +import kotlinx.android.synthetic.main.dialog_insert_link.view.* typealias formatDialogCallback = (String) -> Unit +typealias addRelatedDialogCallback = (String, String) -> Unit fun editTextFormatDialog(titleId: Int, context: Context, callback: formatDialogCallback): AlertDialog { val editTextLayout = getEditTextView(context) @@ -37,4 +39,14 @@ fun confirmationDialog(context: Context, callback: () -> Unit): AlertDialog { } } +fun addRelatedDialog(context: Context, callback: addRelatedDialogCallback): AlertDialog { + val editTextLayout = View.inflate(context, R.layout.dialog_insert_link, null) + context.createAlertBuilder().run { + setTitle("Dodaj powiÄ…zane") + setView(editTextLayout) + setPositiveButton(android.R.string.ok) { _, _ -> callback.invoke(editTextLayout.link.text.toString(), editTextLayout.description.text.toString()) } + return create() + } +} + private fun getEditTextView(context: Context) = View.inflate(context, R.layout.dialog_edittext, null) \ No newline at end of file diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/embedview/YTPlayer.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/embedview/YTPlayer.kt new file mode 100644 index 000000000..2bf65e80d --- /dev/null +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/embedview/YTPlayer.kt @@ -0,0 +1,326 @@ +package io.github.feelfreelinux.wykopmobilny.ui.modules.embedview + +import android.annotation.SuppressLint +import android.content.Intent +import android.content.pm.ActivityInfo +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.content.res.Configuration +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.view.KeyEvent +import android.widget.FrameLayout.LayoutParams +import android.widget.Toast + +import com.google.android.youtube.player.YouTubeBaseActivity +import com.google.android.youtube.player.YouTubeInitializationResult +import com.google.android.youtube.player.YouTubePlayer +import com.google.android.youtube.player.YouTubePlayer.ErrorReason +import com.google.android.youtube.player.YouTubePlayerView + +import android.content.Context +import android.media.AudioManager +import androidx.core.content.ContextCompat.startActivity +import android.content.pm.ResolveInfo +import android.net.Uri + + +import android.app.Activity +import android.view.View +import android.view.WindowManager +import androidx.annotation.NonNull +import io.github.feelfreelinux.wykopmobilny.GOOGLE_KEY +import java.util.regex.Matcher +import java.util.regex.Pattern + + +object YouTubeUrlParser { + + // (?:youtube(?:-nocookie)?\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11}) + internal val reg = "(?:youtube(?:-nocookie)?\\.com\\/(?:[^\\/\\n\\s]+\\/\\S+\\/|(?:v|e(?:mbed)?)\\/|\\S*?[?&]v=)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})" + + fun getVideoId(@NonNull videoUrl: String): String? { + val pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE) + val matcher = pattern.matcher(videoUrl) + + return if (matcher.find()) matcher.group(1) else null + } + + fun getVideoUrl(@NonNull videoId: String): String { + return "http://youtu.be/$videoId" + } +} + +object StatusBarUtil { + + fun hide(activity: Activity) { + if (Build.VERSION.SDK_INT < 16) { + activity.window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN) + } else { + val decorView = activity.window.decorView + val uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN + decorView.systemUiVisibility = uiOptions + } + } +} + + +object AudioUtil { + + private val mSingletonLock = Any() + private var audioManager: AudioManager? = null + + private fun getInstance(context: Context?): AudioManager? { + synchronized(mSingletonLock) { + if (audioManager != null) + return audioManager + if (context != null) + audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager + return audioManager + } + } + + fun adjustMusicVolume(context: Context, up: Boolean, showInterface: Boolean) { + val direction = if (up) AudioManager.ADJUST_RAISE else AudioManager.ADJUST_LOWER + val flag = AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE or if (showInterface) AudioManager.FLAG_SHOW_UI else 0 + getInstance(context)!!.adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, flag) + } + + fun playKeyClickSound(context: Context, volume: Int) { + if (volume == 0) + return + getInstance(context)!!.playSoundEffect(AudioManager.FX_KEY_CLICK, volume.toFloat() / 100.0f) + } +} + +enum class Orientation { + AUTO, AUTO_START_WITH_LANDSCAPE, ONLY_LANDSCAPE, ONLY_PORTRAIT +} + +class YTPlayer : YouTubeBaseActivity(), YouTubePlayer.OnInitializedListener, YouTubePlayer.OnFullscreenListener, YouTubePlayer.PlayerStateChangeListener { + + private var googleApiKey: String? = null + private var videoId: String? = null + + private var playerStyle: YouTubePlayer.PlayerStyle? = null + private var orientation: Orientation? = null + private var showAudioUi: Boolean = false + private var handleError: Boolean = false + private var animEnter: Int = 0 + private var animExit: Int = 0 + + private var playerView: YouTubePlayerView? = null + private var player: YouTubePlayer? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + initialize() + + playerView = YouTubePlayerView(this) + playerView!!.initialize(googleApiKey, this) + + addContentView(playerView, LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)) + + playerView!!.setBackgroundResource(android.R.color.black) + + StatusBarUtil.hide(this) + } + + private fun initialize() { + try { + val ai = packageManager.getApplicationInfo(packageName, + PackageManager.GET_META_DATA) + val bundle = ai.metaData + googleApiKey = GOOGLE_KEY + } catch (e: PackageManager.NameNotFoundException) { + e.printStackTrace() + } + + if (googleApiKey == null) + throw NullPointerException("Google API key must not be null. Set your api key as meta data in AndroidManifest.xml file.") + + videoId = intent.getStringExtra(EXTRA_VIDEO_ID) + if (videoId == null) + throw NullPointerException("Video ID must not be null") + + playerStyle = YouTubePlayer.PlayerStyle.DEFAULT + + orientation = Orientation.AUTO + + showAudioUi = intent.getBooleanExtra(EXTRA_SHOW_AUDIO_UI, true) + handleError = intent.getBooleanExtra(EXTRA_HANDLE_ERROR, true) + animEnter = intent.getIntExtra(EXTRA_ANIM_ENTER, 0) + animExit = intent.getIntExtra(EXTRA_ANIM_EXIT, 0) + } + + override fun onInitializationSuccess(provider: YouTubePlayer.Provider, + player: YouTubePlayer, + wasRestored: Boolean) { + this.player = player + player.setOnFullscreenListener(this) + player.setPlayerStateChangeListener(this) + + when (orientation) { + Orientation.AUTO -> player.fullscreenControlFlags = (YouTubePlayer.FULLSCREEN_FLAG_CONTROL_ORIENTATION + or YouTubePlayer.FULLSCREEN_FLAG_CONTROL_SYSTEM_UI + or YouTubePlayer.FULLSCREEN_FLAG_ALWAYS_FULLSCREEN_IN_LANDSCAPE + or YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT) + Orientation.AUTO_START_WITH_LANDSCAPE -> { + player.fullscreenControlFlags = (YouTubePlayer.FULLSCREEN_FLAG_CONTROL_ORIENTATION + or YouTubePlayer.FULLSCREEN_FLAG_CONTROL_SYSTEM_UI + or YouTubePlayer.FULLSCREEN_FLAG_ALWAYS_FULLSCREEN_IN_LANDSCAPE + or YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT) + player.setFullscreen(true) + } + Orientation.ONLY_LANDSCAPE -> { + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + player.fullscreenControlFlags = YouTubePlayer.FULLSCREEN_FLAG_CONTROL_SYSTEM_UI or YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT + player.setFullscreen(true) + } + Orientation.ONLY_PORTRAIT -> { + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + player.fullscreenControlFlags = YouTubePlayer.FULLSCREEN_FLAG_CONTROL_SYSTEM_UI or YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT + player.setFullscreen(true) + } + } + + when (playerStyle) { + YouTubePlayer.PlayerStyle.CHROMELESS -> player.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS) + YouTubePlayer.PlayerStyle.MINIMAL -> player.setPlayerStyle(YouTubePlayer.PlayerStyle.MINIMAL) + YouTubePlayer.PlayerStyle.DEFAULT -> player.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT) + else -> player.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT) + } + + if (!wasRestored) + player.loadVideo(videoId) + } + + override fun onInitializationFailure(provider: YouTubePlayer.Provider, + errorReason: YouTubeInitializationResult) { + if (errorReason.isUserRecoverableError) { + errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST).show() + } else { + val errorMessage = String.format( + "There was an error initializing the YouTubePlayer (%1\$s)", + errorReason.toString()) + Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show() + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { + if (requestCode == RECOVERY_DIALOG_REQUEST) { + // Retry initialization if user performed a recovery action + playerView!!.initialize(googleApiKey, this) + } + } + + // YouTubePlayer.OnFullscreenListener + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + when (orientation) { + Orientation.AUTO, Orientation.AUTO_START_WITH_LANDSCAPE -> if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (player != null) + player!!.setFullscreen(true) + } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT && player != null) { + player!!.setFullscreen(false) + } + Orientation.ONLY_LANDSCAPE, Orientation.ONLY_PORTRAIT -> { + } + } + } + + override fun onFullscreen(fullScreen: Boolean) { + when (orientation) { + Orientation.AUTO, Orientation.AUTO_START_WITH_LANDSCAPE -> if (fullScreen) + requestedOrientation = LANDSCAPE_ORIENTATION + else + requestedOrientation = PORTRAIT_ORIENTATION + Orientation.ONLY_LANDSCAPE, Orientation.ONLY_PORTRAIT -> { + } + } + } + + // YouTubePlayer.PlayerStateChangeListener + override fun onError(reason: ErrorReason) { + Log.e("onError", "onError : " + reason.name) + if (handleError && ErrorReason.NOT_PLAYABLE == reason) { + val video_uri = Uri.parse(YouTubeUrlParser.getVideoUrl(videoId!!)) + var intent = Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:$videoId")) + val list = getPackageManager().queryIntentActivities( + intent, + PackageManager.MATCH_DEFAULT_ONLY) + + if (list.isEmpty()) + intent = Intent(Intent.ACTION_VIEW, video_uri) + + startActivity(intent) + } + } + + override fun onAdStarted() {} + + override fun onLoaded(videoId: String) {} + + override fun onLoading() {} + + override fun onVideoEnded() {} + + override fun onVideoStarted() { + StatusBarUtil.hide(this) + } + + // Audio Managing + override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + AudioUtil.adjustMusicVolume(applicationContext, true, showAudioUi) + StatusBarUtil.hide(this) + return true + } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + AudioUtil.adjustMusicVolume(applicationContext, false, showAudioUi) + StatusBarUtil.hide(this) + return true + } + return super.onKeyDown(keyCode, event) + } + + // Animation + override fun onBackPressed() { + super.onBackPressed() + if (animEnter != 0 && animExit != 0) + overridePendingTransition(animEnter, animExit) + } + + companion object { + + private val RECOVERY_DIALOG_REQUEST = 1 + + + val EXTRA_VIDEO_ID = "video_id" + + val EXTRA_PLAYER_STYLE = "player_style" + + val EXTRA_ORIENTATION = "orientation" + + val EXTRA_SHOW_AUDIO_UI = "show_audio_ui" + + val EXTRA_HANDLE_ERROR = "handle_error" + + val EXTRA_ANIM_ENTER = "anim_enter" + val EXTRA_ANIM_EXIT = "anim_exit" + + @SuppressLint("InlinedApi") + private val PORTRAIT_ORIENTATION = if (Build.VERSION.SDK_INT < 9) + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + else + ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT + + @SuppressLint("InlinedApi") + private val LANDSCAPE_ORIENTATION = if (Build.VERSION.SDK_INT < 9) + ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + else + ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/embedview/YoutubeActivity.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/embedview/YoutubeActivity.kt index dd8646c67..a2fe1aab8 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/embedview/YoutubeActivity.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/embedview/YoutubeActivity.kt @@ -2,42 +2,31 @@ package io.github.feelfreelinux.wykopmobilny.ui.modules.embedview import android.content.Context import android.content.Intent -import android.os.Bundle -import android.provider.Settings -import android.widget.Toast -import com.google.android.youtube.player.YouTubeBaseActivity -import com.google.android.youtube.player.YouTubeInitializationResult -import com.google.android.youtube.player.YouTubePlayer -import io.github.feelfreelinux.wykopmobilny.GOOGLE_KEY -import io.github.feelfreelinux.wykopmobilny.R -import kotlinx.android.synthetic.main.activity_youtubeplayer.* + import java.util.regex.Pattern -import android.content.pm.ActivityInfo -import android.os.Build -import android.annotation.SuppressLint -import android.R.attr.orientation -import android.app.Activity -import android.content.res.Configuration -import com.google.android.youtube.player.YouTubeStandalonePlayer.createVideoIntent + + private val youTubeUrlRegEx = "^(https?)?(://)?(www.)?(m.)?((youtube.com)|(youtu.be))/" private val videoIdRegex = arrayOf("\\?vi?=([^&]*)", "watch\\?.*v=([^&]*)", "(?:embed|vi?)/([^/?]*)", "^([A-Za-z0-9_\\-]*)") -class YoutubeActivity : YouTubeBaseActivity(), YouTubePlayer.OnInitializedListener, YouTubePlayer.OnFullscreenListener { - override fun onFullscreen(fullScreen: Boolean) { +class YoutubeActivity { + /*override fun onFullscreen(fullScreen: Boolean) { if (fullScreen) { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; } else { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; } - } + }*/ companion object { const val REQUEST_CODE_INITIALIZATION_ERROR = 172 const val EXTRA_URL = "URLEXTRA" - fun createIntent(context: Context, url: String) = - (createVideoIntent(context as Activity, GOOGLE_KEY, extractVideoIdFromUrl(url.replace("m.", "")), 0, true, true)) - + fun createIntent(context: Context, url: String): Intent { + val intent = Intent(context, YTPlayer::class.java) + intent.putExtra(YTPlayer.EXTRA_VIDEO_ID, YouTubeUrlParser.getVideoId(url)) + return intent + } private fun extractVideoIdFromUrl(url: String): String? { val youTubeLinkWithoutProtocolAndDomain = youTubeLinkWithoutProtocolAndDomain(url) @@ -65,7 +54,7 @@ class YoutubeActivity : YouTubeBaseActivity(), YouTubePlayer.OnInitializedListen } else url } } - +/* val autoRotation by lazy { Settings.System.getInt(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 1; @@ -133,5 +122,5 @@ class YoutubeActivity : YouTubeBaseActivity(), YouTubePlayer.OnInitializedListen if (requestCode == REQUEST_CODE_INITIALIZATION_ERROR) { youtubePlayer.initialize(GOOGLE_KEY, this) } - } + }*/ } \ No newline at end of file diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedActivity.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedActivity.kt index 281cf2e91..9fe82a084 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedActivity.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedActivity.kt @@ -3,6 +3,7 @@ package io.github.feelfreelinux.wykopmobilny.ui.modules.links.related import android.app.Activity import android.content.Intent import android.os.Bundle +import android.view.Menu import android.view.MenuItem import io.github.feelfreelinux.wykopmobilny.R import io.github.feelfreelinux.wykopmobilny.base.BaseActivity @@ -11,8 +12,10 @@ import io.github.feelfreelinux.wykopmobilny.models.fragments.DataFragment import io.github.feelfreelinux.wykopmobilny.models.fragments.getDataFragmentInstance import io.github.feelfreelinux.wykopmobilny.models.fragments.removeDataFragment import io.github.feelfreelinux.wykopmobilny.ui.adapters.RelatedListAdapter +import io.github.feelfreelinux.wykopmobilny.ui.dialogs.addRelatedDialog import io.github.feelfreelinux.wykopmobilny.utils.isVisible import io.github.feelfreelinux.wykopmobilny.utils.prepare +import io.github.feelfreelinux.wykopmobilny.utils.usermanager.UserManagerApi import kotlinx.android.synthetic.main.activity_conversations_list.* import kotlinx.android.synthetic.main.toolbar.* import javax.inject.Inject @@ -31,6 +34,7 @@ class RelatedActivity : BaseActivity(), androidx.swiperefreshlayout.widget.Swipe @Inject lateinit var presenter: RelatedPresenter @Inject lateinit var relatedAdapter: RelatedListAdapter + @Inject lateinit var userManager: UserManagerApi private lateinit var relatedDataFragment: DataFragment> @@ -78,8 +82,19 @@ class RelatedActivity : BaseActivity(), androidx.swiperefreshlayout.widget.Swipe relatedDataFragment.data = relatedAdapter.items } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.add_related_menu, menu) + menu?.findItem(R.id.add_related)?.isVisible = userManager.isUserAuthorized() + return true + } + override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { + R.id.add_related -> { + addRelatedDialog(this) { url, description -> + presenter.addRelated(description, url) + }.show() + } android.R.id.home -> finish() } return super.onOptionsItemSelected(item) diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedPresenter.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedPresenter.kt index 5dd6807a6..a7276f371 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedPresenter.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedPresenter.kt @@ -19,4 +19,12 @@ class RelatedPresenter( .subscribe({ view?.showRelated(it) }, { view?.showErrorDialog(it) }) .intoComposite(compositeObservable) } + + fun addRelated(title: String, description: String) { + linksApi.relatedAdd(title, description, false, linkId) + .subscribeOn(schedulers.backgroundThread()) + .observeOn(schedulers.mainThread()) + .subscribe({ view?.onRefresh() }, { view?.showErrorDialog(it) }) + .intoComposite(compositeObservable) + } } \ No newline at end of file diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedView.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedView.kt index 263d7de55..593ccebcc 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedView.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/ui/modules/links/related/RelatedView.kt @@ -5,4 +5,5 @@ import io.github.feelfreelinux.wykopmobilny.models.dataclass.Related interface RelatedView : BaseView { fun showRelated(related: List) + fun onRefresh() } \ No newline at end of file diff --git a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/Extensions.kt b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/Extensions.kt index 959a3898a..2cfa546b0 100644 --- a/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/Extensions.kt +++ b/app/src/main/kotlin/io/github/feelfreelinux/wykopmobilny/utils/Extensions.kt @@ -99,9 +99,11 @@ fun String.toDurationPrettyDate(): String { return "${period.years} lata" } else if (period.years == 1 && period.months > 0) { return "${period.years} rok ${period.months} mies." + } else if (period.years == 1 && period.months == 0) { + return "${period.years} rok" } else if (period.years == 0 && period.months > 0) { return "${period.months} mies." - } else if (period.months == 0 && period.days > 0) { + } else if (period.months == 0 && period.days > 0) { return "${period.days} dni" } else { val durationTime = LocalTime.parse(this, DateTimeFormatter.ofPattern("yyyy-MM-dd kk:mm:ss", Locale.GERMAN)) diff --git a/app/src/main/res/layout/activity_youtubeplayer.xml b/app/src/main/res/layout/activity_youtubeplayer.xml index f60e54e49..e43cc2009 100644 --- a/app/src/main/res/layout/activity_youtubeplayer.xml +++ b/app/src/main/res/layout/activity_youtubeplayer.xml @@ -8,13 +8,5 @@ android:focusableInTouchMode="true" android:focusable="true"> - \ No newline at end of file diff --git a/app/src/main/res/layout/comment_list_item.xml b/app/src/main/res/layout/comment_list_item.xml index cc7bd0529..030140ad1 100644 --- a/app/src/main/res/layout/comment_list_item.xml +++ b/app/src/main/res/layout/comment_list_item.xml @@ -43,7 +43,8 @@ diff --git a/app/src/main/res/layout/dialog_insert_link.xml b/app/src/main/res/layout/dialog_insert_link.xml index 99a847920..1a2724051 100644 --- a/app/src/main/res/layout/dialog_insert_link.xml +++ b/app/src/main/res/layout/dialog_insert_link.xml @@ -1,5 +1,6 @@ diff --git a/app/src/main/res/layout/link_comment_layout.xml b/app/src/main/res/layout/link_comment_layout.xml index c62a02ed2..0e2d19fa8 100644 --- a/app/src/main/res/layout/link_comment_layout.xml +++ b/app/src/main/res/layout/link_comment_layout.xml @@ -39,12 +39,14 @@ app:layout_constraintBottom_toBottomOf="@+id/authorTextView" tools:background="@drawable/patron_badge" tools:text="PATRON" /> + + app:layout_constraintRight_toLeftOf="@id/dateTextView" + app:layout_constraintTop_toTopOf="@id/dateTextView" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 543cfafcf..64d274857 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -322,7 +322,6 @@