From 7992b807873e8c6d10f7409f066a4d4aa747eddf Mon Sep 17 00:00:00 2001 From: Billy Brawner Date: Fri, 17 May 2019 18:17:14 -0700 Subject: [PATCH] Migrate some classes to Kotlin --- app/build.gradle | 16 +- .../view/activity/MainActivity.java | 281 ------------------ .../view/activity/MainActivity.kt | 235 +++++++++++++++ .../view/activity/MarkdownInfoActivity.java | 59 ---- .../view/activity/MarkdownInfoActivity.kt | 45 +++ .../view/fragment/EditFragment.java | 154 ---------- .../view/fragment/EditFragment.kt | 120 ++++++++ .../view/fragment/PreviewFragment.java | 118 -------- .../view/fragment/PreviewFragment.kt | 98 ++++++ .../view/fragment/SettingsFragment.java | 4 + app/src/main/res/layout/activity_main.xml | 6 +- .../res/layout/activity_markdown_info.xml | 2 +- app/src/main/res/xml/pref_general.xml | 10 +- 13 files changed, 520 insertions(+), 628 deletions(-) delete mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java create mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.kt delete mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.java create mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.kt delete mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.java create mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.kt delete mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.java create mode 100644 app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.kt diff --git a/app/build.gradle b/app/build.gradle index 8b55ef5..4295dba 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,6 +33,7 @@ android { versionCode 18 versionName "0.6.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "true" } signingConfigs { release { @@ -47,6 +48,7 @@ android { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release + buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "false" } } flavorDimensions "platform" @@ -62,8 +64,6 @@ android { dependencies { def lifecycle_version = "2.0.0" - annotationProcessor 'com.google.dagger:dagger-compiler:2.21' - annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0' testImplementation 'junit:junit:4.12' testImplementation 'org.robolectric:robolectric:4.2' implementation fileTree(include: ['*.jar'], dir: 'libs') @@ -79,19 +79,21 @@ dependencies { implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.legacy:legacy-support-v13:1.0.0' implementation 'com.commonsware.cwac:anddown:0.3.0' - implementation 'com.google.dagger:dagger:2.21' - implementation 'com.jakewharton:butterknife:8.8.1' + implementation 'com.google.dagger:dagger:2.22.1' + annotationProcessor 'com.google.dagger:dagger-compiler:2.22.1' + kapt 'com.google.dagger:dagger-android-processor:2.22.1' + kapt 'com.google.dagger:dagger-compiler:2.22.1' implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0' implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxjava:2.2.7' - implementation 'com.google.firebase:firebase-core:16.0.8' + implementation 'com.google.firebase:firebase-core:16.0.9' implementation 'com.android.billingclient:billing:1.2' - implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9' + implementation 'com.crashlytics.sdk.android:crashlytics:2.10.0' implementation 'androidx.multidex:multidex:2.0.1' implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" - compile "androidx.core:core-ktx:1.0.1" + compile "androidx.core:core-ktx:1.0.2" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java deleted file mode 100644 index d99028c..0000000 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.wbrawner.simplemarkdown.view.activity; - -import android.Manifest; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.lifecycle.ViewModelProviders; - -import com.crashlytics.android.Crashlytics; -import com.google.android.material.tabs.TabLayout; -import com.wbrawner.simplemarkdown.MarkdownApplication; -import com.wbrawner.simplemarkdown.R; -import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter; -import com.wbrawner.simplemarkdown.utility.Constants; -import com.wbrawner.simplemarkdown.utility.Utils; -import com.wbrawner.simplemarkdown.view.DisableableViewPager; -import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter; - -import java.io.File; -import java.io.InputStream; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class MainActivity extends AppCompatActivity - implements ActivityCompat.OnRequestPermissionsResultCallback { - - @Inject - MarkdownPresenter presenter; - - @BindView(R.id.pager) - DisableableViewPager pager; - @BindView(R.id.layout_tab) - TabLayout tabLayout; - - private boolean shouldAutoSave = true; - private NewFileHandler newFileHandler; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - ((MarkdownApplication) getApplication()).getComponent().inject(this); - ButterKnife.bind(this); - pager.setAdapter( - new EditPagerAdapter(getSupportFragmentManager(), MainActivity.this) - ); - pager.setPageMargin(1); - pager.setPageMarginDrawable(R.color.colorAccent); - if (getResources().getConfiguration().orientation - == Configuration.ORIENTATION_LANDSCAPE) { - tabLayout.setVisibility(View.GONE); - } - newFileHandler = new NewFileHandler(); - if (getIntent().getBooleanExtra(Constants.EXTRA_EXPLORER, false)) { - requestFileOp(Constants.REQUEST_OPEN_FILE); - } - } - - @Override - protected void onUserLeaveHint() { - super.onUserLeaveHint(); - if (shouldAutoSave && !presenter.getMarkdown().isEmpty() && Utils.isAutosaveEnabled(this)) { - presenter.saveMarkdown(null, null); - } - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) - tabLayout.setVisibility(View.GONE); - else - tabLayout.setVisibility(View.VISIBLE); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_edit, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_save: - requestFileOp(Constants.REQUEST_SAVE_FILE); - break; - case R.id.action_share: - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_TEXT, presenter.getMarkdown()); - shareIntent.setType("text/plain"); - startActivity(Intent.createChooser( - shareIntent, - getString(R.string.share_file) - )); - break; - case R.id.action_load: - requestFileOp(Constants.REQUEST_OPEN_FILE); - break; - case R.id.action_new: - presenter.saveMarkdown(newFileHandler, null); - break; - case R.id.action_lock_swipe: - item.setChecked(!item.isChecked()); - pager.setSwipeLocked(item.isChecked()); - break; - case R.id.action_help: - showInfoActivity(R.id.action_help); - break; - case R.id.action_settings: - Intent settingsIntent = new Intent(MainActivity.this, SettingsActivity.class); - startActivity(settingsIntent); - break; - case R.id.action_libraries: - showInfoActivity(R.id.action_libraries); - break; - case R.id.action_privacy: - showInfoActivity(R.id.action_privacy); - break; - } - return super.onOptionsItemSelected(item); - } - - private void showInfoActivity(int action) { - Intent infoIntent = new Intent(MainActivity.this, MarkdownInfoActivity.class); - String fileName = ""; - String title = ""; - switch (action) { - case R.id.action_help: - fileName = "Cheatsheet.md"; - title = getString(R.string.action_help); - break; - case R.id.action_libraries: - fileName = "Libraries.md"; - title = getString(R.string.action_libraries); - break; - case R.id.action_privacy: - fileName = "Privacy Policy.md"; - title = getString(R.string.action_privacy); - break; - } - infoIntent.putExtra("title", title); - InputStream in = null; - try { - AssetManager assetManager = getAssets(); - if (assetManager != null) { - in = assetManager.open(fileName); - } - presenter.loadMarkdown(fileName, in, new MarkdownPresenter.OnTempFileLoadedListener() { - @Override - public void onSuccess(String html) { - infoIntent.putExtra("html", html); - startActivity(infoIntent); - } - - @Override - public void onError() { - Toast.makeText(MainActivity.this, R.string.file_load_error, Toast.LENGTH_SHORT) - .show(); - } - }); - } catch (Exception e) { - Crashlytics.logException(e); - Toast.makeText(MainActivity.this, R.string.file_load_error, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onRequestPermissionsResult( - int requestCode, - @NonNull String permissions[], - @NonNull int[] grantResults - ) { - switch (requestCode) { - case Constants.REQUEST_SAVE_FILE: - case Constants.REQUEST_OPEN_FILE: { - // If request is cancelled, the result arrays are empty. - if (grantResults.length > 0 - && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - // Permission granted, open file save dialog - requestFileOp(requestCode); - } else { - // Permission denied, do nothing - Toast.makeText(MainActivity.this, R.string.no_permissions, Toast.LENGTH_SHORT) - .show(); - } - break; - } - } - } - - @Override - public void onBackPressed() { - if (pager.getCurrentItem() == EditPagerAdapter.FRAGMENT_EDIT) - super.onBackPressed(); - else - pager.setCurrentItem(EditPagerAdapter.FRAGMENT_EDIT); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Constants.REQUEST_OPEN_FILE: - if (resultCode != RESULT_OK || data == null || !data.hasExtra(Constants.EXTRA_FILE)) { - break; - } - - File markdownFile = (File) data.getSerializableExtra(Constants.EXTRA_FILE); - presenter.loadMarkdown(markdownFile); - break; - case Constants.REQUEST_SAVE_FILE: - if (resultCode != RESULT_OK - || data == null - || !data.hasExtra(Constants.EXTRA_FILE_PATH) - || data.getStringExtra(Constants.EXTRA_FILE_PATH).isEmpty()) { - break; - } - String path = data.getStringExtra(Constants.EXTRA_FILE_PATH); - presenter.saveMarkdown(null, path); - break; - } - super.onActivityResult(requestCode, resultCode, data); - } - - private void requestFileOp(int requestType) { - if (Utils.canAccessFiles(MainActivity.this)) { - // If the user is going to save the file, we don't want to auto-save it for them - shouldAutoSave = false; - Intent intent = new Intent(MainActivity.this, ExplorerActivity.class); - intent.putExtra(Constants.EXTRA_REQUEST_CODE, requestType); - intent.putExtra(Constants.EXTRA_FILE, presenter.getFile()); - startActivityForResult( - intent, - requestType - ); - } else if (Build.VERSION.SDK_INT >= 23) { - requestPermissions( - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - requestType - ); - } - } - - @Override - protected void onResume() { - super.onResume(); - setTitle(presenter.getFileName()); - shouldAutoSave = true; - } - - private class NewFileHandler implements MarkdownPresenter.MarkdownSavedListener { - @Override - public void saveComplete(boolean success) { - if (success) { - String newFile = Utils.getDefaultFileName(MainActivity.this); - presenter.newFile(newFile); - } else { - Toast.makeText( - MainActivity.this, - R.string.file_save_error, - Toast.LENGTH_SHORT - ).show(); - } - } - } -} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.kt new file mode 100644 index 0000000..5002b43 --- /dev/null +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.kt @@ -0,0 +1,235 @@ +package com.wbrawner.simplemarkdown.view.activity + +import android.Manifest +import android.app.Activity +import android.content.Intent +import android.content.pm.PackageManager +import android.content.res.Configuration +import android.os.Build +import android.os.Bundle +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat +import com.crashlytics.android.Crashlytics +import com.wbrawner.simplemarkdown.MarkdownApplication +import com.wbrawner.simplemarkdown.R +import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter +import com.wbrawner.simplemarkdown.utility.Constants +import com.wbrawner.simplemarkdown.utility.Utils +import com.wbrawner.simplemarkdown.view.adapter.EditPagerAdapter +import kotlinx.android.synthetic.main.activity_main.* +import java.io.File +import java.io.InputStream +import javax.inject.Inject + +class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback { + + @Inject + lateinit var presenter: MarkdownPresenter + + private var shouldAutoSave = true + private var newFileHandler: NewFileHandler? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + (application as MarkdownApplication).component.inject(this) + pager.adapter = EditPagerAdapter(supportFragmentManager, this@MainActivity) + pager.pageMargin = 1 + pager.setPageMarginDrawable(R.color.colorAccent) + if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) { + tabLayout!!.visibility = View.GONE + } + newFileHandler = NewFileHandler() + if (intent.getBooleanExtra(Constants.EXTRA_EXPLORER, false)) { + requestFileOp(Constants.REQUEST_OPEN_FILE) + } + } + + override fun onUserLeaveHint() { + super.onUserLeaveHint() + if (shouldAutoSave && !presenter!!.markdown.isEmpty() && Utils.isAutosaveEnabled(this)) { + presenter!!.saveMarkdown(null, null) + } + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) + tabLayout!!.visibility = View.GONE + else + tabLayout!!.visibility = View.VISIBLE + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.menu_edit, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.action_save -> requestFileOp(Constants.REQUEST_SAVE_FILE) + R.id.action_share -> { + val shareIntent = Intent(Intent.ACTION_SEND) + shareIntent.putExtra(Intent.EXTRA_TEXT, presenter!!.markdown) + shareIntent.type = "text/plain" + startActivity(Intent.createChooser( + shareIntent, + getString(R.string.share_file) + )) + } + R.id.action_load -> requestFileOp(Constants.REQUEST_OPEN_FILE) + R.id.action_new -> presenter!!.saveMarkdown(newFileHandler, null) + R.id.action_lock_swipe -> { + item.isChecked = !item.isChecked + pager!!.setSwipeLocked(item.isChecked) + } + R.id.action_help -> showInfoActivity(R.id.action_help) + R.id.action_settings -> { + val settingsIntent = Intent(this@MainActivity, SettingsActivity::class.java) + startActivity(settingsIntent) + } + R.id.action_libraries -> showInfoActivity(R.id.action_libraries) + R.id.action_privacy -> showInfoActivity(R.id.action_privacy) + } + return super.onOptionsItemSelected(item) + } + + private fun showInfoActivity(action: Int) { + val infoIntent = Intent(this@MainActivity, MarkdownInfoActivity::class.java) + var fileName = "" + var title = "" + when (action) { + R.id.action_help -> { + fileName = "Cheatsheet.md" + title = getString(R.string.action_help) + } + R.id.action_libraries -> { + fileName = "Libraries.md" + title = getString(R.string.action_libraries) + } + R.id.action_privacy -> { + fileName = "Privacy Policy.md" + title = getString(R.string.action_privacy) + } + } + infoIntent.putExtra("title", title) + var `in`: InputStream? = null + try { + val assetManager = assets + if (assetManager != null) { + `in` = assetManager.open(fileName) + } + presenter!!.loadMarkdown(fileName, `in`, object : MarkdownPresenter.OnTempFileLoadedListener { + override fun onSuccess(html: String) { + infoIntent.putExtra("html", html) + startActivity(infoIntent) + } + + override fun onError() { + Toast.makeText(this@MainActivity, R.string.file_load_error, Toast.LENGTH_SHORT) + .show() + } + }) + } catch (e: Exception) { + Crashlytics.logException(e) + Toast.makeText(this@MainActivity, R.string.file_load_error, Toast.LENGTH_SHORT).show() + } + + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + when (requestCode) { + Constants.REQUEST_SAVE_FILE, Constants.REQUEST_OPEN_FILE -> { + // If request is cancelled, the result arrays are empty. + if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // Permission granted, open file save dialog + requestFileOp(requestCode) + } else { + // Permission denied, do nothing + Toast.makeText(this@MainActivity, R.string.no_permissions, Toast.LENGTH_SHORT) + .show() + } + } + } + } + + override fun onBackPressed() { + if (pager!!.currentItem == EditPagerAdapter.FRAGMENT_EDIT) + super.onBackPressed() + else + pager!!.currentItem = EditPagerAdapter.FRAGMENT_EDIT + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + when (requestCode) { + Constants.REQUEST_OPEN_FILE -> { + if (resultCode != Activity.RESULT_OK || data == null || !data.hasExtra(Constants.EXTRA_FILE)) { + return + } + + val markdownFile = data.getSerializableExtra(Constants.EXTRA_FILE) as File + presenter!!.loadMarkdown(markdownFile) + } + Constants.REQUEST_SAVE_FILE -> { + if (resultCode != Activity.RESULT_OK + || data == null + || !data.hasExtra(Constants.EXTRA_FILE_PATH) + || data.getStringExtra(Constants.EXTRA_FILE_PATH).isEmpty()) { + return + } + val path = data.getStringExtra(Constants.EXTRA_FILE_PATH) + presenter!!.saveMarkdown(null, path) + } + } + super.onActivityResult(requestCode, resultCode, data) + } + + private fun requestFileOp(requestType: Int) { + if (Utils.canAccessFiles(this@MainActivity)) { + // If the user is going to save the file, we don't want to auto-save it for them + shouldAutoSave = false + val intent = Intent(this@MainActivity, ExplorerActivity::class.java) + intent.putExtra(Constants.EXTRA_REQUEST_CODE, requestType) + intent.putExtra(Constants.EXTRA_FILE, presenter!!.file) + startActivityForResult( + intent, + requestType + ) + } else if (Build.VERSION.SDK_INT >= 23) { + requestPermissions( + arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), + requestType + ) + } + } + + override fun onResume() { + super.onResume() + title = presenter!!.fileName + shouldAutoSave = true + } + + private inner class NewFileHandler : MarkdownPresenter.MarkdownSavedListener { + override fun saveComplete(success: Boolean) { + if (success) { + val newFile = Utils.getDefaultFileName(this@MainActivity) + presenter!!.newFile(newFile) + } else { + Toast.makeText( + this@MainActivity, + R.string.file_save_error, + Toast.LENGTH_SHORT + ).show() + } + } + } +} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.java deleted file mode 100644 index 1c183b7..0000000 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.wbrawner.simplemarkdown.view.activity; - -import android.content.Intent; -import android.os.Bundle; -import android.view.MenuItem; -import android.webkit.WebView; - -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; - -import com.wbrawner.simplemarkdown.R; - -import butterknife.BindView; -import butterknife.ButterKnife; - -public class MarkdownInfoActivity extends AppCompatActivity { - public static String FORMAT_CSS = ""; - - @BindView(R.id.info_webview) - WebView infoWebview; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_markdown_info); - ButterKnife.bind(this); - ActionBar supportActionBar = getSupportActionBar(); - if (supportActionBar != null) { - supportActionBar.setDisplayHomeAsUpEnabled(true); - } - Intent intent = getIntent(); - if (intent == null || !intent.hasExtra("title") || !intent.hasExtra("html")) { - finish(); - return; - } - setTitle(intent.getStringExtra("title")); - infoWebview.loadDataWithBaseURL( - null, - String.format(FORMAT_CSS, - getString(R.string.pref_custom_css_default) - ) + intent.getStringExtra("html"), - "text/html", - "UTF-8", - null - ); - } - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } - return super.onOptionsItemSelected(item); - } -} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.kt new file mode 100644 index 0000000..2842a7c --- /dev/null +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MarkdownInfoActivity.kt @@ -0,0 +1,45 @@ +package com.wbrawner.simplemarkdown.view.activity + +import android.os.Bundle +import android.view.MenuItem +import androidx.appcompat.app.AppCompatActivity +import com.wbrawner.simplemarkdown.R +import kotlinx.android.synthetic.main.activity_markdown_info.* + +class MarkdownInfoActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_markdown_info) + val supportActionBar = supportActionBar + supportActionBar?.setDisplayHomeAsUpEnabled(true) + val intent = intent + if (intent == null || !intent.hasExtra("title") || !intent.hasExtra("html")) { + finish() + return + } + title = intent.getStringExtra("title") + infoWebview.loadDataWithBaseURL(null, + String.format(FORMAT_CSS, + getString(R.string.pref_custom_css_default) + ) + intent.getStringExtra("html"), + "text/html", + "UTF-8", null + ) + } + + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) { + onBackPressed() + return true + } + return super.onOptionsItemSelected(item) + } + + companion object { + var FORMAT_CSS = "" + } +} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.java deleted file mode 100644 index ca83ae2..0000000 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.wbrawner.simplemarkdown.view.fragment; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.ScrollView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import com.jakewharton.rxbinding2.widget.RxTextView; -import com.wbrawner.simplemarkdown.MarkdownApplication; -import com.wbrawner.simplemarkdown.R; -import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter; -import com.wbrawner.simplemarkdown.utility.MarkdownObserver; -import com.wbrawner.simplemarkdown.utility.Utils; -import com.wbrawner.simplemarkdown.view.MarkdownEditView; - -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.Unbinder; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; - -public class EditFragment extends Fragment implements MarkdownEditView { - @Inject - MarkdownPresenter presenter; - @BindView(R.id.markdown_edit) - EditText markdownEditor; - @BindView(R.id.markdown_edit_container) - ScrollView markdownEditorScroller; - - private Unbinder unbinder; - private int lastScrollEvent = -1; - - public EditFragment() { - // Required empty public constructor - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_edit, container, false); - unbinder = ButterKnife.bind(this, view); - Activity activity = getActivity(); - if (activity != null) { - ((MarkdownApplication) activity.getApplication()).getComponent().inject(this); - } - Observable obs = RxTextView.textChanges(markdownEditor) - .debounce(50, TimeUnit.MILLISECONDS) - .map(CharSequence::toString) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()); - obs.subscribe(new MarkdownObserver(presenter, obs)); - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - presenter.setEditView(EditFragment.this); - presenter.loadMarkdown(); - //noinspection AndroidLintClickableViewAccessibility - markdownEditorScroller.setOnTouchListener((v, event) -> { - // The focus should only be set if this was a click, and not a scroll - if (lastScrollEvent == MotionEvent.ACTION_DOWN && event.getAction() == MotionEvent.ACTION_UP) { - if (getActivity() == null) { - return false; - } - InputMethodManager imm = (InputMethodManager) getActivity() - .getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm == null) { - return false; - } - imm.showSoftInput(markdownEditor, InputMethodManager.SHOW_IMPLICIT); - markdownEditor.requestFocus(); - } - lastScrollEvent = event.getAction(); - return false; - }); - } - - @Override - public void onResume() { - super.onResume(); - presenter.setEditView(this); - setMarkdown(presenter.getMarkdown()); - } - - @Override - public void onPause() { - super.onPause(); - presenter.setEditView(null); - } - - @Override - public String getMarkdown() { - return markdownEditor.getText().toString(); - } - - @Override - public void setMarkdown(String markdown) { - markdownEditor.setText(markdown); - } - - @Override - public void setTitle(String title) { - Activity activity = getActivity(); - if (activity != null) { - activity.setTitle(title); - } - } - - @Override - public void onFileSaved(boolean success) { - String location = Utils.getDocsPath(getActivity()) + presenter.getFileName(); - String message; - if (success) { - message = getString(R.string.file_saved, location); - } else { - message = getString(R.string.file_save_error); - } - Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); - } - - @Override - public void onFileLoaded(boolean success) { - // TODO: Investigate why this fires off so often -// int message = success ? R.string.file_loaded : R.string.file_load_error; -// Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - unbinder.unbind(); - } -} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.kt new file mode 100644 index 0000000..5fd3426 --- /dev/null +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/EditFragment.kt @@ -0,0 +1,120 @@ +package com.wbrawner.simplemarkdown.view.fragment + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager +import android.widget.EditText +import android.widget.ScrollView +import android.widget.Toast +import androidx.fragment.app.Fragment +import com.jakewharton.rxbinding2.widget.RxTextView +import com.wbrawner.simplemarkdown.MarkdownApplication +import com.wbrawner.simplemarkdown.R +import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter +import com.wbrawner.simplemarkdown.utility.MarkdownObserver +import com.wbrawner.simplemarkdown.utility.Utils +import com.wbrawner.simplemarkdown.view.MarkdownEditView +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +class EditFragment : Fragment(), MarkdownEditView { + @Inject + lateinit var presenter: MarkdownPresenter + private var markdownEditor: EditText? = null + private var markdownEditorScroller: ScrollView? = null + + private var lastScrollEvent = -1 + + @SuppressLint("ClickableViewAccessibility") + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + // Inflate the layout for this fragment + val view = inflater.inflate(R.layout.fragment_edit, container, false) + markdownEditor = view.findViewById(R.id.markdown_edit) + markdownEditorScroller = view.findViewById(R.id.markdown_edit_container) + val activity = activity + if (activity != null) { + (activity.application as MarkdownApplication).component.inject(this) + } + val obs = RxTextView.textChanges(markdownEditor!!) + .debounce(50, TimeUnit.MILLISECONDS) + .map { it.toString() } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + obs.subscribe(MarkdownObserver(presenter, obs)) + return view + } + + @SuppressLint("ClickableViewAccessibility") + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + presenter!!.setEditView(this@EditFragment) + presenter!!.loadMarkdown() + + markdownEditorScroller!!.setOnTouchListener { v, event -> + // The focus should only be set if this was a click, and not a scroll + if (lastScrollEvent == MotionEvent.ACTION_DOWN && event.action == MotionEvent.ACTION_UP) { + if (activity == null) { + return@setOnTouchListener false + } + val imm = activity + ?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager + ?: return@setOnTouchListener false + imm.showSoftInput(markdownEditor, InputMethodManager.SHOW_IMPLICIT) + markdownEditor!!.requestFocus() + } + lastScrollEvent = event.action + false + } + } + + override fun onResume() { + super.onResume() + presenter!!.setEditView(this) + markdown = presenter!!.markdown + } + + override fun onPause() { + super.onPause() + presenter!!.setEditView(null) + } + + override fun getMarkdown(): String { + return markdownEditor!!.text.toString() + } + + override fun setMarkdown(markdown: String) { + markdownEditor!!.setText(markdown) + } + + override fun setTitle(title: String) { + val activity = activity + if (activity != null) { + activity.title = title + } + } + + override fun onFileSaved(success: Boolean) { + val location = Utils.getDocsPath(activity) + presenter!!.fileName + val message: String + message = if (success) { + getString(R.string.file_saved, location) + } else { + getString(R.string.file_save_error) + } + Toast.makeText(activity, message, Toast.LENGTH_SHORT).show() + } + + override fun onFileLoaded(success: Boolean) { + // TODO: Investigate why this fires off so often + // int message = success ? R.string.file_loaded : R.string.file_load_error; + // Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); + } +}// Required empty public constructor diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.java deleted file mode 100644 index e916eda..0000000 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.wbrawner.simplemarkdown.view.fragment; - -import android.app.Activity; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.WebView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import com.wbrawner.simplemarkdown.BuildConfig; -import com.wbrawner.simplemarkdown.MarkdownApplication; -import com.wbrawner.simplemarkdown.R; -import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter; -import com.wbrawner.simplemarkdown.view.MarkdownPreviewView; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.Unbinder; - -public class PreviewFragment extends Fragment implements MarkdownPreviewView { - private static final String TAG = PreviewFragment.class.getSimpleName(); - public static String FORMAT_CSS = ""; - @Inject - MarkdownPresenter presenter; - @BindView(R.id.markdown_view) - WebView markdownPreview; - private Unbinder unbinder; - private SharedPreferences sharedPreferences; - - public PreviewFragment() { - // Required empty constructor - } - - @Override - public View onCreateView( - @NonNull LayoutInflater inflater, - ViewGroup container, - Bundle savedInstanceState - ) { - sharedPreferences = PreferenceManager.getDefaultSharedPreferences(container.getContext()); - // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_preview, container, false); - unbinder = ButterKnife.bind(this, view); - Activity activity = getActivity(); - if (activity != null) { - ((MarkdownApplication) activity.getApplication()).getComponent().inject(this); - } - if (BuildConfig.DEBUG) - WebView.setWebContentsDebuggingEnabled(true); - return view; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - } - - @Override - public void updatePreview(String html) { - if (markdownPreview == null) { - return; - } - markdownPreview.post(() -> { - if (markdownPreview == null) { - return; - } - - String style = String.format( - FORMAT_CSS, - sharedPreferences.getString( - getString(R.string.pref_custom_css), - "" - ) - ); - - markdownPreview.loadDataWithBaseURL( - null, - style + html, - "text/html", - "UTF-8", - null - ); - }); - } - - @Override - public void onResume() { - super.onResume(); - presenter.setPreviewView(this); - presenter.onMarkdownEdited(); - } - - @Override - public void onDestroyView() { - if (markdownPreview != null) { - ((ViewGroup) markdownPreview.getParent()).removeView(markdownPreview); - markdownPreview.destroy(); - } - unbinder.unbind(); - super.onDestroyView(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - presenter.setPreviewView(null); - } -} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.kt new file mode 100644 index 0000000..c1b77d0 --- /dev/null +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/PreviewFragment.kt @@ -0,0 +1,98 @@ +package com.wbrawner.simplemarkdown.view.fragment + +import android.content.SharedPreferences +import android.os.Bundle +import android.preference.PreferenceManager +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.webkit.WebView +import androidx.fragment.app.Fragment +import com.wbrawner.simplemarkdown.BuildConfig +import com.wbrawner.simplemarkdown.MarkdownApplication +import com.wbrawner.simplemarkdown.R +import com.wbrawner.simplemarkdown.presentation.MarkdownPresenter +import com.wbrawner.simplemarkdown.view.MarkdownPreviewView +import javax.inject.Inject + +class PreviewFragment : Fragment(), MarkdownPreviewView { + @Inject + lateinit var presenter: MarkdownPresenter + private var markdownPreview: WebView? = null + private var sharedPreferences: SharedPreferences? = null + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(container!!.context) + // Inflate the layout for this fragment + val view = inflater.inflate(R.layout.fragment_preview, container, false) + markdownPreview = view.findViewById(R.id.markdown_view) + val activity = activity + if (activity != null) { + (activity.application as MarkdownApplication).component.inject(this) + } + if (BuildConfig.DEBUG) + WebView.setWebContentsDebuggingEnabled(true) + return view + } + + override fun updatePreview(html: String) { + if (markdownPreview == null) { + return + } + markdownPreview!!.post { + if (markdownPreview == null) { + return@post + } + + val css: String? = if (!BuildConfig.ENABLE_CUSTOM_CSS) { + sharedPreferences!!.getString( + getString(R.string.pref_custom_css_default), + "" + ) + } else { + sharedPreferences!!.getString( + getString(R.string.pref_custom_css), + getString(R.string.pref_custom_css_default) + ) + } + + val style = String.format(FORMAT_CSS, css) + + markdownPreview!!.loadDataWithBaseURL(null, + style + html, + "text/html", + "UTF-8", null + ) + } + } + + override fun onResume() { + super.onResume() + presenter!!.setPreviewView(this) + presenter!!.onMarkdownEdited() + } + + override fun onDestroyView() { + markdownPreview?.let { + (it.parent as ViewGroup).removeView(it) + it.destroy() + } + super.onDestroyView() + } + + override fun onDestroy() { + super.onDestroy() + presenter!!.setPreviewView(null) + } + + companion object { + private val TAG = PreviewFragment::class.java.simpleName + var FORMAT_CSS = "" + } +} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.java index 347aecb..c6e97f0 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.java +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/fragment/SettingsFragment.java @@ -14,6 +14,7 @@ import android.view.ViewGroup; import androidx.annotation.Nullable; +import com.wbrawner.simplemarkdown.BuildConfig; import com.wbrawner.simplemarkdown.R; import com.wbrawner.simplemarkdown.utility.Constants; import com.wbrawner.simplemarkdown.utility.Utils; @@ -36,6 +37,9 @@ public class SettingsFragment extends PreferenceFragment sharedPreferences, findPreference(getString(R.string.key_default_view)) ); + if (!BuildConfig.ENABLE_CUSTOM_CSS) { + getPreferenceScreen().removePreference(findPreference(getString(R.string.pref_custom_css))); + } Preference defaultRoot = findPreference(Constants.KEY_DOCS_PATH); defaultRoot.setSummary(Utils.getDocsPath(getActivity())); defaultRoot.setOnPreferenceClickListener((preference) -> { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index d190acc..7f1d0c2 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -5,19 +5,19 @@ android:layout_height="match_parent"> diff --git a/app/src/main/res/layout/activity_markdown_info.xml b/app/src/main/res/layout/activity_markdown_info.xml index a585a6f..d06d64c 100644 --- a/app/src/main/res/layout/activity_markdown_info.xml +++ b/app/src/main/res/layout/activity_markdown_info.xml @@ -8,5 +8,5 @@ + android:id="@+id/infoWebview" /> diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index b02fb14..7a44dc4 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -21,10 +21,10 @@ android:summaryOff="@string/pref_error_reports_off" android:summaryOn="@string/pref_error_reports_on" android:title="@string/pref_title_error_reports" /> - - - - - +