Commit 4d9a5ca9 authored by sheteng's avatar sheteng

资讯3

parent b161ab81
...@@ -25,7 +25,11 @@ ...@@ -25,7 +25,11 @@
<package android:name="com.tencent.mobileqq" /> <package android:name="com.tencent.mobileqq" />
<package android:name="com.baidu.browser.apps" /> <package android:name="com.baidu.browser.apps" />
<package android:name="com.ldsanguo.shark" /> <package android:name="com.ldsanguo.shark" />
<package android:name="com.ldsanguomj.shark" />
<package android:name="com.nexon.mdnf.cbt" /> <package android:name="com.nexon.mdnf.cbt" />
<package android:name="com.google.android.gsf" />
<package android:name="com.google.android.gms" />
<package android:name="com.android.vending" />
</queries> </queries>
<application <application
......
...@@ -12,7 +12,7 @@ data class GameInfo( ...@@ -12,7 +12,7 @@ data class GameInfo(
val greatNum: Int, val greatNum: Int,
val icon: String, val icon: String,
val id: Int, val id: Int,
val boosterServerIp:String, val boosterServer:String,
val imgs: String, val imgs: String,
val introduction: String, val introduction: String,
val packageName: String, val packageName: String,
......
...@@ -21,5 +21,6 @@ data class News( ...@@ -21,5 +21,6 @@ data class News(
val star: String?, val star: String?,
val title: String?, val title: String?,
val type: Int?, val type: Int?,
val videoUrl: String? val videoUrl: String?,
val videoImg : String?
) )
\ No newline at end of file
package com.ccwangluo.accelerator.model
data class Plugin(
val createdDate: String?,
val gameId: Int,
val icon: String?,
val id: Int,
val isOpen: Boolean,
val name: String?,
val type: Int,
val url: String?
)
\ No newline at end of file
package com.ccwangluo.accelerator.model
data class PluginModel(
val list: List<Plugin>,
val total: Int
)
\ No newline at end of file
...@@ -55,7 +55,6 @@ class BottomNavigationFragment : XPageFragment(), ViewPager.OnPageChangeListener ...@@ -55,7 +55,6 @@ class BottomNavigationFragment : XPageFragment(), ViewPager.OnPageChangeListener
binding.viewPager.setOffscreenPageLimit(titles.size - 1); binding.viewPager.setOffscreenPageLimit(titles.size - 1);
binding.viewPager.adapter = adapter binding.viewPager.adapter = adapter
binding.viewPager.setNoScroll(true) binding.viewPager.setNoScroll(true)
AcceleratorUtils.getGameList(this,{})
} }
override fun initListeners() { override fun initListeners() {
......
...@@ -83,7 +83,7 @@ class MainActivity() : XPageActivity(), TencentLocationListener { ...@@ -83,7 +83,7 @@ class MainActivity() : XPageActivity(), TencentLocationListener {
p0: MutableList<PermissionRequest>?, p0: MutableList<PermissionRequest>?,
p1: PermissionToken? p1: PermissionToken?
) { ) {
PermissionUtils.openAppSettings() // PermissionUtils.openAppSettings()
} }
}).check() }).check()
...@@ -105,8 +105,6 @@ class MainActivity() : XPageActivity(), TencentLocationListener { ...@@ -105,8 +105,6 @@ class MainActivity() : XPageActivity(), TencentLocationListener {
AcceleratorUtils.initConnect(this, connect) AcceleratorUtils.initConnect(this, connect)
mSensorManager = getSystemService(SENSOR_SERVICE) as SensorManager mSensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
mSensorEventListener = JCVideoPlayer.JCAutoFullscreenListener() mSensorEventListener = JCVideoPlayer.JCAutoFullscreenListener()
} }
private fun initPhoneUtils() { private fun initPhoneUtils() {
...@@ -127,13 +125,14 @@ class MainActivity() : XPageActivity(), TencentLocationListener { ...@@ -127,13 +125,14 @@ class MainActivity() : XPageActivity(), TencentLocationListener {
mSensorEventListener, mSensorEventListener,
mSensor, mSensor,
SensorManager.SENSOR_DELAY_NORMAL SensorManager.SENSOR_DELAY_NORMAL
); )
AcceleratorUtils.checkVpn()
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
mSensorManager?.unregisterListener(mSensorEventListener); mSensorManager?.unregisterListener(mSensorEventListener);
JCVideoPlayer.releaseAllVideos(); JCVideoPlayer.releaseAllVideos()
} }
override fun onStart() { override fun onStart() {
......
...@@ -33,7 +33,6 @@ class MemberDialog( ...@@ -33,7 +33,6 @@ class MemberDialog(
} }
} }
init { init {
mDialog.setCancelable(false)
} }
......
...@@ -156,7 +156,7 @@ class AccelertorFragment : XPageFragment() { ...@@ -156,7 +156,7 @@ class AccelertorFragment : XPageFragment() {
} }
binding.gamePage.setOnClickListener { binding.gamePage.setOnClickListener {
openToWebview(HttpConfig.UI_GAME_URL) openToWebview(HttpConfig.UI_GAME_URL + "?gameId=${AcceleratorUtils.game?.id}")
} }
binding.smartAccOpen.setOnClickListener { binding.smartAccOpen.setOnClickListener {
......
package com.ccwangluo.accelerator.ui.home package com.ccwangluo.accelerator.ui.home
import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.ccwangluo.accelerator.R import com.ccwangluo.accelerator.R
import com.ccwangluo.accelerator.adapter.KotlinDataAdapter import com.ccwangluo.accelerator.adapter.KotlinDataAdapter
import com.ccwangluo.accelerator.databinding.FragmentNewsBinding import com.ccwangluo.accelerator.databinding.FragmentNewsBinding
import com.ccwangluo.accelerator.model.News import com.ccwangluo.accelerator.model.News
import com.ccwangluo.accelerator.model.Plugin
import com.ccwangluo.accelerator.ui.MainActivity
import com.ccwangluo.accelerator.ui.news.NewsCollectionAdapter import com.ccwangluo.accelerator.ui.news.NewsCollectionAdapter
import com.ccwangluo.accelerator.ui.web.CommonWebViewFragment
import com.ccwangluo.accelerator.utils.AcceleratorUtils import com.ccwangluo.accelerator.utils.AcceleratorUtils
import com.ccwangluo.accelerator.utils.LoginUtils
import com.ccwangluo.cc_quickly.utils.XToastUtils
import com.github.shadowsocks.http.HttpConfig
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
import com.hjq.toast.ToastUtils
import com.xuexiang.xpage.base.XPageFragment import com.xuexiang.xpage.base.XPageFragment
import com.xuexiang.xpage.utils.TitleBar import com.xuexiang.xpage.utils.TitleBar
import com.xuexiang.xui.widget.toast.XToast
class NewsFragment : XPageFragment() { class NewsFragment : XPageFragment() {
private var _binding: FragmentNewsBinding? = null private var _binding: FragmentNewsBinding? = null
...@@ -24,48 +41,102 @@ class NewsFragment : XPageFragment() { ...@@ -24,48 +41,102 @@ class NewsFragment : XPageFragment() {
return null return null
} }
var dataList = arrayListOf<String>() var dataList = arrayListOf<Plugin>()
override fun inflateView(inflater: LayoutInflater?, container: ViewGroup?): View { override fun inflateView(inflater: LayoutInflater?, container: ViewGroup?): View {
_binding = FragmentNewsBinding.inflate(inflater!!, container, false) _binding = FragmentNewsBinding.inflate(inflater!!, container, false)
newsViewModel = ViewModelProvider(this).get(NewsViewModel::class.java) newsViewModel = ViewModelProvider(requireActivity()).get(NewsViewModel::class.java)
return binding.root return binding.root
} }
val titles = arrayOf("全部", "攻略", "视频", "评价", "问答") val titles = arrayOf("全部", "攻略", "视频", "评价", "问答")
var adapter: NewsCollectionAdapter? = null var adapter: NewsCollectionAdapter? = null
override fun initViews() { override fun initViews() {
newsViewModel.notice.observe(this,{ newsViewModel.notice.observe(this, {
binding.tvMarquee.addDisplayString(it.title) it.forEach {
binding.tvMarquee.addDisplayString(it.title)
}
binding.tvMarquee.startRoll() binding.tvMarquee.startRoll()
}) })
binding.refreshNews.setOnClickListener { newsViewModel.isRefresh.observe(this, Observer {
binding.refreshNews.isRefreshing = false
})
binding.appbar.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
if (verticalOffset >= 0) {
binding.refreshNews.isEnabled = true
} else {
binding.refreshNews.isEnabled = false
}
}
})
binding.refreshNews.setOnRefreshListener {
adapter?.refresh(binding.viewPager.currentItem) adapter?.refresh(binding.viewPager.currentItem)
binding.refreshNews.postDelayed({ binding.refreshNews.postDelayed({
binding.refreshNews.isRefreshing = false binding.refreshNews.isRefreshing = false
},1000) }, 2000)
} }
binding.gameNewsList.adapter = KotlinDataAdapter.Builder<String>() val layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
binding.gameNewsList?.setLayoutManager(layoutManager)
binding.gameNewsList.adapter = KotlinDataAdapter.Builder<Plugin>()
.setData(dataList) .setData(dataList)
.setLayoutId(R.layout.item_news_game) .setLayoutId(R.layout.item_news_game)
.addBindView{itemView, itemData -> .addBindView { itemView, itemData ->
context?.let {
Glide.with(it).load(itemData.icon)
.into(itemView.findViewById<ImageView>(R.id.plugin_img))
}
itemView.findViewById<TextView>(R.id.plugin_name).setText(itemData.name)
itemView.setOnClickListener {
if (!itemData.isOpen) {
ToastUtils.show("暂不支持${itemData.name}")
return@setOnClickListener
}
}.create() if (itemData.type == 1) {
itemData.url?.let {
openToWebview(it)
}
}
if (itemData.type == 2) {
itemData.url?.let {
openToWebview(it)
}
}
}
}.create()
newsViewModel.pluginList.observe(this, {
dataList.clear()
dataList.addAll(it)
binding.gameNewsList.adapter?.notifyDataSetChanged()
})
adapter = NewsCollectionAdapter(this, titles) adapter = NewsCollectionAdapter(this, titles)
binding.viewPager.adapter = adapter binding.viewPager.adapter = adapter
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position -> TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
tab.setCustomView(R.layout.item_tab) tab.setCustomView(R.layout.item_tab)
tab.text = titles[position] tab.text = titles[position]
}.attach() }.attach()
AcceleratorUtils.game?.let { AcceleratorUtils.getGameList(this) {
newsViewModel.getNotice(it.id) if (it) {
AcceleratorUtils.game?.let {
newsViewModel.getNotice(it.id)
newsViewModel.getPlugin(it.id)
}
}
} }
} }
fun openToWebview(url: String) {
val params = Bundle()
params.putString(CommonWebViewFragment.WEBVIEW_URL_KEY, url)
openPage(CommonWebViewFragment::class.java, params)
}
override fun initListeners() { override fun initListeners() {
// binding.refreshLayout.setOnRefreshListener { // binding.refreshLayout.setOnRefreshListener {
// adapter?.refresh(binding.viewPager.currentItem) // adapter?.refresh(binding.viewPager.currentItem)
......
...@@ -3,9 +3,7 @@ package com.ccwangluo.accelerator.ui.home ...@@ -3,9 +3,7 @@ package com.ccwangluo.accelerator.ui.home
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.ccwangluo.accelerator.model.NewsModel import com.ccwangluo.accelerator.model.*
import com.ccwangluo.accelerator.model.Notice
import com.ccwangluo.accelerator.model.NoticeList
import com.ccwangluo.accelerator.utils.http.HttpGo import com.ccwangluo.accelerator.utils.http.HttpGo
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -14,30 +12,12 @@ import javax.security.auth.callback.Callback ...@@ -14,30 +12,12 @@ import javax.security.auth.callback.Callback
class NewsViewModel : ViewModel() { class NewsViewModel : ViewModel() {
val newsModel = MutableLiveData<NewsModel>() val isRefresh = MutableLiveData<Boolean>()
val notice = MutableLiveData<Notice>()
fun freshData(position: String, gameId: Int, page: Int) { val notice = MutableLiveData<List<Notice>>()
val type = when (position) {
"1" -> 1 val pluginList = MutableLiveData<List<Plugin>>()
"2" -> 2
"3" -> 4
"4" -> 5
else -> ""
}
viewModelScope.launch(Dispatchers.IO) {
val res =
HttpGo.getSync<NewsModel>("/api/new/all/list?gameId=$gameId&page=$page&size=10&type=$type")
res?.let {
if (it.code == 200) {
it.data?.let {
newsModel.postValue(it)
}
}
}
}
}
fun getNotice(gameId: Int) { fun getNotice(gameId: Int) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
...@@ -46,35 +26,24 @@ class NewsViewModel : ViewModel() { ...@@ -46,35 +26,24 @@ class NewsViewModel : ViewModel() {
res?.let { res?.let {
if (it.code == 200) { if (it.code == 200) {
it.data?.list?.let { it.data?.list?.let {
notice.postValue(it.get(0)) notice.postValue(it)
} }
} }
} }
} }
} }
/** fun getPlugin(gameId: Int) {
* 点赞
*/
fun greate(type: Int?,parentId : Int, gameId: Int, callback: () -> Unit) {
val map = mutableMapOf<String, String>()
map.put("gameId", gameId.toString())
map.put("parentId",parentId.toString())
type?.let {
map.put("type", it.toString())
}
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val res = val res =
HttpGo.postSync<String>("/api/new/great", map) HttpGo.getSync<PluginModel>("/api/plugin/list?gameId=$gameId&page=1&size=10")
res?.let { res?.let {
if (it.code == 200) { if (it.code == 200) {
withContext(Dispatchers.Main) { it.data?.list?.let {
callback() pluginList.postValue(it)
} }
} }
} }
} }
} }
} }
\ No newline at end of file
...@@ -79,10 +79,10 @@ class PhoneLoginActivity:XPageActivity() { ...@@ -79,10 +79,10 @@ class PhoneLoginActivity:XPageActivity() {
binding.authCodeBtn.isEnabled = false binding.authCodeBtn.isEnabled = false
binding.authCodeWait.setText("${it}秒后重新获得验证码") binding.authCodeWait.setText("${it}秒后重新获得验证码")
} else { } else {
resetCounter() resetCounter(it)
} }
}) })
loginViewModel.timerNumber.postValue(-1)
} }
...@@ -156,11 +156,15 @@ class PhoneLoginActivity:XPageActivity() { ...@@ -156,11 +156,15 @@ class PhoneLoginActivity:XPageActivity() {
} }
//重置按钮状态 //重置按钮状态
fun resetCounter() { fun resetCounter(i: Int) {
mCountTime = 60 mCountTime = 60
binding.authCodeBtn.visibility = View.VISIBLE binding.authCodeBtn.visibility = View.VISIBLE
binding.authCodeWait.visibility = View.GONE binding.authCodeWait.visibility = View.GONE
binding.authCodeBtn.setText("重新获取验证码") if (i == -1){
binding.authCodeBtn.setText("获取验证码")
} else {
binding.authCodeBtn.setText("重新获取验证码")
}
binding.authCodeBtn.isEnabled = true binding.authCodeBtn.isEnabled = true
} }
......
...@@ -6,11 +6,10 @@ import android.view.ViewGroup ...@@ -6,11 +6,10 @@ import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.ccwangluo.accelerator.databinding.FragmentSplashBinding import com.ccwangluo.accelerator.databinding.FragmentSplashBinding
import com.ccwangluo.accelerator.ui.BottomNavigationFragment import com.ccwangluo.accelerator.ui.BottomNavigationFragment
import com.ccwangluo.accelerator.utils.SysUtils import com.ccwangluo.accelerator.utils.AcceleratorUtils
import com.tencent.map.geolocation.TencentLocationManager import com.tencent.map.geolocation.TencentLocationManager
import com.xuexiang.xpage.annotation.Page import com.xuexiang.xpage.annotation.Page
import com.xuexiang.xpage.base.XPageFragment import com.xuexiang.xpage.base.XPageFragment
import com.xuexiang.xpage.core.PageOption
import com.xuexiang.xpage.utils.TitleBar import com.xuexiang.xpage.utils.TitleBar
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
...@@ -30,10 +29,14 @@ class SplashFragment : XPageFragment() { ...@@ -30,10 +29,14 @@ class SplashFragment : XPageFragment() {
} }
override fun initViews() { override fun initViews() {
lifecycleScope.launch(Dispatchers.IO) { AcceleratorUtils.getGameList(this) {
delay(1000) if (it) {
withContext(Dispatchers.Main) { lifecycleScope.launch(Dispatchers.IO) {
openPage(BottomNavigationFragment::class.java,false) delay(1000)
withContext(Dispatchers.Main) {
openPage(BottomNavigationFragment::class.java, false)
}
}
} }
} }
TencentLocationManager.getInstance(context) TencentLocationManager.getInstance(context)
......
...@@ -19,8 +19,10 @@ class NewsCollectionAdapter(fragment: Fragment, val titles: Array<String>) : ...@@ -19,8 +19,10 @@ class NewsCollectionAdapter(fragment: Fragment, val titles: Array<String>) :
return fragment return fragment
} }
fun refresh(index:Int) { fun refresh(index: Int) {
list.get(index).refresh() if (index < list.size) {
list.get(index).refresh()
}
} }
companion object { companion object {
......
...@@ -6,6 +6,7 @@ import android.view.View ...@@ -6,6 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
...@@ -23,6 +24,7 @@ import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard ...@@ -23,6 +24,7 @@ import fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard
import com.ccwangluo.accelerator.model.NewsModel import com.ccwangluo.accelerator.model.NewsModel
import com.ccwangluo.accelerator.ui.view.RatingBar import com.ccwangluo.accelerator.ui.view.RatingBar
import com.ccwangluo.accelerator.ui.web.CommonWebViewFragment import com.ccwangluo.accelerator.ui.web.CommonWebViewFragment
import com.github.shadowsocks.http.HttpConfig
class NewsObjectFragment : XPageFragment() { class NewsObjectFragment : XPageFragment() {
...@@ -32,14 +34,16 @@ class NewsObjectFragment : XPageFragment() { ...@@ -32,14 +34,16 @@ class NewsObjectFragment : XPageFragment() {
return null return null
} }
private lateinit var newsViewModel: NewsViewModel private var newsViewModel: NewsObjectModel? = null
private lateinit var viewModel: NewsViewModel
private val dataList = arrayListOf<News>() private val dataList = arrayListOf<News>()
private var page = 1 private var page = 1
private lateinit var position: String private lateinit var position: String
private var newsModel: NewsModel? = null private var newsModel: NewsModel? = null
override fun inflateView(inflater: LayoutInflater?, container: ViewGroup?): View { override fun inflateView(inflater: LayoutInflater?, container: ViewGroup?): View {
newsViewModel = ViewModelProvider(this).get(NewsViewModel::class.java) viewModel = ViewModelProvider(requireActivity()).get(NewsViewModel::class.java)
newsViewModel = ViewModelProvider(this).get(NewsObjectModel::class.java)
return inflater!!.inflate(R.layout.fragment_collection_object, container, false) return inflater!!.inflate(R.layout.fragment_collection_object, container, false)
} }
...@@ -86,8 +90,11 @@ class NewsObjectFragment : XPageFragment() { ...@@ -86,8 +90,11 @@ class NewsObjectFragment : XPageFragment() {
vedio.setUp( vedio.setUp(
it, JCVideoPlayer.SCREEN_LAYOUT_LIST it, JCVideoPlayer.SCREEN_LAYOUT_LIST
) )
// Glide.with(this@NewsObjectFragment).load(url) itemData.videoImg?.let {
// .into(vedio.thumbImageView) Glide.with(this@NewsObjectFragment).load(it)
.into(vedio.thumbImageView)
}
} }
val star = itemView.findViewById<RatingBar>(R.id.star) val star = itemView.findViewById<RatingBar>(R.id.star)
itemData.star?.let { itemData.star?.let {
...@@ -104,7 +111,7 @@ class NewsObjectFragment : XPageFragment() { ...@@ -104,7 +111,7 @@ class NewsObjectFragment : XPageFragment() {
itemView.findViewById<TextView>(R.id.great_num).setText("${it}") itemView.findViewById<TextView>(R.id.great_num).setText("${it}")
} }
itemData.isGreat?.let { itemData.isGreat?.let {
if(it) { if (it) {
itemView.findViewById<ImageView>(R.id.great_img) itemView.findViewById<ImageView>(R.id.great_img)
.setBackgroundResource(R.mipmap.icon_praise_bu) .setBackgroundResource(R.mipmap.icon_praise_bu)
} else { } else {
...@@ -117,7 +124,7 @@ class NewsObjectFragment : XPageFragment() { ...@@ -117,7 +124,7 @@ class NewsObjectFragment : XPageFragment() {
if (it) { if (it) {
return@setOnClickListener return@setOnClickListener
} }
newsViewModel.greate(itemData.type, gameId, itemData.id,{ newsViewModel?.greate(itemData.type, gameId, itemData.id, {
itemData.isGreat = true itemData.isGreat = true
recycle_view?.adapter?.notifyDataSetChanged() recycle_view?.adapter?.notifyDataSetChanged()
}) })
...@@ -126,20 +133,16 @@ class NewsObjectFragment : XPageFragment() { ...@@ -126,20 +133,16 @@ class NewsObjectFragment : XPageFragment() {
itemView.setOnClickListener { itemView.setOnClickListener {
val params = Bundle() val params = Bundle()
params.putString(CommonWebViewFragment.WEBVIEW_URL_KEY, "/gameDetail?gameId=${gameId}&id=${itemData.id}") params.putString(
CommonWebViewFragment.WEBVIEW_URL_KEY,HttpConfig.UI_MAIN_URL +
"/gameDetail?gameId=${gameId}&id=${itemData.id}"
)
openPage(CommonWebViewFragment::class.java, params) openPage(CommonWebViewFragment::class.java, params)
} }
} }
.create() .create()
recycle_view?.adapter = adapter recycle_view?.adapter = adapter
AcceleratorUtils.getGameList(this@NewsObjectFragment) { refresh()
if (it) {
AcceleratorUtils.game?.let {
gameId = it.id
newsViewModel.freshData(position, it.id, page)
}
}
}
recycle_view?.addOnScrollListener(object : RecyclerView.OnScrollListener() { recycle_view?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState) super.onScrollStateChanged(recyclerView, newState)
...@@ -151,7 +154,7 @@ class NewsObjectFragment : XPageFragment() { ...@@ -151,7 +154,7 @@ class NewsObjectFragment : XPageFragment() {
newsModel?.let { newsModel?.let {
if (dataList.size < it.total) { if (dataList.size < it.total) {
page++ page++
newsViewModel.freshData(position, gameId, page) newsViewModel?.freshData(position, gameId, page)
} }
} }
...@@ -159,10 +162,11 @@ class NewsObjectFragment : XPageFragment() { ...@@ -159,10 +162,11 @@ class NewsObjectFragment : XPageFragment() {
} }
}) })
} }
newsViewModel.newsModel.observe(this, { newsViewModel?.newsModel?.observe(this, {
newsModel = it newsModel = it
dataList.addAll(it.list) dataList.addAll(it.list)
recycle_view?.adapter?.notifyDataSetChanged() recycle_view?.adapter?.notifyDataSetChanged()
viewModel.isRefresh.postValue(true)
}) })
} }
...@@ -178,9 +182,10 @@ class NewsObjectFragment : XPageFragment() { ...@@ -178,9 +182,10 @@ class NewsObjectFragment : XPageFragment() {
fun refresh() { fun refresh() {
AcceleratorUtils.game?.let { AcceleratorUtils.game?.let {
dataList.clear()
gameId = it.id gameId = it.id
page = 1 page = 1
newsViewModel.freshData(position, it.id, page) newsViewModel?.freshData(position, it.id, page)
} }
} }
......
package com.ccwangluo.accelerator.ui.news
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.ccwangluo.accelerator.model.NewsModel
import com.ccwangluo.accelerator.utils.http.HttpGo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class NewsObjectModel : ViewModel() {
val newsModel = MutableLiveData<NewsModel>()
fun freshData(position: String, gameId: Int, page: Int) {
val type = when (position) {
"1" -> 1
"2" -> 2
"3" -> 4
"4" -> 5
else -> ""
}
viewModelScope.launch(Dispatchers.IO) {
val res =
HttpGo.getSync<NewsModel>("/api/new/all/list?gameId=$gameId&page=$page&size=10&type=$type")
res?.let {
if (it.code == 200) {
it.data?.let {
newsModel.postValue(it)
}
}
}
}
}
/**
* 点赞
*/
fun greate(type: Int?,parentId : Int, gameId: Int, callback: () -> Unit) {
val map = mutableMapOf<String, String>()
map.put("gameId", gameId.toString())
map.put("parentId",parentId.toString())
type?.let {
map.put("type", it.toString())
}
viewModelScope.launch(Dispatchers.IO) {
val res =
HttpGo.postSync<String>("/api/new/great", map)
res?.let {
if (it.code == 200) {
withContext(Dispatchers.Main) {
callback()
}
}
}
}
}
}
\ No newline at end of file
...@@ -21,6 +21,7 @@ import com.hjq.toast.ToastUtils ...@@ -21,6 +21,7 @@ import com.hjq.toast.ToastUtils
import java.lang.Exception import java.lang.Exception
import android.util.DisplayMetrics import android.util.DisplayMetrics
import com.ccwangluo.accelerator.utils.SysUtils import com.ccwangluo.accelerator.utils.SysUtils
import java.util.*
/** /**
...@@ -127,35 +128,38 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb) ...@@ -127,35 +128,38 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb)
@JavascriptInterface @JavascriptInterface
fun requirePermissionState(key: String, callback: String) { fun requirePermissionState(key: String, callback: String) {
xPageFragment.context?.let { xPageFragment.context?.let {
//获取权限 PermissionUtils.permission(key).rationale({
Dexter.withContext(it) PermissionUtils.openAppSettings()
.withPermissions(key) }).callback(object : PermissionUtils.FullCallback {
.withListener(object : MultiplePermissionsListener { override fun onGranted(permissionsGranted: MutableList<String>?) {
override fun onPermissionsChecked(p0: MultiplePermissionsReport?) { permissionsGranted?.forEach {
p0?.let { if (it.equals(key)) {
it.grantedPermissionResponses.forEach { agentWeb.getJsAccessEntrace()
if (it.permissionName.equals(key)) { .quickCallJs(callback, key, "true")
agentWeb.getJsAccessEntrace()
.quickCallJs(callback, key, "true")
}
}
it.deniedPermissionResponses.forEach {
if (it.permissionName.equals(key)) {
agentWeb.getJsAccessEntrace()
.quickCallJs(callback, key, "false")
}
}
} }
} }
override fun onPermissionRationaleShouldBeShown( }
p0: MutableList<PermissionRequest>?,
p1: PermissionToken? override fun onDenied(
) { permissionsDeniedForever: MutableList<String>?,
PermissionUtils.openAppSettings() permissionsDenied: MutableList<String>?
) {
permissionsDenied?.forEach {
if (it.equals(key)) {
agentWeb.getJsAccessEntrace()
.quickCallJs(callback, key, "false")
}
} }
permissionsDeniedForever?.forEach {
if (it.equals(key)) {
PermissionUtils.openAppSettings()
}
}
}
}).check() }).request()
} }
} }
...@@ -165,9 +169,9 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb) ...@@ -165,9 +169,9 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb)
@JavascriptInterface @JavascriptInterface
fun getPackageState(packageName: String, callback: String) { fun getPackageState(packageName: String, callback: String) {
xPageFragment.context?.let { xPageFragment.context?.let {
val packageInstall = AppUtils.isInstallApp(packageName) val packageInstall = SysUtils.isPackageInstall(it, packageName)
agentWeb.getJsAccessEntrace() agentWeb.getJsAccessEntrace()
.quickCallJs(callback, packageName, packageInstall.toString()) .quickCallJs(callback, packageName,packageInstall.toString())
} }
} }
...@@ -228,7 +232,11 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb) ...@@ -228,7 +232,11 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb)
@JavascriptInterface @JavascriptInterface
fun getSystemVersion(callback: String) { fun getSystemVersion(callback: String) {
agentWeb.getJsAccessEntrace() agentWeb.getJsAccessEntrace()
.quickCallJs(callback, android.os.Build.VERSION.RELEASE) .quickCallJs(
callback,
android.os.Build.VERSION.RELEASE,
SysUtils.getDpi(xPageFragment).toString()
)
} }
/** /**
...@@ -240,4 +248,10 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb) ...@@ -240,4 +248,10 @@ class AndroidInterface(val xPageFragment: XPageFragment, val agentWeb: AgentWeb)
.quickCallJs(callback, SysUtils.getDpi(xPageFragment).toString()) .quickCallJs(callback, SysUtils.getDpi(xPageFragment).toString())
} }
@JavascriptInterface
fun closeApp() {
LoginUtils.clearToken()
System.exit(0)
}
} }
\ No newline at end of file
...@@ -52,6 +52,8 @@ object AcceleratorUtils { ...@@ -52,6 +52,8 @@ object AcceleratorUtils {
//游戏 //游戏
var game: GameInfo? = null var game: GameInfo? = null
var isOpenSetting = true
//加速前延迟 //加速前延迟
var pre_net = -1 var pre_net = -1
...@@ -70,7 +72,9 @@ object AcceleratorUtils { ...@@ -70,7 +72,9 @@ object AcceleratorUtils {
val res = HttpGo.getSync<Game>("/api/new/game/list?id=1&page=1&size=1") val res = HttpGo.getSync<Game>("/api/new/game/list?id=1&page=1&size=1")
res?.let { res?.let {
game = it.data?.list?.get(0) game = it.data?.list?.get(0)
callback(true) withContext(Dispatchers.Main){
callback(true)
}
game?.let { game?.let {
AuthManager.gameId = it.id.toString() AuthManager.gameId = it.id.toString()
} }
...@@ -84,28 +88,19 @@ object AcceleratorUtils { ...@@ -84,28 +88,19 @@ object AcceleratorUtils {
fun initConnect(context: AppCompatActivity, connect: ActivityResultLauncher<Void?>) { fun initConnect(context: AppCompatActivity, connect: ActivityResultLauncher<Void?>) {
this.context = context this.context = context
this.connect = connect this.connect = connect
if (SysUtils.isVpn(context) && state != BaseService.State.Connected){
CommonDialog(context).setTitle("VPN被挤占")
.setContent("请确保已关闭其他加速器,并未开起任何游戏空间等类似功能")
.setBtnLeft("取消", {
context.finish()
}).setBtnRight("我知道了", {
context.finish()
NetworkUtils.openWirelessSettings()
}).show<CommonDialog>()
return
}
connection.connect(context, shadowsocksConnection) connection.connect(context, shadowsocksConnection)
ProfileManager.ensureNotEmpty() ProfileManager.ensureNotEmpty()
context.lifecycleScope.launch(Dispatchers.IO) { context.lifecycleScope.launch(Dispatchers.IO) {
while (true) { while (true) {
game?.let { game?.let {
val net = SysUtils.getNetPing(it.boosterServerIp) val split = it.boosterServer.split(":")
println(net) var net = NetState(-1, -1, -1, "100")
if (state != BaseService.State.Connected) { if (state != BaseService.State.Connected) {
net.delay = NetUtils.tcpPing(split[0], split[1].toInt()).toInt()
pre_net = net.delay pre_net = net.delay
acc_net = -1 acc_net = -1
} else { } else {
net.delay = NetUtils.tcpPing(split[0], split[1].toInt(), 1080).toInt()
acc_net = if (net.delay > pre_net) pre_net else net.delay acc_net = if (net.delay > pre_net) pre_net else net.delay
LoginUtils.getUserHasTimer { LoginUtils.getUserHasTimer {
if (!it) { //没有加速时长关闭服务 if (!it) { //没有加速时长关闭服务
...@@ -113,9 +108,12 @@ object AcceleratorUtils { ...@@ -113,9 +108,12 @@ object AcceleratorUtils {
} }
} }
} }
net.lossRate = if (net.delay == -1) "100" else "0"
net.preNetDelay = pre_net net.preNetDelay = pre_net
net.accNetDelay = acc_net net.accNetDelay = acc_net
stateListener(state, getAccTime(), net) withContext(Dispatchers.Main) {
stateListener(state, getAccTime(), net)
}
} }
delay(1000) delay(1000)
} }
...@@ -128,6 +126,20 @@ object AcceleratorUtils { ...@@ -128,6 +126,20 @@ object AcceleratorUtils {
} }
} }
fun checkVpn() {
if (SysUtils.isVpn(context) && state != BaseService.State.Connected && isOpenSetting) {
isOpenSetting = false
CommonDialog(context).setTitle("VPN被挤占")
.setContent("请确保已关闭其他加速器,并未开起任何游戏空间等类似功能")
.setBtnLeft("取消", {
}).setBtnRight("我知道了", {
}).show<CommonDialog>()
return
}
}
fun startAccelerator(xPageFragment: XPageFragment) { fun startAccelerator(xPageFragment: XPageFragment) {
game?.let { game?.let {
initAuthProfile(xPageFragment) initAuthProfile(xPageFragment)
......
...@@ -41,7 +41,7 @@ object LoginUtils { ...@@ -41,7 +41,7 @@ object LoginUtils {
userProfile = it userProfile = it
} }
} else { } else {
ToastUtils.show(it.error) // ToastUtils.show(it.error)
} }
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
callBack(userProfile) callBack(userProfile)
......
...@@ -49,8 +49,6 @@ object PhoneUtils { ...@@ -49,8 +49,6 @@ object PhoneUtils {
} }
} }
fun openLoginAuth(xPageFragment: XPageFragment, callback: (Boolean, String) -> Unit) { fun openLoginAuth(xPageFragment: XPageFragment, callback: (Boolean, String) -> Unit) {
xPageFragment.context?.let { xPageFragment.context?.let {
OneKeyLoginManager.getInstance().setAuthThemeConfig(getEConfig(it, xPageFragment)) OneKeyLoginManager.getInstance().setAuthThemeConfig(getEConfig(it, xPageFragment))
......
...@@ -51,19 +51,20 @@ object HttpGo { ...@@ -51,19 +51,20 @@ object HttpGo {
LoginUtils.token?.let { LoginUtils.token?.let {
request.addHeader("Authorization", it) request.addHeader("Authorization", it)
} }
Timber.i(request.toString()) Timber.i("%s%s", url, request.toString())
val call = okHttpClient.newCall(request.build()) val call = okHttpClient.newCall(request.build())
val response: Response = call.execute() val response: Response = call.execute()
if (response.isSuccessful) { if (response.isSuccessful) {
val type = object : TypeToken<BaseModel<T>>() {}.type val type = object : TypeToken<BaseModel<T>>() {}.type
val string = response.body?.string() val string = response.body?.string()
Timber.i(string.toString()) Timber.i("%s%s", url, string.toString())
return gson.fromJson(string, type) return gson.fromJson(string, type)
} else { } else {
ToastUtils.show("网络错误") ToastUtils.show("网络错误")
} }
} catch (e: java.lang.Exception) { } catch (e: java.lang.Exception) {
ToastUtils.show("网络错误") ToastUtils.show("网络错误")
} }
return null return null
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
android:background="@color/white"> android:background="@color/white">
<androidx.coordinatorlayout.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
...@@ -19,62 +20,71 @@ ...@@ -19,62 +20,71 @@
android:background="@color/white" android:background="@color/white"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<TextView <com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent" android:id="@+id/collap"
android:layout_height="wrap_content"
android:background="@mipmap/new_top"
android:gravity="center"
android:paddingTop="36dp"
android:paddingBottom="16dp"
android:text="地下城与勇士 韩服"
android:textColor="#FFFFFFFF"
android:textSize="16sp"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|exitUntilCollapsed" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/game_news_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="21dp" app:contentScrim="@color/colorPrimary"
android:background="@color/white" app:layout_scrollFlags="snap|scroll|exitUntilCollapsed">
android:orientation="horizontal"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
</androidx.recyclerview.widget.RecyclerView> <LinearLayout
android:layout_width="match_parent"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="21dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
app:layout_collapseMode="parallax"
app:layout_scrollFlags="noScroll">
<ImageView
android:layout_width="17.95dp"
android:layout_height="14.6dp"
android:layout_gravity="center_vertical"
android:background="@mipmap/icon_notice" />
<com.xuexiang.xui.widget.textview.MarqueeTextView
android:id="@+id/tv_marquee"
android:layout_width="299dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="3dp" android:orientation="vertical">
android:gravity="center"
android:text=""
android:textColor="#FF1A1A1A" <TextView
android:textSize="14sp" android:layout_width="match_parent"
app:mtv_isAutoDisplay="true" android:layout_height="wrap_content"
app:mtv_isAutoFit="true" /> android:background="@mipmap/new_top"
android:gravity="center"
</LinearLayout> android:paddingTop="36dp"
android:paddingBottom="16dp"
android:text="地下城与勇士 韩服"
android:textColor="#FFFFFFFF"
android:textSize="16sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/game_news_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="21dp"
android:background="@color/white"
android:orientation="horizontal">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="21dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp">
<ImageView
android:layout_width="17.95dp"
android:layout_height="14.6dp"
android:layout_gravity="center_vertical"
android:background="@mipmap/icon_notice" />
<com.xuexiang.xui.widget.textview.MarqueeTextView
android:id="@+id/tv_marquee"
android:layout_width="299dp"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:gravity="center"
android:text=""
android:textColor="#FF1A1A1A"
android:textSize="14sp"
app:mtv_isAutoDisplay="true"
app:mtv_isAutoFit="true" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@color/white" android:background="@color/white"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16.5dp" android:layout_marginTop="16.5dp"
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
</LinearLayout> </LinearLayout>
<com.ccwangluo.accelerator.ui.view.RatingBar <com.ccwangluo.accelerator.ui.view.RatingBar
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:id="@+id/star" android:id="@+id/star"
android:visibility="gone" android:visibility="gone"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
...@@ -64,6 +66,8 @@ ...@@ -64,6 +66,8 @@
app:starStep="0" app:starStep="0"
app:stepSize="Half"/> app:stepSize="Half"/>
<TextView <TextView
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
...@@ -74,6 +78,8 @@ ...@@ -74,6 +78,8 @@
android:textSize="14sp" /> android:textSize="14sp" />
<TextView <TextView
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:id="@+id/abbrContent" android:id="@+id/abbrContent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
...@@ -84,6 +90,8 @@ ...@@ -84,6 +90,8 @@
android:textSize="14sp" /> android:textSize="14sp" />
<ImageView <ImageView
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:id="@+id/imgs" android:id="@+id/imgs"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="182.5dp" android:layout_height="182.5dp"
...@@ -92,6 +100,8 @@ ...@@ -92,6 +100,8 @@
android:visibility="gone" /> android:visibility="gone" />
<fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard <fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:id="@+id/video_view" android:id="@+id/video_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="182.5dp" android:layout_height="182.5dp"
...@@ -100,6 +110,8 @@ ...@@ -100,6 +110,8 @@
<RelativeLayout <RelativeLayout
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="11dp" android:layout_marginTop="11dp"
...@@ -132,6 +144,10 @@ ...@@ -132,6 +144,10 @@
android:background="@mipmap/icon_praise_ga" /> android:background="@mipmap/icon_praise_ga" />
</RelativeLayout> </RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#FFEFEFF4"
/>
</LinearLayout> </LinearLayout>
\ No newline at end of file
...@@ -5,16 +5,17 @@ ...@@ -5,16 +5,17 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
android:id="@+id/plugin_img"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:background="@mipmap/game_download" /> android:background="@mipmap/game_download" />
<TextView <TextView
android:id="@+id/plugin_name"
android:layout_width="70dp" android:layout_width="70dp"
android:layout_height="20dp" android:layout_height="20dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
......
...@@ -3,14 +3,16 @@ package com.github.shadowsocks.http ...@@ -3,14 +3,16 @@ package com.github.shadowsocks.http
object HttpConfig { object HttpConfig {
//app后端 //app后端
val baseUrl = "https://test-cc-tt-api.orangenet.org.cn" val baseUrl = "https://test-cc-tt-api.orangenet.org.cn" //测试
// val baseUrl = "https://cc-tt-front.srccwl.com" //生产
/** /**
* 主页h5 * 主页h5
*/ */
// val UI_MAIN_URL = "https://test-cc-tt-front.orangenet.org.cn/#" val UI_MAIN_URL = "https://test-cc-tt-front.orangenet.org.cn/#" //测试
val UI_MAIN_URL = "http://10.3.0.217:8080/#" // val UI_MAIN_URL = "http://10.3.0.217:8080/#"
// val UI_MAIN_URL = "https://cc-tt-front.srccwl.com/#" //生产
//隐私协议地址 //隐私协议地址
val privacy_url = "http:wwww.baidu.com" val privacy_url = "http:wwww.baidu.com"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment