|
|
@ -33,45 +33,37 @@ import org.isoron.androidbase.activities.*
|
|
|
|
import org.isoron.androidbase.utils.*
|
|
|
|
import org.isoron.androidbase.utils.*
|
|
|
|
import org.isoron.androidbase.utils.InterfaceUtils.getFontAwesome
|
|
|
|
import org.isoron.androidbase.utils.InterfaceUtils.getFontAwesome
|
|
|
|
import org.isoron.uhabits.*
|
|
|
|
import org.isoron.uhabits.*
|
|
|
|
import org.isoron.uhabits.core.preferences.*
|
|
|
|
import org.isoron.uhabits.core.ui.screens.sync.*
|
|
|
|
import org.isoron.uhabits.core.tasks.*
|
|
|
|
|
|
|
|
import org.isoron.uhabits.databinding.*
|
|
|
|
import org.isoron.uhabits.databinding.*
|
|
|
|
import org.isoron.uhabits.sync.*
|
|
|
|
import org.isoron.uhabits.sync.*
|
|
|
|
import org.isoron.uhabits.utils.*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SyncActivity : BaseActivity() {
|
|
|
|
class SyncActivity : BaseActivity(), SyncBehavior.Screen {
|
|
|
|
|
|
|
|
|
|
|
|
private lateinit var syncManager: SyncManager
|
|
|
|
|
|
|
|
private lateinit var preferences: Preferences
|
|
|
|
|
|
|
|
private lateinit var taskRunner: TaskRunner
|
|
|
|
|
|
|
|
private lateinit var baseScreen: BaseScreen
|
|
|
|
private lateinit var baseScreen: BaseScreen
|
|
|
|
private lateinit var binding: ActivitySyncBinding
|
|
|
|
private lateinit var binding: ActivitySyncBinding
|
|
|
|
|
|
|
|
private lateinit var behavior: SyncBehavior
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private val scope = CoroutineScope(Dispatchers.Main)
|
|
|
|
private var styledResources = StyledResources(this)
|
|
|
|
private var styledResources = StyledResources(this)
|
|
|
|
|
|
|
|
|
|
|
|
override fun onCreate(state: Bundle?) {
|
|
|
|
override fun onCreate(state: Bundle?) {
|
|
|
|
super.onCreate(state)
|
|
|
|
super.onCreate(state)
|
|
|
|
|
|
|
|
|
|
|
|
baseScreen = BaseScreen(this)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val component = (application as HabitsApplication).component
|
|
|
|
val component = (application as HabitsApplication).component
|
|
|
|
taskRunner = component.taskRunner
|
|
|
|
val preferences = component.preferences
|
|
|
|
preferences = component.preferences
|
|
|
|
val server = RemoteSyncServer(baseURL = preferences.syncBaseURL)
|
|
|
|
syncManager = component.syncManager
|
|
|
|
baseScreen = BaseScreen(this)
|
|
|
|
|
|
|
|
behavior = SyncBehavior(this, preferences, server)
|
|
|
|
|
|
|
|
|
|
|
|
binding = ActivitySyncBinding.inflate(layoutInflater)
|
|
|
|
binding = ActivitySyncBinding.inflate(layoutInflater)
|
|
|
|
setContentView(binding.root)
|
|
|
|
setContentView(binding.root)
|
|
|
|
|
|
|
|
|
|
|
|
binding.errorIcon.typeface = getFontAwesome(this)
|
|
|
|
binding.errorIcon.typeface = getFontAwesome(this)
|
|
|
|
|
|
|
|
|
|
|
|
setSupportActionBar(binding.toolbar)
|
|
|
|
setSupportActionBar(binding.toolbar)
|
|
|
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
|
|
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
|
|
|
supportActionBar?.setDisplayShowHomeEnabled(true)
|
|
|
|
supportActionBar?.setDisplayShowHomeEnabled(true)
|
|
|
|
supportActionBar?.elevation = 10.0f
|
|
|
|
supportActionBar?.elevation = 10.0f
|
|
|
|
|
|
|
|
|
|
|
|
binding.instructions.setText(Html.fromHtml(resources.getString(R.string.sync_instructions)))
|
|
|
|
binding.instructions.setText(Html.fromHtml(resources.getString(R.string.sync_instructions)))
|
|
|
|
|
|
|
|
|
|
|
|
binding.syncLink.setOnClickListener {
|
|
|
|
binding.syncLink.setOnClickListener {
|
|
|
|
copyToClipboard()
|
|
|
|
copyToClipboard()
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -79,96 +71,62 @@ class SyncActivity : BaseActivity() {
|
|
|
|
|
|
|
|
|
|
|
|
override fun onResume() {
|
|
|
|
override fun onResume() {
|
|
|
|
super.onResume()
|
|
|
|
super.onResume()
|
|
|
|
if(preferences.syncKey.isBlank()) {
|
|
|
|
scope.launch {
|
|
|
|
register()
|
|
|
|
behavior.onResume()
|
|
|
|
} else {
|
|
|
|
|
|
|
|
displayCurrentKey()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun displayCurrentKey() {
|
|
|
|
private fun copyToClipboard() {
|
|
|
|
displayLink("https://loophabits.org/sync/${preferences.syncKey}#${preferences.encryptionKey}")
|
|
|
|
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
|
|
|
|
|
|
clipboard.setPrimaryClip(ClipData.newPlainText("Loop Sync Link", binding.syncLink.text))
|
|
|
|
|
|
|
|
baseScreen.showMessage(R.string.copied_to_the_clipboard, binding.root)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun register() {
|
|
|
|
suspend fun generateQR(msg: String): Bitmap = Dispatchers.IO {
|
|
|
|
displayLoading()
|
|
|
|
val writer = QRCodeWriter()
|
|
|
|
taskRunner.execute(object : Task {
|
|
|
|
val matrix = writer.encode(msg, BarcodeFormat.QR_CODE, 1024, 1024)
|
|
|
|
private lateinit var encKey: EncryptionKey
|
|
|
|
val height = matrix.height
|
|
|
|
private lateinit var syncKey: String
|
|
|
|
val width = matrix.width
|
|
|
|
private var error = false
|
|
|
|
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
|
|
|
|
override fun doInBackground() {
|
|
|
|
val bgColor = styledResources.getColor(R.attr.highContrastReverseTextColor)
|
|
|
|
runBlocking {
|
|
|
|
val fgColor = styledResources.getColor(R.attr.highContrastTextColor)
|
|
|
|
try {
|
|
|
|
for (x in 0 until width) {
|
|
|
|
val server = RemoteSyncServer(baseURL = preferences.syncBaseURL)
|
|
|
|
for (y in 0 until height) {
|
|
|
|
syncKey = server.register()
|
|
|
|
val color = if (matrix.get(x, y)) fgColor else bgColor
|
|
|
|
encKey = EncryptionKey.generate()
|
|
|
|
bitmap.setPixel(x, y, color)
|
|
|
|
preferences.enableSync(syncKey, encKey.base64)
|
|
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
|
|
Log.e("SyncActivity", "Unexpected exception", e)
|
|
|
|
|
|
|
|
error = true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return@IO bitmap
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
suspend fun showQR(msg: String) {
|
|
|
|
|
|
|
|
binding.progress.visibility = View.GONE
|
|
|
|
|
|
|
|
binding.qrCode.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
binding.qrCode.setImageBitmap(generateQR(msg))
|
|
|
|
|
|
|
|
|
|
|
|
override fun onPostExecute() {
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
|
|
|
displayError()
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
displayCurrentKey()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun displayLoading() {
|
|
|
|
override suspend fun showLoadingScreen() {
|
|
|
|
binding.qrCode.visibility = View.GONE
|
|
|
|
binding.qrCode.visibility = View.GONE
|
|
|
|
binding.progress.visibility = View.VISIBLE
|
|
|
|
binding.progress.visibility = View.VISIBLE
|
|
|
|
binding.errorPanel.visibility = View.GONE
|
|
|
|
binding.errorPanel.visibility = View.GONE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun displayError() {
|
|
|
|
override suspend fun showErrorScreen() {
|
|
|
|
binding.qrCode.visibility = View.GONE
|
|
|
|
binding.qrCode.visibility = View.GONE
|
|
|
|
binding.progress.visibility = View.GONE
|
|
|
|
binding.progress.visibility = View.GONE
|
|
|
|
binding.errorPanel.visibility = View.VISIBLE
|
|
|
|
binding.errorPanel.visibility = View.VISIBLE
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun copyToClipboard() {
|
|
|
|
override suspend fun showLink(link: String) {
|
|
|
|
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
|
|
|
|
|
|
clipboard.setPrimaryClip(ClipData.newPlainText("Loop Sync Link", binding.syncLink.text))
|
|
|
|
|
|
|
|
baseScreen.showMessage(R.string.copied_to_the_clipboard, binding.root)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun displayLink(link: String) {
|
|
|
|
|
|
|
|
binding.qrCode.visibility = View.GONE
|
|
|
|
binding.qrCode.visibility = View.GONE
|
|
|
|
binding.progress.visibility = View.VISIBLE
|
|
|
|
binding.progress.visibility = View.VISIBLE
|
|
|
|
binding.errorPanel.visibility = View.GONE
|
|
|
|
binding.errorPanel.visibility = View.GONE
|
|
|
|
binding.syncLink.text = link
|
|
|
|
binding.syncLink.text = link
|
|
|
|
displayQR(link)
|
|
|
|
showQR(link)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun displayQR(msg: String) {
|
|
|
|
override fun logError(msg: String) {
|
|
|
|
taskRunner.execute(object : Task {
|
|
|
|
Log.e("SyncActivity", msg)
|
|
|
|
lateinit var bitmap: Bitmap
|
|
|
|
|
|
|
|
override fun doInBackground() {
|
|
|
|
|
|
|
|
val writer = QRCodeWriter()
|
|
|
|
|
|
|
|
val matrix = writer.encode(msg, BarcodeFormat.QR_CODE, 1024, 1024)
|
|
|
|
|
|
|
|
val height = matrix.height
|
|
|
|
|
|
|
|
val width = matrix.width
|
|
|
|
|
|
|
|
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
|
|
|
|
|
|
|
|
val bgColor = styledResources.getColor(R.attr.highContrastReverseTextColor)
|
|
|
|
|
|
|
|
val fgColor = styledResources.getColor(R.attr.highContrastTextColor)
|
|
|
|
|
|
|
|
for (x in 0 until width) {
|
|
|
|
|
|
|
|
for (y in 0 until height) {
|
|
|
|
|
|
|
|
val color = if (matrix.get(x, y)) fgColor else bgColor
|
|
|
|
|
|
|
|
bitmap.setPixel(x, y, color)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onPostExecute() {
|
|
|
|
|
|
|
|
binding.progress.visibility = View.GONE
|
|
|
|
|
|
|
|
binding.qrCode.visibility = View.VISIBLE
|
|
|
|
|
|
|
|
binding.qrCode.setImageBitmap(bitmap)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|