mirror of
https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
synced 2025-02-11 17:08:43 +01:00
Compare commits
6 Commits
60f07f7707
...
930a425af5
Author | SHA1 | Date | |
---|---|---|---|
|
930a425af5 | ||
|
7168cecbcb | ||
|
7f067023e7 | ||
|
167aecb696 | ||
|
9872e6e806 | ||
|
859e9ab5d6 |
BIN
.assets/IzzyOnDroid.png
Normal file
BIN
.assets/IzzyOnDroid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
.assets/codeberg.png
Normal file
BIN
.assets/codeberg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
28
README.md
28
README.md
@ -6,32 +6,28 @@
|
|||||||
|
|
||||||
A Lemmy client for Android written in Java. It's a fork of the [Infinity for Reddit](https://github.com/Docile-Alligator/Infinity-For-Reddit) project, currenty in early development.
|
A Lemmy client for Android written in Java. It's a fork of the [Infinity for Reddit](https://github.com/Docile-Alligator/Infinity-For-Reddit) project, currenty in early development.
|
||||||
|
|
||||||
<img align="right" src="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/raw/branch/master/fastlane/metadata/android/en-US/images/icon.png" width=200>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
<img src="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/raw/branch/master/fastlane/metadata/android/en-US/images/icon.png" width=256>
|
||||||
|
|
||||||
[![status-badge](https://ci.codeberg.org/api/badges/12474/status.svg)](https://ci.codeberg.org/12474)
|
[![status-badge](https://ci.codeberg.org/api/badges/12474/status.svg)](https://ci.codeberg.org/repos/12474)
|
||||||
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/bazsalanszky)](https://liberapay.com/Bazsalanszky)
|
[![Liberapay patrons](https://img.shields.io/liberapay/patrons/bazsalanszky)](https://liberapay.com/Bazsalanszky)
|
||||||
|
|
||||||
<a href="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues">Report a Bug</a>
|
<a href="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues">Report a Bug</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
<a href="https://apt.izzysoft.de/fdroid/index/apk/eu.toldi.infinityforlemmy">
|
||||||
|
<img src="./.assets/IzzyOnDroid.png" height="80">
|
||||||
|
</a>
|
||||||
|
<a href="https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/releases/">
|
||||||
|
<img src="./.assets/codeberg.png" height="80">
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Action Items for Infinity for Lemmy
|
## Action Items for Infinity for Lemmy
|
||||||
@ -53,9 +49,6 @@ Infinity for Lemmy is currently in the early stages of development. Expect many
|
|||||||
- [ ] Account editing function
|
- [ ] Account editing function
|
||||||
- [ ] Multi community view?
|
- [ ] Multi community view?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
First off, thanks for taking the time to contribute! Contributions are what makes the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
First off, thanks for taking the time to contribute! Contributions are what makes the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
|
||||||
@ -75,16 +68,12 @@ Don't forget to give the project a star! Thanks again!
|
|||||||
|
|
||||||
You can alos help Infinity for Lemmy by translating it to your native langugage! Translations are done via [Weblate](https://hosted.weblate.org/projects/lemminfinity/codeberg/)!
|
You can alos help Infinity for Lemmy by translating it to your native langugage! Translations are done via [Weblate](https://hosted.weblate.org/projects/lemminfinity/codeberg/)!
|
||||||
|
|
||||||
|
|
||||||
[![Translation](https://hosted.weblate.org/widgets/lemminfinity/-/codeberg/multi-auto.svg)](https://hosted.weblate.org/engage/lemminfinity/)
|
[![Translation](https://hosted.weblate.org/widgets/lemminfinity/-/codeberg/multi-auto.svg)](https://hosted.weblate.org/engage/lemminfinity/)
|
||||||
|
|
||||||
|
|
||||||
### Reporting bugs
|
### Reporting bugs
|
||||||
|
|
||||||
You can also contribute by [reporting bugs](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues)
|
You can also contribute by [reporting bugs](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy/issues)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p align="right">(<a href="#top">back to top</a>)</p>
|
<p align="right">(<a href="#top">back to top</a>)</p>
|
||||||
|
|
||||||
## License
|
## License
|
||||||
@ -97,7 +86,6 @@ Distributed under the AGPL-3.0 License. See <a href="https://codeberg.org/Bazsal
|
|||||||
|
|
||||||
[@bazsalanszky@lemmy.toldi.eu](https://lemmy.toldi.eu/u/bazsalanszky) - (Owner)
|
[@bazsalanszky@lemmy.toldi.eu](https://lemmy.toldi.eu/u/bazsalanszky) - (Owner)
|
||||||
|
|
||||||
|
|
||||||
Project Link: [https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy)
|
Project Link: [https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy](https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy)
|
||||||
|
|
||||||
<p align="right">(<a href="#top">back to top</a>)</p>
|
<p align="right">(<a href="#top">back to top</a>)</p>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
|
id 'org.jetbrains.kotlin.android'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@ -34,6 +35,11 @@ android {
|
|||||||
versionNameSuffix ' (DEBUG)'
|
versionNameSuffix ' (DEBUG)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/kotlin'
|
||||||
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_11
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_11
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
|
@ -27,6 +27,8 @@ import org.json.JSONException;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -146,11 +148,12 @@ public class LoginActivity extends BaseActivity {
|
|||||||
progressBar.setVisibility(ProgressBar.VISIBLE);
|
progressBar.setVisibility(ProgressBar.VISIBLE);
|
||||||
String username = username_input.getText().toString().trim();
|
String username = username_input.getText().toString().trim();
|
||||||
String instance = correctURL(instance_input.getText().toString().trim());
|
String instance = correctURL(instance_input.getText().toString().trim());
|
||||||
if (!Patterns.WEB_URL.matcher(instance).matches()) {
|
try {
|
||||||
instance_input.setError("Invalid instance URL");
|
URL urlObj = new URL(instance);
|
||||||
|
instance = urlObj.getProtocol() + "://" + urlObj.getHost() + "/";
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
instance_input.setError("Invalid URL");
|
||||||
Toast.makeText(LoginActivity.this, "Invalid instance URL", Toast.LENGTH_SHORT).show();
|
Toast.makeText(LoginActivity.this, "Invalid instance URL", Toast.LENGTH_SHORT).show();
|
||||||
loginButton.setEnabled(true);
|
|
||||||
progressBar.setVisibility(ProgressBar.GONE);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log.i("LoginActivity", "Instance: " + instance);
|
Log.i("LoginActivity", "Instance: " + instance);
|
||||||
@ -158,6 +161,7 @@ public class LoginActivity extends BaseActivity {
|
|||||||
mRetrofit.setBaseURL(instance);
|
mRetrofit.setBaseURL(instance);
|
||||||
LemmyAPI api = mRetrofit.getRetrofit().create(LemmyAPI.class);
|
LemmyAPI api = mRetrofit.getRetrofit().create(LemmyAPI.class);
|
||||||
Call<String> accessTokenCall = api.userLogin(accountLoginDTO);
|
Call<String> accessTokenCall = api.userLogin(accountLoginDTO);
|
||||||
|
String finalInstance = instance;
|
||||||
accessTokenCall.enqueue(new Callback<String>() {
|
accessTokenCall.enqueue(new Callback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
|
public void onResponse(@NonNull Call<String> call, @NonNull Response<String> response) {
|
||||||
@ -185,7 +189,7 @@ public class LoginActivity extends BaseActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) {
|
public void onFetchSiteInfoSuccess(SiteInfo siteInfo) {
|
||||||
boolean canDownvote = siteInfo.isEnable_downvotes();
|
boolean canDownvote = siteInfo.isEnable_downvotes();
|
||||||
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken, profileImageUrl, bannerImageUrl, authCode,instance,canDownvote, mRedditDataRoomDatabase.accountDao(),
|
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken, profileImageUrl, bannerImageUrl, authCode, finalInstance,canDownvote, mRedditDataRoomDatabase.accountDao(),
|
||||||
() -> {
|
() -> {
|
||||||
Intent resultIntent = new Intent();
|
Intent resultIntent = new Intent();
|
||||||
setResult(Activity.RESULT_OK, resultIntent);
|
setResult(Activity.RESULT_OK, resultIntent);
|
||||||
@ -196,7 +200,7 @@ public class LoginActivity extends BaseActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchSiteInfoFailed() {
|
public void onFetchSiteInfoFailed() {
|
||||||
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken, profileImageUrl, bannerImageUrl, authCode,instance,true, mRedditDataRoomDatabase.accountDao(),
|
ParseAndInsertNewAccount.parseAndInsertNewAccount(mExecutor, new Handler(), name,display_name, accessToken, profileImageUrl, bannerImageUrl, authCode, finalInstance,true, mRedditDataRoomDatabase.accountDao(),
|
||||||
() -> {
|
() -> {
|
||||||
Intent resultIntent = new Intent();
|
Intent resultIntent = new Intent();
|
||||||
setResult(Activity.RESULT_OK, resultIntent);
|
setResult(Activity.RESULT_OK, resultIntent);
|
||||||
@ -208,7 +212,7 @@ public class LoginActivity extends BaseActivity {
|
|||||||
mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, accessToken)
|
mCurrentAccountSharedPreferences.edit().putString(SharedPreferencesUtils.ACCESS_TOKEN, accessToken)
|
||||||
.putString(SharedPreferencesUtils.ACCOUNT_NAME, display_name)
|
.putString(SharedPreferencesUtils.ACCOUNT_NAME, display_name)
|
||||||
.putString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, name)
|
.putString(SharedPreferencesUtils.ACCOUNT_QUALIFIED_NAME, name)
|
||||||
.putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,instance)
|
.putString(SharedPreferencesUtils.ACCOUNT_INSTANCE,finalInstance)
|
||||||
.putString(SharedPreferencesUtils.ACCOUNT_IMAGE_URL, profileImageUrl).apply();
|
.putString(SharedPreferencesUtils.ACCOUNT_IMAGE_URL, profileImageUrl).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,9 +690,8 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp
|
|||||||
qualifiedName = LemmyUtils.actorID2FullName(communityData.getActorId());
|
qualifiedName = LemmyUtils.actorID2FullName(communityData.getActorId());
|
||||||
if (communityName == null) {
|
if (communityName == null) {
|
||||||
communityName = communityData.getTitle();
|
communityName = communityData.getTitle();
|
||||||
|
|
||||||
setupVisibleElements();
|
|
||||||
}
|
}
|
||||||
|
setupVisibleElements();
|
||||||
communityId = communityData.getId();
|
communityId = communityData.getId();
|
||||||
setupSubscribeChip();
|
setupSubscribeChip();
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ import eu.toldi.infinityforlemmy.markdown.MarkdownUtils;
|
|||||||
import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData;
|
import eu.toldi.infinityforlemmy.subreddit.FetchSubredditData;
|
||||||
import eu.toldi.infinityforlemmy.subreddit.SubredditData;
|
import eu.toldi.infinityforlemmy.subreddit.SubredditData;
|
||||||
import eu.toldi.infinityforlemmy.subreddit.SubredditViewModel;
|
import eu.toldi.infinityforlemmy.subreddit.SubredditViewModel;
|
||||||
|
import eu.toldi.infinityforlemmy.utils.LemmyUtils;
|
||||||
import io.noties.markwon.AbstractMarkwonPlugin;
|
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||||
import io.noties.markwon.Markwon;
|
import io.noties.markwon.Markwon;
|
||||||
import io.noties.markwon.MarkwonConfiguration;
|
import io.noties.markwon.MarkwonConfiguration;
|
||||||
@ -97,7 +98,7 @@ public class SidebarFragment extends Fragment {
|
|||||||
mAccessToken = getArguments().getString(EXTRA_ACCESS_TOKEN);
|
mAccessToken = getArguments().getString(EXTRA_ACCESS_TOKEN);
|
||||||
subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME);
|
subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME);
|
||||||
communityQualifiedName = getArguments().getString(EXTRA_COMMUNITY_QUALIFIED_NAME);
|
communityQualifiedName = getArguments().getString(EXTRA_COMMUNITY_QUALIFIED_NAME);
|
||||||
if (subredditName == null) {
|
if (communityQualifiedName == null) {
|
||||||
Toast.makeText(activity, R.string.error_getting_community_name, Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, R.string.error_getting_community_name, Toast.LENGTH_SHORT).show();
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
@ -166,7 +167,7 @@ public class SidebarFragment extends Fragment {
|
|||||||
});
|
});
|
||||||
|
|
||||||
mSubredditViewModel = new ViewModelProvider(activity,
|
mSubredditViewModel = new ViewModelProvider(activity,
|
||||||
new SubredditViewModel.Factory(activity.getApplication(), mRedditDataRoomDatabase, communityQualifiedName))
|
new SubredditViewModel.Factory(activity.getApplication(), mRedditDataRoomDatabase, LemmyUtils.qualifiedCommunityName2ActorId(communityQualifiedName)))
|
||||||
.get(SubredditViewModel.class);
|
.get(SubredditViewModel.class);
|
||||||
mSubredditViewModel.getSubredditLiveData().observe(getViewLifecycleOwner(), subredditData -> {
|
mSubredditViewModel.getSubredditLiveData().observe(getViewLifecycleOwner(), subredditData -> {
|
||||||
if (subredditData != null) {
|
if (subredditData != null) {
|
||||||
|
@ -52,6 +52,7 @@ public class MarkdownUtils {
|
|||||||
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
|
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
|
||||||
.usePlugin(TableEntryPlugin.create(context))
|
.usePlugin(TableEntryPlugin.create(context))
|
||||||
.usePlugin(ClickableGlideImagesPlugin.create(context))
|
.usePlugin(ClickableGlideImagesPlugin.create(context))
|
||||||
|
.usePlugin(new MarkwonLemmyLinkPlugin())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +72,7 @@ public class MarkdownUtils {
|
|||||||
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
|
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS))
|
||||||
.usePlugin(TableEntryPlugin.create(context))
|
.usePlugin(TableEntryPlugin.create(context))
|
||||||
.usePlugin(GlideImagesPlugin.create(context))
|
.usePlugin(GlideImagesPlugin.create(context))
|
||||||
|
.usePlugin(new MarkwonLemmyLinkPlugin())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
package eu.toldi.infinityforlemmy.markdown
|
||||||
|
|
||||||
|
|
||||||
|
import android.text.Spannable
|
||||||
|
import android.text.SpannableStringBuilder
|
||||||
|
import android.text.style.URLSpan
|
||||||
|
import android.text.util.Linkify
|
||||||
|
import eu.toldi.infinityforlemmy.utils.LemmyUtils
|
||||||
|
import io.noties.markwon.*
|
||||||
|
import io.noties.markwon.core.CorePlugin
|
||||||
|
import io.noties.markwon.core.CoreProps
|
||||||
|
import org.commonmark.node.Link
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
// Source : https://github.com/dessalines/jerboa/blob/main/app/src/main/java/com/jerboa/util/markwon/MarkwonLemmyLinkPlugin.kt
|
||||||
|
class MarkwonLemmyLinkPlugin : AbstractMarkwonPlugin() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* pattern that matches all valid communities; intended to be loose
|
||||||
|
*/
|
||||||
|
const val communityPatternFragment: String = """[a-zA-Z0-9_]{3,}"""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pattern to match all valid instances
|
||||||
|
*/
|
||||||
|
const val instancePatternFragment: String =
|
||||||
|
"""([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+[a-zA-Z]{2,}"""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pattern to match all valid usernames
|
||||||
|
*/
|
||||||
|
const val userPatternFragment: String = """[a-zA-Z0-9_]{3,}"""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pattern to match lemmy's unique community pattern, e.g. !commmunity[@instance]
|
||||||
|
*/
|
||||||
|
val lemmyCommunityPattern: Pattern =
|
||||||
|
Pattern.compile("(?<!\\S)!($communityPatternFragment)(?:@($instancePatternFragment))?\\b")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pattern to match lemmy's unique user pattern, e.g. @user[@instance]
|
||||||
|
*/
|
||||||
|
val lemmyUserPattern: Pattern =
|
||||||
|
Pattern.compile("(?<!\\S)@($userPatternFragment)(?:@($instancePatternFragment))?\\b")
|
||||||
|
|
||||||
|
}
|
||||||
|
override fun configure(registry: MarkwonPlugin.Registry) {
|
||||||
|
registry.require(CorePlugin::class.java) { it.addOnTextAddedListener(LemmyTextAddedListener()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LemmyTextAddedListener : CorePlugin.OnTextAddedListener {
|
||||||
|
override fun onTextAdded(visitor: MarkwonVisitor, text: String, start: Int) {
|
||||||
|
// we will be using the link that is used by markdown (instead of directly applying URLSpan)
|
||||||
|
val spanFactory = visitor.configuration().spansFactory().get(
|
||||||
|
Link::class.java,
|
||||||
|
) ?: return
|
||||||
|
|
||||||
|
// don't re-use builder (thread safety achieved for
|
||||||
|
// render calls from different threads and ... better performance)
|
||||||
|
val builder = SpannableStringBuilder(text)
|
||||||
|
if (addLinks(builder)) {
|
||||||
|
// target URL span specifically
|
||||||
|
val spans = builder.getSpans(0, builder.length, URLSpan::class.java)
|
||||||
|
if (!spans.isNullOrEmpty()) {
|
||||||
|
val renderProps = visitor.renderProps()
|
||||||
|
val spannableBuilder = visitor.builder()
|
||||||
|
for (span in spans) {
|
||||||
|
CoreProps.LINK_DESTINATION[renderProps] = if (span.url.startsWith("!")) { LemmyUtils.qualifiedCommunityName2ActorId(span.url.drop(1)) } else { LemmyUtils.qualifiedUserName2ActorId(span.url.drop(1)) }
|
||||||
|
SpannableBuilder.setSpans(
|
||||||
|
spannableBuilder,
|
||||||
|
spanFactory.getSpans(visitor.configuration(), renderProps),
|
||||||
|
start + builder.getSpanStart(span),
|
||||||
|
start + builder.getSpanEnd(span),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addLinks(text: Spannable): Boolean {
|
||||||
|
val communityLinkAdded = Linkify.addLinks(text, lemmyCommunityPattern, null)
|
||||||
|
val userLinkAdded = Linkify.addLinks(text, lemmyUserPattern, null)
|
||||||
|
|
||||||
|
return communityLinkAdded || userLinkAdded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1352,4 +1352,6 @@
|
|||||||
<string name="instance_cannot_be_empty">The instance field cannot be left empty.</string>
|
<string name="instance_cannot_be_empty">The instance field cannot be left empty.</string>
|
||||||
<string name="username_cannot_be_empty">The username field cannot be left empty.</string>
|
<string name="username_cannot_be_empty">The username field cannot be left empty.</string>
|
||||||
<string name="password_cannot_be_empty">The password field cannot be left empty.</string>
|
<string name="password_cannot_be_empty">The password field cannot be left empty.</string>
|
||||||
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
|
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -9,6 +9,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||||
|
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.20'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
Loading…
x
Reference in New Issue
Block a user