diff --git a/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactoryTest.kt b/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactoryTest.kt deleted file mode 100644 index 3103e97df..000000000 --- a/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactoryTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.mariotaku.twidere.util - -import android.support.test.runner.AndroidJUnit4 -import org.junit.Test -import org.junit.runner.RunWith - -/** - * Created by mariotaku on 2016/12/15. - */ -@RunWith(AndroidJUnit4::class) -class TwitterCardFragmentFactoryTest { - @Test - fun testGetInstance() { - TwitterCardFragmentFactory.instance - } -} \ No newline at end of file diff --git a/twidere/src/fdroid/resources/META-INF/services/org.mariotaku.twidere.util.TwitterCardFragmentFactory b/twidere/src/fdroid/resources/META-INF/services/org.mariotaku.twidere.util.TwitterCardFragmentFactory deleted file mode 100644 index af201596b..000000000 --- a/twidere/src/fdroid/resources/META-INF/services/org.mariotaku.twidere.util.TwitterCardFragmentFactory +++ /dev/null @@ -1 +0,0 @@ -org.mariotaku.twidere.util.TwitterCardFragmentFactoryImpl \ No newline at end of file diff --git a/twidere/src/google/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactoryImpl.kt b/twidere/src/google/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactoryImpl.kt deleted file mode 100644 index c471a4b51..000000000 --- a/twidere/src/google/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactoryImpl.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.util - -import android.net.Uri -import android.support.v4.app.Fragment -import com.google.android.youtube.player.YouTubeInitializationResult -import com.google.android.youtube.player.YouTubePlayer -import com.google.android.youtube.player.YouTubePlayerSupportFragment -import org.mariotaku.twidere.model.ParcelableCardEntity -import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils - -/** - * Created by mariotaku on 15/1/1. - */ -class TwitterCardFragmentFactoryImpl : TwitterCardFragmentFactory() { - - override fun createAnimatedGifFragment(card: ParcelableCardEntity): Fragment? { - return null - } - - override fun createAudioFragment(card: ParcelableCardEntity): Fragment? { - return null - } - - override fun createPlayerFragment(card: ParcelableCardEntity): Fragment? { - if (java.lang.Boolean.parseBoolean("true")) return null - val appUrlResolved = ParcelableCardEntityUtils.getString(card, "app_url_resolved") - val domain = ParcelableCardEntityUtils.getString(card, "domain") - if (domain != null && appUrlResolved != null) { - val uri = Uri.parse(appUrlResolved) - val paramV = uri.getQueryParameter("v") - if ("www.youtube.com" == domain && paramV != null) { - val fragment = YouTubePlayerSupportFragment.newInstance() - fragment.initialize(YOUTUBE_DATA_API_KEY, object : YouTubePlayer.OnInitializedListener { - override fun onInitializationSuccess(provider: YouTubePlayer.Provider, player: YouTubePlayer, wasRestored: Boolean) { - if (!wasRestored) { - player.cueVideo(paramV) - } - } - - override fun onInitializationFailure(provider: YouTubePlayer.Provider, errorReason: YouTubeInitializationResult) { - val activity = fragment.activity ?: return -// if (errorReason.isUserRecoverableError()) { - // errorReason.getErrorDialog(activity, RECOVERY_DIALOG_REQUEST).show(); - // } else { - // Toast.makeText(activity, errorReason.toString(), Toast.LENGTH_LONG).show(); - // } - } - }) - return fragment - } - } - return null - } - - companion object { - - private val YOUTUBE_DATA_API_KEY = "AIzaSyCVdCIMFFxdNqHnCPrJ9yKUzoTfs8jhYGc" - } - -} diff --git a/twidere/src/google/resources/META-INF/services/org.mariotaku.twidere.util.TwitterCardFragmentFactory b/twidere/src/google/resources/META-INF/services/org.mariotaku.twidere.util.TwitterCardFragmentFactory index af201596b..c040ad2cc 100644 --- a/twidere/src/google/resources/META-INF/services/org.mariotaku.twidere.util.TwitterCardFragmentFactory +++ b/twidere/src/google/resources/META-INF/services/org.mariotaku.twidere.util.TwitterCardFragmentFactory @@ -1 +1 @@ -org.mariotaku.twidere.util.TwitterCardFragmentFactoryImpl \ No newline at end of file +TwitterCardViewFactoryImpl \ No newline at end of file diff --git a/twidere/src/main/java/org/mariotaku/twidere/view/TwitterCardContainer.java b/twidere/src/main/java/org/mariotaku/twidere/view/TwitterCardContainer.java deleted file mode 100644 index 013c0f794..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/view/TwitterCardContainer.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.view; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.FrameLayout; - -import org.mariotaku.twidere.util.support.ViewSupport; - -/** - * Created by mariotaku on 15/1/1. - */ -public class TwitterCardContainer extends FrameLayout { - - private int mCardWidth, mCardHeight; - - public TwitterCardContainer(Context context) { - super(context); - } - - public TwitterCardContainer(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public TwitterCardContainer(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public void setCardSize(int width, int height) { - mCardWidth = width; - mCardHeight = height; - if (!ViewSupport.isInLayout(this)) { - requestLayout(); - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - if (mCardWidth <= 0 || mCardHeight <= 0) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - return; - } - final int measuredWidth = MeasureSpec.getSize(widthMeasureSpec); - final int measuredHeight = Math.round(measuredWidth * (mCardHeight / (float) mCardWidth)); - final int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY); - final int newHeightMeasureSpec; - if (measuredHeight != 0) { - newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY); - } else { - newHeightMeasureSpec = heightMeasureSpec; - } - super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec); - } -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt index bda95ec7a..8a9978c32 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt @@ -31,7 +31,6 @@ import android.nfc.NfcAdapter.CreateNdefMessageCallback import android.os.AsyncTask import android.os.Bundle import android.support.annotation.UiThread -import android.support.v4.app.FragmentManagerAccessor import android.support.v4.app.LoaderManager.LoaderCallbacks import android.support.v4.app.hasRunningLoadersSafe import android.support.v4.content.AsyncTaskLoader @@ -106,6 +105,7 @@ import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.ContentScrollHandler.ContentListSupport import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback import org.mariotaku.twidere.util.RecyclerViewScrollHandler.RecyclerViewCallback +import org.mariotaku.twidere.util.twitter.card.TwitterCardViewFactory import org.mariotaku.twidere.view.CardMediaContainer.OnMediaClickListener import org.mariotaku.twidere.view.ExtendedRecyclerView import org.mariotaku.twidere.view.holder.GapViewHolder @@ -996,24 +996,25 @@ class StatusFragment : BaseFragment(), LoaderCallbacks - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.fragment.card - -import android.os.Bundle -import org.mariotaku.twidere.Constants.EXTRA_URI -import org.mariotaku.twidere.fragment.BrowserFragment - -/** - * Created by mariotaku on 15/1/6. - */ -class CardBrowserFragment : BrowserFragment() { - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - val settings = webView!!.settings - settings.builtInZoomControls = false - } - - companion object { - - fun show(uri: String, extraArgs: Bundle?): CardBrowserFragment { - val args = Bundle() - args.putString(EXTRA_URI, uri) - if (extraArgs != null) { - args.putAll(extraArgs) - } - val fragment = CardBrowserFragment() - fragment.arguments = args - return fragment - } - } -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactory.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactory.kt deleted file mode 100644 index f5750533d..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/TwitterCardFragmentFactory.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.mariotaku.twidere.util - -import android.os.Bundle -import android.support.v4.app.Fragment - -import org.mariotaku.twidere.fragment.card.CardBrowserFragment -import org.mariotaku.twidere.fragment.card.CardPollFragment -import org.mariotaku.twidere.model.ParcelableCardEntity -import org.mariotaku.twidere.model.ParcelableStatus -import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils -import java.util.* - -/** - * Created by mariotaku on 15/1/1. - */ -abstract class TwitterCardFragmentFactory { - - abstract fun createAnimatedGifFragment(card: ParcelableCardEntity): Fragment? - - abstract fun createAudioFragment(card: ParcelableCardEntity): Fragment? - - abstract fun createPlayerFragment(card: ParcelableCardEntity): Fragment? - - companion object { - - val instance: TwitterCardFragmentFactory by lazy { - ServiceLoader.load(TwitterCardFragmentFactory::class.java).first() - } - - fun createGenericPlayerFragment(card: ParcelableCardEntity?, args: Bundle?): Fragment? { - if (card == null) return null - val playerUrl = ParcelableCardEntityUtils.getString(card, "player_url") ?: return null - return CardBrowserFragment.show(playerUrl, args) - } - - fun createCardPollFragment(status: ParcelableStatus): Fragment { - return CardPollFragment.show(status) - } - - fun createCardFragment(status: ParcelableStatus): Fragment? { - val card = status.card - if (card == null || card.name == null) return null - if (TwitterCardUtils.CARD_NAME_PLAYER == card.name) { - val playerFragment = instance.createPlayerFragment(card) - if (playerFragment != null) return playerFragment - return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null) - } else if (TwitterCardUtils.CARD_NAME_AUDIO == card.name) { - val playerFragment = instance.createAudioFragment(card) - if (playerFragment != null) return playerFragment - return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null) - } else if (TwitterCardUtils.CARD_NAME_ANIMATED_GIF == card.name) { - val playerFragment = instance.createAnimatedGifFragment(card) - if (playerFragment != null) return playerFragment - return TwitterCardFragmentFactory.createGenericPlayerFragment(card, null) - } else if (TwitterCardUtils.isPoll(card)) { - return TwitterCardFragmentFactory.createCardPollFragment(status) - } - return null - } - - } -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/twitter/card/TwitterCardViewFactory.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/twitter/card/TwitterCardViewFactory.kt new file mode 100644 index 000000000..94fe33e08 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/twitter/card/TwitterCardViewFactory.kt @@ -0,0 +1,76 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.util.twitter.card + +import org.mariotaku.twidere.model.ParcelableCardEntity +import org.mariotaku.twidere.model.ParcelableStatus +import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils +import org.mariotaku.twidere.util.TwitterCardUtils +import org.mariotaku.twidere.view.ContainerView +import org.mariotaku.twidere.view.controller.twitter.card.CardBrowserViewController +import org.mariotaku.twidere.view.controller.twitter.card.CardPollViewController +import java.util.* + +/** + * Created by mariotaku on 15/1/1. + */ +abstract class TwitterCardViewFactory { + + abstract fun from(status: ParcelableStatus): ContainerView.ViewController? + + companion object { + fun from(status: ParcelableStatus): ContainerView.ViewController? { + val vc = fromImplementations(status) + if (vc != null) return vc + return createCardFragment(status) + } + + private fun fromImplementations(status: ParcelableStatus): ContainerView.ViewController? { + ServiceLoader.load(TwitterCardViewFactory::class.java).forEach { factory -> + val vc = factory.from(status) + if (vc != null) return vc + } + return null + } + + private fun createCardFragment(status: ParcelableStatus): ContainerView.ViewController? { + val card = status.card + if (card == null || card.name == null) return null + if (TwitterCardUtils.CARD_NAME_PLAYER == card.name) { + return createGenericPlayerFragment(card) + } else if (TwitterCardUtils.CARD_NAME_AUDIO == card.name) { + return createGenericPlayerFragment(card) + } else if (TwitterCardUtils.isPoll(card)) { + return createCardPollFragment(status) + } + return null + } + + + private fun createCardPollFragment(status: ParcelableStatus): ContainerView.ViewController { + return CardPollViewController.show(status) + } + + private fun createGenericPlayerFragment(card: ParcelableCardEntity): ContainerView.ViewController? { + val playerUrl = ParcelableCardEntityUtils.getString(card, "player_url") ?: return null + return CardBrowserViewController.show(playerUrl) + } + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/twitter/card/impl/DefaultTwitterCardViewFactory.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/twitter/card/impl/DefaultTwitterCardViewFactory.kt new file mode 100644 index 000000000..820f4a2c6 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/twitter/card/impl/DefaultTwitterCardViewFactory.kt @@ -0,0 +1,16 @@ +package org.mariotaku.twidere.util.twitter.card.impl + +import org.mariotaku.twidere.model.ParcelableStatus +import org.mariotaku.twidere.util.twitter.card.TwitterCardViewFactory +import org.mariotaku.twidere.view.ContainerView + +/** + * Created by mariotaku on 2017/1/25. + */ + +class DefaultTwitterCardViewFactory : TwitterCardViewFactory() { + override fun from(status: ParcelableStatus): ContainerView.ViewController? { + return null + } + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/ContainerView.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/ContainerView.kt new file mode 100644 index 000000000..48893afba --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/ContainerView.kt @@ -0,0 +1,96 @@ +package org.mariotaku.twidere.view + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.widget.FrameLayout + +/** + * Created by mariotaku on 2017/1/25. + */ + +open class ContainerView(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) { + + private var attachedToWindow: Boolean = false + + var viewController: ViewController? = null + set(vc) { + field?.let { vc -> + if (vc.attached) { + vc.attached = false + vc.onDetached() + } + val view = vc.view + vc.onDestroyView(view) + this.removeView(view) + vc.onDestroy() + } + field = vc + if (vc != null) { + if (vc.attached) { + throw IllegalStateException("ViewController has already attached") + } + vc.context = context + val view = vc.onCreateView(this) + this.addView(view) + vc.view = view + vc.onCreate() + vc.onViewCreated(view) + if (attachedToWindow) { + vc.attached = true + vc.onAttached() + } + } + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + attachedToWindow = true + viewController?.let { vc -> + if (!vc.windowAttached) { + vc.windowAttached = true + vc.onWindowAttached() + } + } + } + + override fun onDetachedFromWindow() { + attachedToWindow = false + viewController?.let { vc -> + if (vc.attached) { + vc.windowAttached = false + vc.onWindowDetached() + } + } + super.onDetachedFromWindow() + } + + + abstract class ViewController { + + lateinit var context: Context + internal set + lateinit var view: View + internal set + var attached: Boolean = false + internal set + var windowAttached: Boolean = false + internal set + + open fun onCreate() {} + open fun onDestroy() {} + + open fun onAttached() {} + open fun onDetached() {} + + open fun onWindowAttached() {} + open fun onWindowDetached() {} + + abstract fun onCreateView(parent: ContainerView): View + + open fun onDestroyView(view: View) {} + + open fun onViewCreated(view: View) {} + } + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/TwitterCardContainer.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/TwitterCardContainer.kt new file mode 100644 index 000000000..e16786e0f --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/TwitterCardContainer.kt @@ -0,0 +1,59 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.view + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import org.mariotaku.twidere.util.support.ViewSupport + +/** + * Created by mariotaku on 15/1/1. + */ +class TwitterCardContainer(context: Context, attrs: AttributeSet? = null) : ContainerView(context, attrs) { + + private var cardWidth: Int = 0 + private var cardHeight: Int = 0 + + fun setCardSize(width: Int, height: Int) { + cardWidth = width + cardHeight = height + if (!ViewSupport.isInLayout(this)) { + requestLayout() + } + } + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + if (cardWidth <= 0 || cardHeight <= 0) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + return + } + val measuredWidth = View.MeasureSpec.getSize(widthMeasureSpec) + val measuredHeight = Math.round(measuredWidth * (cardHeight / cardWidth.toFloat())) + val newWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.EXACTLY) + val newHeightMeasureSpec: Int + if (measuredHeight != 0) { + newHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.EXACTLY) + } else { + newHeightMeasureSpec = heightMeasureSpec + } + super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec) + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardBrowserViewController.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardBrowserViewController.kt new file mode 100644 index 000000000..b611b9fa7 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardBrowserViewController.kt @@ -0,0 +1,68 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2015 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.view.controller.twitter.card + +import android.annotation.SuppressLint +import android.view.View +import android.view.ViewGroup +import android.webkit.WebView +import android.widget.FrameLayout +import org.mariotaku.twidere.view.ContainerView + +/** + * Created by mariotaku on 15/1/6. + */ +class CardBrowserViewController : ContainerView.ViewController() { + + lateinit var url: String + + override fun onCreateView(parent: ContainerView): View { + val webView = WebView(context) + webView.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT) + return webView + } + + override fun onDestroyView(view: View) { + (view as WebView).destroy() + super.onDestroyView(view) + } + + @SuppressLint("SetJavaScriptEnabled") + override fun onCreate() { + super.onCreate() + val webView = view as WebView + webView.settings.apply { + javaScriptEnabled = true + builtInZoomControls = false + } + webView.loadUrl(url) + } + + + companion object { + + fun show(url: String): CardBrowserViewController { + val vc = CardBrowserViewController() + vc.url = url + return vc + } + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/card/CardPollFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardPollViewController.kt similarity index 62% rename from twidere/src/main/kotlin/org/mariotaku/twidere/fragment/card/CardPollFragment.kt rename to twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardPollViewController.kt index 8acec1c71..654e9e67a 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/card/CardPollFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardPollViewController.kt @@ -17,39 +17,30 @@ * along with this program. If not, see . */ -package org.mariotaku.twidere.fragment.card +package org.mariotaku.twidere.view.controller.twitter.card import android.accounts.AccountManager -import android.content.Context import android.graphics.* import android.graphics.drawable.Drawable -import android.os.Bundle -import android.support.v4.app.LoaderManager -import android.support.v4.content.AsyncTaskLoader import android.support.v4.content.ContextCompat -import android.support.v4.content.Loader import android.text.format.DateUtils import android.util.Log import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.widget.RadioButton import android.widget.TextView -import kotlinx.android.synthetic.main.fragment_card_poll.* +import kotlinx.android.synthetic.main.layout_twitter_card_poll.view.* +import nl.komponents.kovenant.task +import nl.komponents.kovenant.ui.successUi import org.apache.commons.lang3.math.NumberUtils import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.TwitterCaps import org.mariotaku.microblog.library.twitter.model.CardDataMap -import org.mariotaku.twidere.Constants.EXTRA_CARD import org.mariotaku.twidere.Constants.LOGTAG import org.mariotaku.twidere.R -import org.mariotaku.twidere.constant.IntentConstants -import org.mariotaku.twidere.constant.IntentConstants.EXTRA_STATUS import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.fragment.BaseFragment -import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.ParcelableCardEntity import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.util.AccountUtils @@ -57,46 +48,70 @@ import org.mariotaku.twidere.model.util.ParcelableCardEntityUtils import org.mariotaku.twidere.util.MicroBlogAPIFactory import org.mariotaku.twidere.util.TwitterCardUtils import org.mariotaku.twidere.util.support.ViewSupport +import org.mariotaku.twidere.view.ContainerView +import java.lang.ref.WeakReference import java.util.* /** * Created by mariotaku on 15/12/20. */ -class CardPollFragment : BaseFragment(), LoaderManager.LoaderCallbacks, View.OnClickListener { +class CardPollViewController : ContainerView.ViewController() { + + private lateinit var status: ParcelableStatus private var fetchedCard: ParcelableCardEntity? = null + private val card: ParcelableCardEntity + get() = fetchedCard ?: status.card!! - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - initChoiceView(savedInstanceState) - - loaderManager.initLoader(0, null, this) + override fun onCreate() { + super.onCreate() + initChoiceView() + loadCardPoll() } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - return inflater.inflate(R.layout.fragment_card_poll, container, false) + override fun onCreateView(parent: ContainerView): View { + return LayoutInflater.from(context).inflate(R.layout.layout_twitter_card_poll, parent, false) } - override fun fitSystemWindows(insets: Rect) { - // No-op - } - - - private fun initChoiceView(savedInstanceState: Bundle?) { - val card = card - val status = status + private fun initChoiceView() { val choicesCount = TwitterCardUtils.getChoicesCount(card) - val inflater = getLayoutInflater(savedInstanceState) + val inflater = LayoutInflater.from(context) for (i in 0 until choicesCount) { - inflater.inflate(R.layout.layout_poll_item, pollContainer, true) + inflater.inflate(R.layout.layout_poll_item, view.pollContainer, true) } displayPoll(card, status) } + private fun displayAndReloadPoll(result: ParcelableCardEntity, status: ParcelableStatus) { + if (!attached) return + displayPoll(result, status) + loadCardPoll() + } + + private fun loadCardPoll() { + val weakThis = WeakReference(this) + task { + val vc = weakThis.get() ?: throw IllegalStateException() + val card = vc.card + val details = AccountUtils.getAccountDetails(AccountManager.get(vc.context), card.account_key, true)!! + val caps = details.newMicroBlogInstance(vc.context, cls = TwitterCaps::class.java) + val params = CardDataMap() + params.putString("card_uri", card.url) + params.putString("cards_platform", MicroBlogAPIFactory.CARDS_PLATFORM_ANDROID_12) + params.putString("response_card_name", card.name) + val cardResponse = caps.getPassThrough(params).card + if (cardResponse == null || cardResponse.name == null) { + throw IllegalStateException() + } + return@task ParcelableCardEntityUtils.fromCardEntity(cardResponse, details.key) + }.successUi { data -> + weakThis.get()?.displayPoll(data, status) + } + } + private fun displayPoll(card: ParcelableCardEntity?, status: ParcelableStatus?) { - val context = context - if (card == null || status == null || context == null) return + if (card == null || status == null) return fetchedCard = card val choicesCount = TwitterCardUtils.getChoicesCount(card) var votesSum = 0 @@ -116,8 +131,8 @@ class CardPollFragment : BaseFragment(), LoaderManager.LoaderCallbacks() { + val task = object : AbstractTask() { - public override fun afterExecute(handler: CardPollFragment?, result: ParcelableCardEntity?) { + public override fun afterExecute(handler: CardPollViewController?, result: ParcelableCardEntity?) { result ?: return handler?.displayAndReloadPoll(result, status) } @@ -152,7 +167,7 @@ class CardPollFragment : BaseFragment(), LoaderManager.LoaderCallbacks(EXTRA_CARD)!! - assert(card.name != null) - return card - } - - private val status: ParcelableStatus - get() = arguments.getParcelable(EXTRA_STATUS) - - override fun onClick(v: View) { - - } - - override fun onCreateLoader(id: Int, args: Bundle?): Loader { - val card = card - val details = AccountUtils.getAccountDetails(AccountManager.get(context), card.account_key, true)!! - return ParcelableCardEntityLoader(context, details, card.url, card.name) - } - - override fun onLoadFinished(loader: Loader, data: ParcelableCardEntity?) { - if (data == null) return - displayPoll(data, status) - } - - override fun onLoaderReset(loader: Loader) { - + view.pollSummary.text = context.getString(R.string.poll_summary_format, nVotes, timeLeft) } private class PercentDrawable internal constructor( @@ -246,22 +223,18 @@ class CardPollFragment : BaseFragment(), LoaderManager.LoaderCallbacks(context) { - - override fun loadInBackground(): ParcelableCardEntity? { - val caps = details.newMicroBlogInstance(context, cls = TwitterCaps::class.java) - try { - val params = CardDataMap() - params.putString("card_uri", cardUri) - params.putString("cards_platform", MicroBlogAPIFactory.CARDS_PLATFORM_ANDROID_12) - params.putString("response_card_name", cardName) - val card = caps.getPassThrough(params).card - if (card == null || card.name == null) { - return null - } - return ParcelableCardEntityUtils.fromCardEntity(card, details.key) - } catch (e: MicroBlogException) { - return null - } - - } - - override fun onStartLoading() { - forceLoad() - } - } - companion object { - fun show(status: ParcelableStatus): CardPollFragment { - val fragment = CardPollFragment() - val args = Bundle() - args.putParcelable(EXTRA_STATUS, status) - args.putParcelable(IntentConstants.EXTRA_CARD, status.card) - fragment.arguments = args - return fragment + fun show(status: ParcelableStatus): CardPollViewController { + val vc = CardPollViewController() + vc.status = status + return vc } } diff --git a/twidere/src/main/res/layout/fragment_card_poll.xml b/twidere/src/main/res/layout/layout_twitter_card_poll.xml similarity index 100% rename from twidere/src/main/res/layout/fragment_card_poll.xml rename to twidere/src/main/res/layout/layout_twitter_card_poll.xml diff --git a/twidere/src/main/resources/META-INF/services/org.mariotaku.twidere.util.twitter.card.TwitterCardViewFactory b/twidere/src/main/resources/META-INF/services/org.mariotaku.twidere.util.twitter.card.TwitterCardViewFactory new file mode 100644 index 000000000..76660fca4 --- /dev/null +++ b/twidere/src/main/resources/META-INF/services/org.mariotaku.twidere.util.twitter.card.TwitterCardViewFactory @@ -0,0 +1 @@ +org.mariotaku.twidere.util.twitter.card.impl.DefaultTwitterCardViewFactory \ No newline at end of file