From eb19a04779a6eb0a66034e2e19e321117dc5f7df Mon Sep 17 00:00:00 2001 From: kosharskiy Date: Thu, 14 Jan 2021 00:49:41 +0200 Subject: [PATCH 1/5] converted AddServerFragment to kotlin and refactored it --- app/build.gradle | 32 +++- .../activity/ServerAddressBookActivity.java | 45 +---- .../peertube/fragment/AddServerFragment.java | 180 ------------------ .../peertube/fragment/AddServerFragment.kt | 142 ++++++++++++++ .../schueller/peertube/utils/Extensions.kt | 24 +++ .../layout/content_server_address_book.xml | 4 +- .../main/res/layout/fragment_add_server.xml | 15 +- build.gradle | 3 + 8 files changed, 218 insertions(+), 227 deletions(-) delete mode 100644 app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.java create mode 100644 app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.kt create mode 100644 app/src/main/java/net/schueller/peertube/utils/Extensions.kt diff --git a/app/build.gradle b/app/build.gradle index 7948ec1..ab33d68 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,9 @@ -apply plugin: 'com.android.application' +plugins { + id 'com.android.application' + id 'kotlin-android' + id 'kotlin-parcelize' + id 'kotlin-kapt' +} ext.readProperty = { paramName -> readPropertyWithDefault(paramName, null) } ext.readPropertyWithDefault = { paramName, defaultValue -> @@ -80,20 +85,29 @@ android { applicationVariants.all { variant -> variant.resValue "string", "versionName", variant.versionName } + + buildFeatures{ + viewBinding = true + } + } def room_version = "2.2.6" def lifecycleVersion = '2.2.0' def exoplayer = '2.12.3' +def fragment_version = "1.2.5" dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + // Layouts and design implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" + implementation "androidx.fragment:fragment-ktx:$fragment_version" implementation 'de.hdodenhof:circleimageview:3.0.0' @@ -135,17 +149,27 @@ dependencies { // database lib implementation "androidx.room:room-runtime:$room_version" implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' - annotationProcessor "androidx.room:room-compiler:$room_version" + kapt "androidx.room:room-compiler:$room_version" androidTestImplementation "androidx.room:room-testing:$room_version" // Lifecycle components implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion" - annotationProcessor "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" + kapt "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion" + implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" - implementation 'androidx.preference:preference:1.1.1' + + implementation 'androidx.preference:preference-ktx:1.1.1' // testing testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' } + +tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { + kotlinOptions { + jvmTarget = "1.8" + } +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.java b/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.java index f7e0514..2e637f7 100644 --- a/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.java +++ b/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.java @@ -17,13 +17,8 @@ package net.schueller.peertube.activity; import android.app.AlertDialog; -import android.net.Uri; import android.os.Bundle; import android.util.Log; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.View; -import android.widget.EditText; import com.google.android.material.floatingactionbutton.FloatingActionButton; @@ -46,7 +41,7 @@ import net.schueller.peertube.fragment.AddServerFragment; import java.util.Objects; -public class ServerAddressBookActivity extends CommonActivity implements AddServerFragment.OnFragmentInteractionListener { +public class ServerAddressBookActivity extends CommonActivity { private String TAG = "ServerAddressBookActivity"; public static final String EXTRA_REPLY = "net.schueller.peertube.room.REPLY"; @@ -96,10 +91,6 @@ public class ServerAddressBookActivity extends CommonActivity implements AddServ } - @Override - public void onFragmentInteraction(Uri uri) { - - } @Override public void onPointerCaptureChanged(boolean hasCapture) { @@ -112,7 +103,6 @@ public class ServerAddressBookActivity extends CommonActivity implements AddServ RecyclerView recyclerView = findViewById(R.id.server_list_recyclerview); final ServerListAdapter adapter = new ServerListAdapter(this); recyclerView.setAdapter(adapter); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); // Delete items on swipe ItemTouchHelper helper = new ItemTouchHelper( @@ -153,32 +143,17 @@ public class ServerAddressBookActivity extends CommonActivity implements AddServ // Update the cached copy of the words in the adapter. - mServerViewModel.getAllServers().observe(this, adapter::setServers); + mServerViewModel.getAllServers().observe(this, servers -> { + adapter.setServers(servers); - } + if (addServerFragment != null) { + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + fragmentTransaction.remove(addServerFragment); + fragmentTransaction.commit(); - public void addServer(View view) - { - Log.d(TAG, "addServer"); - - EditText serverLabel = view.findViewById(R.id.serverLabel); - EditText serverUrl = view.findViewById(R.id.serverUrl); - EditText serverUsername = view.findViewById(R.id.serverUsername); - EditText serverPassword = view.findViewById(R.id.serverPassword); - - Server server = new Server(serverLabel.getText().toString()); - - server.setServerHost(serverUrl.getText().toString()); - server.setUsername(serverUsername.getText().toString()); - server.setPassword(serverPassword.getText().toString()); - - mServerViewModel.insert(server); - - FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - fragmentTransaction.remove(addServerFragment); - fragmentTransaction.commit(); - - floatingActionButton.show(); + floatingActionButton.show(); + } + }); } diff --git a/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.java b/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.java deleted file mode 100644 index bc2b3fd..0000000 --- a/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2020 Stefan Schüller - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package net.schueller.peertube.fragment; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import android.text.TextUtils; -import android.util.Log; -import android.util.Patterns; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; - -import net.schueller.peertube.R; -import net.schueller.peertube.activity.SearchServerActivity; -import net.schueller.peertube.activity.ServerAddressBookActivity; -import net.schueller.peertube.helper.APIUrlHelper; - -import java.util.Objects; - -import static android.app.Activity.RESULT_OK; - - -public class AddServerFragment extends Fragment { - - public static final String TAG = "AddServerFragment"; - public static final Integer PICK_SERVER = 1; - - private OnFragmentInteractionListener mListener; - - private View mView; - - public AddServerFragment() { - // Required empty public constructor - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - Log.d(TAG, "onCreateView"); - // Inflate the layout for this fragment - - mView = inflater.inflate(R.layout.fragment_add_server, container, false); - - // bind button click - Button addServerButton = mView.findViewById(R.id.addServerButton); - addServerButton.setOnClickListener(view -> { - - Activity act = getActivity(); - - boolean formValid = true; - - // close keyboard - try { - assert act != null; - InputMethodManager inputManager = (InputMethodManager) - act.getSystemService(Context.INPUT_METHOD_SERVICE); - - inputManager.hideSoftInputFromWindow(Objects.requireNonNull(act.getCurrentFocus()).getWindowToken(), - InputMethodManager.HIDE_NOT_ALWAYS); - } catch (Exception e) { - - } - - EditText selectedLabel = mView.findViewById(R.id.serverLabel); - if ( TextUtils.isEmpty(selectedLabel.getText())){ - selectedLabel.setError( act.getString(R.string.server_book_label_is_required )); - Toast.makeText(act, R.string.invalid_url, Toast.LENGTH_LONG).show(); - formValid = false; - } - - // validate url - EditText selectedUrl = mView.findViewById(R.id.serverUrl); - String serverUrl = APIUrlHelper.cleanServerUrl(selectedUrl.getText().toString()); - selectedUrl.setText(serverUrl); - - if (!Patterns.WEB_URL.matcher(serverUrl).matches()) { - selectedUrl.setError( act.getString(R.string.server_book_valid_url_is_required ) ); - Toast.makeText(act, R.string.invalid_url, Toast.LENGTH_LONG).show(); - formValid = false; - } - - if (formValid) { - if (act instanceof ServerAddressBookActivity) { - ((ServerAddressBookActivity) act).addServer(mView); - - } - } - - }); - -// Button testServerButton = mView.findViewById(R.id.testServerButton); -// testServerButton.setOnClickListener(view -> { -// Activity act = getActivity(); -// if (act instanceof ServerAddressBookActivity) { -// ((ServerAddressBookActivity) act).testServer(); -// } -// }); - - Button pickServerUrl = mView.findViewById(R.id.pickServerUrl); - pickServerUrl.setOnClickListener(view -> { - Intent intentServer = new Intent(getActivity(), SearchServerActivity.class); - this.startActivityForResult(intentServer, PICK_SERVER); - }); - - return mView; - } - - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == PICK_SERVER) { - if(resultCode == RESULT_OK) { - - String serverUrlTest = data.getStringExtra("serverUrl"); - //Log.d(TAG, "serverUrl " + serverUrlTest); - EditText serverUrl = mView.findViewById(R.id.serverUrl); - serverUrl.setText(serverUrlTest); - - EditText serverLabel = mView.findViewById(R.id.serverLabel); - if ("".equals(serverLabel.getText().toString())) { - serverLabel.setText(data.getStringExtra("serverName")); - } - - } - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - if (context instanceof OnFragmentInteractionListener) { - mListener = (OnFragmentInteractionListener) context; - } else { - throw new RuntimeException(context.toString() - + " must implement OnFragmentInteractionListener"); - } - } - - @Override - public void onDetach() { - super.onDetach(); - mListener = null; - } - - public interface OnFragmentInteractionListener { - // TODO: Update argument type and name - void onFragmentInteraction(Uri uri); - } -} diff --git a/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.kt b/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.kt new file mode 100644 index 0000000..d6088a1 --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.kt @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2020 Stefan Schüller + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package net.schueller.peertube.fragment + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.util.Patterns +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import net.schueller.peertube.R +import net.schueller.peertube.activity.SearchServerActivity +import net.schueller.peertube.database.Server +import net.schueller.peertube.database.ServerViewModel +import net.schueller.peertube.databinding.FragmentAddServerBinding +import net.schueller.peertube.helper.APIUrlHelper +import net.schueller.peertube.utils.hideKeyboard + +class AddServerFragment : Fragment() { + + + private lateinit var mBinding: FragmentAddServerBinding + + private val mServerViewModel: ServerViewModel by activityViewModels() + + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + Log.d(TAG, "onCreateView") + // Inflate the layout for this fragment + mBinding = FragmentAddServerBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + // bind button click + + mBinding.addServerButton.setOnClickListener { view: View? -> + var formValid = true + + hideKeyboard() + + + if (mBinding.serverLabel.text.toString().isNullOrBlank()) { + mBinding.serverLabel.error = getString(R.string.server_book_label_is_required) + Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_LONG).show() + formValid = false + } + + // validate url + + mBinding.serverUrl.apply { + APIUrlHelper.cleanServerUrl(text.toString())?.let { + + setText(it) + + if (!Patterns.WEB_URL.matcher(it).matches()) { + error = getString(R.string.server_book_valid_url_is_required) + Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_LONG).show() + formValid = false + } + } + } + + + if (formValid) { + mBinding.apply { + val server = Server(serverLabel.text.toString()) + + server.serverHost = serverUrl.text.toString() + server.username = serverUsername.text.toString() + server.password = serverPassword.text.toString() + + mServerViewModel.insert(server) + } + } + } + +// Button testServerButton = mView.findViewById(R.id.testServerButton); +// testServerButton.setOnClickListener(view -> { +// Activity act = getActivity(); +// if (act instanceof ServerAddressBookActivity) { +// ((ServerAddressBookActivity) act).testServer(); +// } +// }); + + + mBinding.pickServerUrl.setOnClickListener { + val intentServer = Intent(activity, SearchServerActivity::class.java) + this.startActivityForResult(intentServer, PICK_SERVER) + } + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + + if (requestCode != PICK_SERVER) { + return + } + + if (resultCode != Activity.RESULT_OK) { + return + } + + val serverUrlTest = data?.getStringExtra("serverUrl") + //Log.d(TAG, "serverUrl " + serverUrlTest); + + mBinding.serverUrl.setText(serverUrlTest) + + mBinding.serverLabel.apply { + if (text.toString().isBlank()) { + setText(data?.getStringExtra("serverName")) + } + } + + } + + companion object { + const val TAG = "AddServerFragment" + const val PICK_SERVER = 1 + } +} \ No newline at end of file diff --git a/app/src/main/java/net/schueller/peertube/utils/Extensions.kt b/app/src/main/java/net/schueller/peertube/utils/Extensions.kt new file mode 100644 index 0000000..14bf8ba --- /dev/null +++ b/app/src/main/java/net/schueller/peertube/utils/Extensions.kt @@ -0,0 +1,24 @@ +package net.schueller.peertube.utils + +import android.content.Context +import android.view.inputmethod.InputMethodManager +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment + +fun Fragment.hideKeyboard(): Boolean { + activity?.currentFocus?.let { + val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(it.windowToken, 0) + return true + } + return false +} + +fun AppCompatActivity.hideKeyboard(): Boolean { + currentFocus?.let { + val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(it.windowToken, 0) + return true + } + return false +} diff --git a/app/src/main/res/layout/content_server_address_book.xml b/app/src/main/res/layout/content_server_address_book.xml index cd9daa2..98667eb 100644 --- a/app/src/main/res/layout/content_server_address_book.xml +++ b/app/src/main/res/layout/content_server_address_book.xml @@ -14,7 +14,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/darker_gray" - tools:listitem="@layout/row_server_address_book" /> + tools:listitem="@layout/row_server_address_book" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + /> diff --git a/app/src/main/res/layout/fragment_add_server.xml b/app/src/main/res/layout/fragment_add_server.xml index e55bba1..91e0a6b 100644 --- a/app/src/main/res/layout/fragment_add_server.xml +++ b/app/src/main/res/layout/fragment_add_server.xml @@ -19,28 +19,29 @@ android:hint="@string/server_book_add_label" android:inputType="textPersonName" /> - + android:layout_width="match_parent" + android:orientation="horizontal" + > + />