diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7c7d5b18..be988ad9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -54,19 +54,21 @@ + - + + + - > { - private HttpUrl forumUrl = SessionManager.forumUrl; //may change upon collapse/expand + private HttpUrl forumUrl = SessionManager.getForumUrl(); //may change upon collapse/expand ForumTask(OnTaskStartedListener onTaskStartedListener, OnNetworkTaskFinishedListener> onParseTaskFinishedListener) { diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReplyTask.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReplyTask.java index b67b2157..373bde04 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReplyTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/tasks/PrepareForReplyTask.java @@ -61,7 +61,7 @@ public class PrepareForReplyTask extends AsyncTask { .addFormDataPart("icon", "xx") .build(); Request post = new Request.Builder() - .url("https://www.thmmy.gr/smf/index.php?action=post2") + .url(BaseApplication.getForumUrl() + "index.php?action=post2") .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36") .post(postBody) .build(); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java index 48ec3b5b..cfb27028 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/upload/UploadActivity.java @@ -91,7 +91,7 @@ public class UploadActivity extends BaseActivity { public static final String BUNDLE_UPLOAD_CATEGORY = "UPLOAD_CATEGORY"; public static final String firebaseConfigUploadsCoursesKey = "uploads_courses"; - private static final String uploadIndexUrl = "https://www.thmmy.gr/smf/index.php?action=tpmod;dl=upload"; + private static final String uploadIndexUrl = forumUrl + "index.php?action=tpmod;dl=upload"; private static final String uploadedFromTHMMYPromptHtml = "
uploaded from mTHMMY"; /** * Request codes used in activities for result (AFR) calls diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java index 0fc7d749..e983bb8d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -106,6 +106,8 @@ public abstract class BaseActivity extends AppCompatActivity { private boolean isMainActivity; private boolean isUserConsentDialogShown; //Needed because sometimes onResume is being called twice + protected static String forumUrl = BaseApplication.getForumUrl(); // For convenience + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -346,7 +348,7 @@ public abstract class BaseActivity extends AppCompatActivity { if (sessionManager.isLoggedIn()) { Intent intent = new Intent(BaseActivity.this, ProfileActivity.class); Bundle extras = new Bundle(); - extras.putString(BUNDLE_PROFILE_URL, "https://www.thmmy.gr/smf/index.php?action=profile"); + extras.putString(BUNDLE_PROFILE_URL, forumUrl + "index.php?action=profile"); if (!sessionManager.hasAvatar()) extras.putString(BUNDLE_PROFILE_THUMBNAIL_URL, ""); else diff --git a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java index 5b1d0154..e38f4472 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseApplication.java @@ -3,6 +3,7 @@ package gr.thmmy.mthmmy.base; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; @@ -70,10 +71,27 @@ public class BaseApplication extends Application implements Executor{ private static float widthDp; private static int widthPxl, heightPxl; + private static String forumUrl; + private static String forumHost; + private static String forumHostSimple; + public static BaseApplication getInstance() { return baseApplication; } + public static String getForumUrl() { + return forumUrl; + } + + public static String getForumHost() { + return forumHost; + } + + + public static String getForumHostSimple() { + return forumHostSimple; + } + @Override public void onCreate() { super.onCreate(); @@ -83,6 +101,11 @@ public class BaseApplication extends Application implements Executor{ if (BuildConfig.DEBUG) Timber.plant(new Timber.DebugTree()); + Resources resources = getApplicationContext().getResources(); + forumUrl = resources.getString(R.string.forum_url); + forumHost = resources.getString(R.string.forum_host); + forumHostSimple= resources.getString(R.string.forum_host_simple); + //Shared Preferences SharedPreferences sessionSharedPrefs = getSharedPreferences(getString(R.string.session_shared_prefs), MODE_PRIVATE); SharedPreferences settingsSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -157,7 +180,7 @@ public class BaseApplication extends Application implements Executor{ .addInterceptor(chain -> { Request request = chain.request(); HttpUrl oldUrl = chain.request().url(); - if (Objects.equals(chain.request().url().host(), "www.thmmy.gr") + if (Objects.equals(chain.request().url().host(), forumHost) && !oldUrl.toString().contains("theme=4")) { //Probably works but needs more testing: HttpUrl newUrl = oldUrl.newBuilder().addQueryParameter("theme", "4").build(); diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java index 0b47cb42..dbaf4e23 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/ThmmyPage.java @@ -6,6 +6,7 @@ import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; +import gr.thmmy.mthmmy.base.BaseApplication; import timber.log.Timber; /** @@ -20,6 +21,14 @@ public class ThmmyPage { @SuppressWarnings("unused") private static final String TAG = "LinkTarget"; + private static final String forumUrl = BaseApplication.getForumUrl(); + private static final String forumHost = BaseApplication.getForumHost(); + private static final String forumHostHttp = "http://" + forumHost; + private static final String forumHostHttps = "https://" + forumHost; + private static final String forumHostSimple = BaseApplication.getForumHostSimple(); + private static final String forumHostSimpleHttp = "http://" + forumHostSimple; + private static final String forumHostSimpleHttps = "https://" + forumHostSimple; + /** * An enum describing a link's target by defining the types:
    *
  • {@link #NOT_THMMY}
  • @@ -142,9 +151,9 @@ public class ThmmyPage { final String host = uri.getHost(); final String uriString = uri.toString(); - if (Objects.equals(uriString, "http://thmmy.gr") - || Objects.equals(uriString, "https://thmmy.gr")) return PageCategory.INDEX; - if (Objects.equals(host, "www.thmmy.gr")) { + if (Objects.equals(uriString, forumHostSimpleHttp) + || Objects.equals(uriString, forumHostSimpleHttps)) return PageCategory.INDEX; + if (Objects.equals(host, forumHost)) { if (uriString.contains("topic=")) return PageCategory.TOPIC; else if (uriString.contains("board=")) return PageCategory.BOARD; else if (uriString.contains("action=profile")) { @@ -160,12 +169,12 @@ public class ThmmyPage { return PageCategory.DOWNLOADS_FILE; else if (uriString.contains("action=tpmod;dl")) return PageCategory.DOWNLOADS_CATEGORY; - else if (uriString.contains("action=forum") || Objects.equals(uriString, "www.thmmy.gr") - || Objects.equals(uriString, "http://www.thmmy.gr") - || Objects.equals(uriString, "https://www.thmmy.gr") - || Objects.equals(uriString, "https://www.thmmy.gr/smf/index.php")) + else if (uriString.contains("action=forum") || Objects.equals(uriString, forumHost) + || Objects.equals(uriString, forumHostHttp) + || Objects.equals(uriString, forumHostHttps) + || Objects.equals(uriString, forumUrl + "index.php")) return PageCategory.INDEX; - Timber.v("Unknown thmmy link found, link: %s", uriString); + Timber.v("Unknown thmmy link found, link: %s", uriString); //TODO: maybe report this? return PageCategory.UNKNOWN_THMMY; } return PageCategory.NOT_THMMY; diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java index 482dffdb..07ea15af 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java @@ -171,7 +171,7 @@ public class NotificationService extends FirebaseMessagingService { } //Builds notification - String topicUrl = "https://www.thmmy.gr/smf/index.php?topic=" + postNotification.getTopicId() + "." + postNotification.getPostId(); + String topicUrl = BaseApplication.getForumUrl() + "index.php?topic=" + postNotification.getTopicId() + "." + postNotification.getPostId(); Intent intent = new Intent(this, MainActivity.class); Bundle extras = new Bundle(); extras.putString(BUNDLE_TOPIC_URL, topicUrl); diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java index d199d539..207336a5 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.utils.parsing.ParseException; import okhttp3.Cookie; import okhttp3.FormBody; @@ -34,13 +35,14 @@ import timber.log.Timber; */ public class SessionManager { //Generic constants - public static final HttpUrl indexUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?theme=4"); - public static final HttpUrl forumUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=forum;theme=4"); - private static final HttpUrl loginUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=login2"); - public static final HttpUrl unreadUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=unread;all;start=0;theme=4"); - public static final HttpUrl shoutboxUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=tpmod;sa=shoutbox;theme=4"); - static final String baseLogoutLink = "https://www.thmmy.gr/smf/index.php?action=logout;sesc="; - static final String baseMarkAllAsReadLink = "https://www.thmmy.gr/smf/index.php?action=markasread;sa=all;sesc="; + private final static String FORUM_URL = BaseApplication.getForumUrl(); + public static final HttpUrl indexUrl = HttpUrl.parse(FORUM_URL + "index.php?theme=4"); + private static final HttpUrl forumUrl = HttpUrl.parse(FORUM_URL + "index.php?action=forum;theme=4"); + private static final HttpUrl loginUrl = HttpUrl.parse(FORUM_URL + "index.php?action=login2"); + public static final HttpUrl unreadUrl = HttpUrl.parse(FORUM_URL + "index.php?action=unread;all;start=0;theme=4"); + public static final HttpUrl shoutboxUrl = HttpUrl.parse(FORUM_URL + "index.php?action=tpmod;sa=shoutbox;theme=4"); + static final String baseLogoutLink = FORUM_URL + "index.php?action=logout;sesc="; + static final String baseMarkAllAsReadLink = FORUM_URL + "index.php?action=markasread;sa=all;sesc="; private static final String guestName = "Guest"; //Response Codes - make sure they do not overlap with NetworkResultCodes, just in case @@ -190,6 +192,10 @@ public class SessionManager { } //--------------------------------------- GETTERS ------------------------------------------------ + public static HttpUrl getForumUrl() { + return forumUrl; + } + public String getUsername() { return sessionSharedPrefs.getString(USERNAME, USERNAME); } @@ -291,7 +297,7 @@ public class SessionManager { if (elements.size() == 1) { String link = elements.first().attr("href"); - Pattern pattern = Pattern.compile("https://www.thmmy.gr/smf/index.php\\?action=profile;u=(\\d*);sa=showPosts"); + Pattern pattern = Pattern.compile(FORUM_URL + "index.php\\?action=profile;u=(\\d*);sa=showPosts"); Matcher matcher = pattern.matcher(link); if (matcher.find()) return Integer.parseInt(matcher.group(1)); diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java index 7d1c2189..bdf79ae9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/networking/NetworkTask.java @@ -57,7 +57,7 @@ public abstract class NetworkTask extends ExternalAsyncTask try { response = sendRequest(BaseApplication.getInstance().getClient(), input); } catch (IOException e) { - Timber.e(e, "Error connecting to thmmy.gr"); + Timber.e(e, "Error connecting to forum!"); return new Parcel<>(NetworkResultCodes.NETWORK_ERROR, null); } String responseBodyString; diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java index 2aea53c4..af00157d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/parsing/ParseHelpers.java @@ -9,13 +9,15 @@ import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import gr.thmmy.mthmmy.base.BaseApplication; + /** * This class consists exclusively of static classes (enums) and methods (excluding methods of inner * classes). It can be used to resolve a page's language and state or fix embedded videos html code * and obfuscated emails. */ public class ParseHelpers { - + private final static String FORUM_URL = BaseApplication.getForumUrl(); /** * An enum describing a forum page's language by defining the types:
      *
    • {@link #PAGE_INCOMPLETE}
    • @@ -185,138 +187,138 @@ public class ParseHelpers { * @return the base URL of the given topic */ public static String getBaseURL(String topicURL) { - String forumUrl = "https://www.thmmy.gr/smf/index.php?"; + String indexUrl = FORUM_URL + "index.php?"; Matcher baseUrlMatcher = Pattern.compile("topic=[0-9]+").matcher(topicURL); if (baseUrlMatcher.find()) - return forumUrl + topicURL.substring(baseUrlMatcher.start(), baseUrlMatcher.end()); + return indexUrl + topicURL.substring(baseUrlMatcher.start(), baseUrlMatcher.end()); else return ""; } public static String emojiTagToHtml(String emojiTagedString) { HashMap tagToHtmlMap = new HashMap<>(); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":)"), Pattern.MULTILINE), "\"Smiley\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(";)"), Pattern.MULTILINE), "\"Wink\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":D"), Pattern.MULTILINE), "\"Cheesy\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(";D"), Pattern.MULTILINE), "\"Grin\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(">:("), Pattern.MULTILINE), "\"Angry\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":("), Pattern.MULTILINE), "\"Sad\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":o"), Pattern.MULTILINE), "\"Shocked\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("8))"), Pattern.MULTILINE), "\"Cool\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":???:"), Pattern.MULTILINE), "\"Huh\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":P"), Pattern.MULTILINE), "\"Tongue\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-["), Pattern.MULTILINE), "\"Embarrassed\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-X"), Pattern.MULTILINE), "\"Lips"); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-\\"), Pattern.MULTILINE), "\"Undecided\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-*"), Pattern.MULTILINE), "\"Kiss\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":'("), Pattern.MULTILINE), "\"Cry\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("<3"), Pattern.MULTILINE), "\"heart\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^locked^"), Pattern.MULTILINE), "\"kleidaria\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^rollover^"), Pattern.MULTILINE), "\"roll_over\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^redface^"), Pattern.MULTILINE), "\"redface\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^confused^"), Pattern.MULTILINE), "\"confused\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^innocent^"), Pattern.MULTILINE), "\"innocent\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sleep^"), Pattern.MULTILINE), "\"sleep\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sealed^"), Pattern.MULTILINE), "\"lips_sealed\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^cool^"), Pattern.MULTILINE), "\"cool\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^crazy^"), Pattern.MULTILINE), "\"crazy\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^mad^"), Pattern.MULTILINE), "\"mad\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^wav^"), Pattern.MULTILINE), "\"wav\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^binkybaby^"), Pattern.MULTILINE), "\"BinkyBaby\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^Police^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^dontknow^"), Pattern.MULTILINE), "\"DontKnow\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote(":angry4:"), Pattern.MULTILINE), "\"angry4\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^angryhot^"), Pattern.MULTILINE), "\"angryAndHot\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^angry^"), Pattern.MULTILINE), "\"angry\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^fouska^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^nysta^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sfinaki^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^banghead^"), Pattern.MULTILINE), "\"bang_head\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^crybaby^"), Pattern.MULTILINE), "\"CryBaby\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^hello^"), Pattern.MULTILINE), "\"Hello\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^jerk^"), Pattern.MULTILINE), "\"jerk\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^nono^"), Pattern.MULTILINE), "\"NoNo\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^notworthy^"), Pattern.MULTILINE), "\"NotWorthy\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^off-topic^"), Pattern.MULTILINE), "\"Off-topic\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^puke^"), Pattern.MULTILINE), "\"Puke\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shout^"), Pattern.MULTILINE), "\"Shout\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^slurp^"), Pattern.MULTILINE), "\"Slurp\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^superconfused^"), Pattern.MULTILINE), "\"SuperConfused\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^superinnocent^"), Pattern.MULTILINE), "\"SuperInnocent\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^cellPhone^"), Pattern.MULTILINE), "\"CellPhone\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^idiot^"), Pattern.MULTILINE), "\"Idiot\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^knuppel^"), Pattern.MULTILINE), "\"Knuppel\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^tickedOff^"), Pattern.MULTILINE), "\"TickedOff\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^peace^"), Pattern.MULTILINE), "\"Peace\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^suspicious^"), Pattern.MULTILINE), "\"Suspicious\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^caffine^"), Pattern.MULTILINE), "\"Caffine\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^argue^"), Pattern.MULTILINE), "\"argue\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^banned2^"), Pattern.MULTILINE), "\"banned2\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^banned^"), Pattern.MULTILINE), "\"banned\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bath^"), Pattern.MULTILINE), "\"bath\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^beg^"), Pattern.MULTILINE), "\"beg\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bluescreen^"), Pattern.MULTILINE), "\"bluescreen\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^boil^"), Pattern.MULTILINE), "\"boil\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bye^"), Pattern.MULTILINE), "\"bye\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^callmerip^"), Pattern.MULTILINE), "\"callmerip\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^carnaval^"), Pattern.MULTILINE), "\"carnaval\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^clap^"), Pattern.MULTILINE), "\"clap\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^coffepot^"), Pattern.MULTILINE), "\"coffepot\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^crap^"), Pattern.MULTILINE), "\"crap\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^curses^"), Pattern.MULTILINE), "\"curses\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^funny^"), Pattern.MULTILINE), "\"funny\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^guitar^"), Pattern.MULTILINE), "\"guitar\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^kissy^"), Pattern.MULTILINE), "\"kissy\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^band^"), Pattern.MULTILINE), "\"band\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^ivres^"), Pattern.MULTILINE), "\"ivres\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^kaloe^"), Pattern.MULTILINE), "\"kaloe\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^kremala^"), Pattern.MULTILINE), "\"kremala\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^moon^"), Pattern.MULTILINE), "\"moon\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^mopping^"), Pattern.MULTILINE), "\"mopping\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^mountza^"), Pattern.MULTILINE), "\"mountza\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^pcsleep^"), Pattern.MULTILINE), "\"pcsleep\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^pinokio^"), Pattern.MULTILINE), "\"pinokio\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^poke^"), Pattern.MULTILINE), "\"poke\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^seestars^"), Pattern.MULTILINE), "\"seestars\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sfyri^"), Pattern.MULTILINE), "\"sfyri\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^spam^"), Pattern.MULTILINE), "\"spam\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^super^"), Pattern.MULTILINE), "\"super\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^tafos^"), Pattern.MULTILINE), "\"tafos\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^tomato^"), Pattern.MULTILINE), "\"tomato\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^ytold^"), Pattern.MULTILINE), "\"ytold\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^beer^"), Pattern.MULTILINE), "\"beer\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^yue^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^eatpaper^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^fritz^"), Pattern.MULTILINE), "\"ο"); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^wade^"), Pattern.MULTILINE), "\"o"); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^lypi^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^aytoxeir^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^victory^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^filarakia^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^hat^"), Pattern.MULTILINE), "\"bonjour\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^miss^"), Pattern.MULTILINE), "\"bonjour2\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^rolfmao^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^lock^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^que^"), Pattern.MULTILINE), "\"question\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shifty^"), Pattern.MULTILINE), "\"shifty\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shy^"), Pattern.MULTILINE), "\"shy\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^music_listen^"), Pattern.MULTILINE), "\"music_listenning\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bagface^"), Pattern.MULTILINE), "\"bag_face\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^rotate^"), Pattern.MULTILINE), "\"rotation\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^love^"), Pattern.MULTILINE), "\"love\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^speech^"), Pattern.MULTILINE), "\"speech\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^facepalm^"), Pattern.MULTILINE), "\"\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shocked^"), Pattern.MULTILINE), "\"shocked\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^ex_shocked^"), Pattern.MULTILINE), "\"extremely_shocked\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^smurf^"), Pattern.MULTILINE), "\"smurf\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^monster^"), Pattern.MULTILINE), "\"monster\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^pig^"), Pattern.MULTILINE), "\"pig\""); - tagToHtmlMap.put(Pattern.compile(Pattern.quote("^lol^"), Pattern.MULTILINE), "\"lol\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":)"), Pattern.MULTILINE), "\"Smiley\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(";)"), Pattern.MULTILINE), "\"Wink\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":D"), Pattern.MULTILINE), "\"Cheesy\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(";D"), Pattern.MULTILINE), "\"Grin\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(">:("), Pattern.MULTILINE), "\"Angry\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":("), Pattern.MULTILINE), "\"Sad\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":o"), Pattern.MULTILINE), "\"Shocked\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("8))"), Pattern.MULTILINE), "\"Cool\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":???:"), Pattern.MULTILINE), "\"Huh\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":P"), Pattern.MULTILINE), "\"Tongue\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-["), Pattern.MULTILINE), "\"Embarrassed\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-X"), Pattern.MULTILINE), "\"Lips"); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-\\"), Pattern.MULTILINE), "\"Undecided\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":-*"), Pattern.MULTILINE), "\"Kiss\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":'("), Pattern.MULTILINE), "\"Cry\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("<3"), Pattern.MULTILINE), "\"heart\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^locked^"), Pattern.MULTILINE), "\"kleidaria\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^rollover^"), Pattern.MULTILINE), "\"roll_over\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^redface^"), Pattern.MULTILINE), "\"redface\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^confused^"), Pattern.MULTILINE), "\"confused\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^innocent^"), Pattern.MULTILINE), "\"innocent\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sleep^"), Pattern.MULTILINE), "\"sleep\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sealed^"), Pattern.MULTILINE), "\"lips_sealed\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^cool^"), Pattern.MULTILINE), "\"cool\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^crazy^"), Pattern.MULTILINE), "\"crazy\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^mad^"), Pattern.MULTILINE), "\"mad\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^wav^"), Pattern.MULTILINE), "\"wav\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^binkybaby^"), Pattern.MULTILINE), "\"BinkyBaby\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^Police^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^dontknow^"), Pattern.MULTILINE), "\"DontKnow\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote(":angry4:"), Pattern.MULTILINE), "\"angry4\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^angryhot^"), Pattern.MULTILINE), "\"angryAndHot\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^angry^"), Pattern.MULTILINE), "\"angry\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^fouska^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^nysta^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sfinaki^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^banghead^"), Pattern.MULTILINE), "\"bang_head\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^crybaby^"), Pattern.MULTILINE), "\"CryBaby\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^hello^"), Pattern.MULTILINE), "\"Hello\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^jerk^"), Pattern.MULTILINE), "\"jerk\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^nono^"), Pattern.MULTILINE), "\"NoNo\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^notworthy^"), Pattern.MULTILINE), "\"NotWorthy\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^off-topic^"), Pattern.MULTILINE), "\"Off-topic\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^puke^"), Pattern.MULTILINE), "\"Puke\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shout^"), Pattern.MULTILINE), "\"Shout\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^slurp^"), Pattern.MULTILINE), "\"Slurp\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^superconfused^"), Pattern.MULTILINE), "\"SuperConfused\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^superinnocent^"), Pattern.MULTILINE), "\"SuperInnocent\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^cellPhone^"), Pattern.MULTILINE), "\"CellPhone\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^idiot^"), Pattern.MULTILINE), "\"Idiot\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^knuppel^"), Pattern.MULTILINE), "\"Knuppel\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^tickedOff^"), Pattern.MULTILINE), "\"TickedOff\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^peace^"), Pattern.MULTILINE), "\"Peace\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^suspicious^"), Pattern.MULTILINE), "\"Suspicious\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^caffine^"), Pattern.MULTILINE), "\"Caffine\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^argue^"), Pattern.MULTILINE), "\"argue\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^banned2^"), Pattern.MULTILINE), "\"banned2\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^banned^"), Pattern.MULTILINE), "\"banned\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bath^"), Pattern.MULTILINE), "\"bath\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^beg^"), Pattern.MULTILINE), "\"beg\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bluescreen^"), Pattern.MULTILINE), "\"bluescreen\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^boil^"), Pattern.MULTILINE), "\"boil\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bye^"), Pattern.MULTILINE), "\"bye\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^callmerip^"), Pattern.MULTILINE), "\"callmerip\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^carnaval^"), Pattern.MULTILINE), "\"carnaval\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^clap^"), Pattern.MULTILINE), "\"clap\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^coffepot^"), Pattern.MULTILINE), "\"coffepot\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^crap^"), Pattern.MULTILINE), "\"crap\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^curses^"), Pattern.MULTILINE), "\"curses\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^funny^"), Pattern.MULTILINE), "\"funny\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^guitar^"), Pattern.MULTILINE), "\"guitar\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^kissy^"), Pattern.MULTILINE), "\"kissy\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^band^"), Pattern.MULTILINE), "\"band\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^ivres^"), Pattern.MULTILINE), "\"ivres\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^kaloe^"), Pattern.MULTILINE), "\"kaloe\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^kremala^"), Pattern.MULTILINE), "\"kremala\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^moon^"), Pattern.MULTILINE), "\"moon\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^mopping^"), Pattern.MULTILINE), "\"mopping\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^mountza^"), Pattern.MULTILINE), "\"mountza\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^pcsleep^"), Pattern.MULTILINE), "\"pcsleep\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^pinokio^"), Pattern.MULTILINE), "\"pinokio\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^poke^"), Pattern.MULTILINE), "\"poke\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^seestars^"), Pattern.MULTILINE), "\"seestars\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^sfyri^"), Pattern.MULTILINE), "\"sfyri\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^spam^"), Pattern.MULTILINE), "\"spam\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^super^"), Pattern.MULTILINE), "\"super\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^tafos^"), Pattern.MULTILINE), "\"tafos\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^tomato^"), Pattern.MULTILINE), "\"tomato\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^ytold^"), Pattern.MULTILINE), "\"ytold\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^beer^"), Pattern.MULTILINE), "\"beer\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^yue^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^eatpaper^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^fritz^"), Pattern.MULTILINE), "\"ο"); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^wade^"), Pattern.MULTILINE), "\"o"); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^lypi^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^aytoxeir^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^victory^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^filarakia^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^hat^"), Pattern.MULTILINE), "\"bonjour\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^miss^"), Pattern.MULTILINE), "\"bonjour2\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^rolfmao^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^lock^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^que^"), Pattern.MULTILINE), "\"question\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shifty^"), Pattern.MULTILINE), "\"shifty\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shy^"), Pattern.MULTILINE), "\"shy\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^music_listen^"), Pattern.MULTILINE), "\"music_listenning\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^bagface^"), Pattern.MULTILINE), "\"bag_face\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^rotate^"), Pattern.MULTILINE), "\"rotation\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^love^"), Pattern.MULTILINE), "\"love\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^speech^"), Pattern.MULTILINE), "\"speech\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^facepalm^"), Pattern.MULTILINE), "\"\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^shocked^"), Pattern.MULTILINE), "\"shocked\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^ex_shocked^"), Pattern.MULTILINE), "\"extremely_shocked\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^smurf^"), Pattern.MULTILINE), "\"smurf\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^monster^"), Pattern.MULTILINE), "\"monster\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^pig^"), Pattern.MULTILINE), "\"pig\""); + tagToHtmlMap.put(Pattern.compile(Pattern.quote("^lol^"), Pattern.MULTILINE), "\"lol\""); //Needs priority over the rest tags final Pattern pattern = Pattern.compile(Pattern.quote("::)"), Pattern.MULTILINE); Matcher matcher = pattern.matcher(emojiTagedString); - emojiTagedString = matcher.replaceAll("\"Roll"); + emojiTagedString = matcher.replaceAll("\"Roll"); for (Pattern patternKey : tagToHtmlMap.keySet()) { matcher = patternKey.matcher(emojiTagedString); diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 29c0bb21..9a8a3119 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -31,7 +31,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" - android:contentDescription="@string/thmmy_img_description" /> + android:contentDescription="@string/mthmmy_logo" /> mTHMMY + https://www.thmmy.gr/smf/ + www.thmmy.gr + thmmy.gr Login @@ -26,7 +29,7 @@ No unread topics! - thmmy.gr + mTHMMY Username Password LOGIN