diff --git a/.gitignore b/.gitignore index 252008e0..8df35eb6 100644 --- a/.gitignore +++ b/.gitignore @@ -46,5 +46,5 @@ captures/ ### Android Patch ### gen-external-apklibs -# Google Services (release build) -app/src/release/google-services.json \ No newline at end of file +# Google Services JSON +google-services.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 851425b8..1788ca59 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,30 +2,38 @@ image: openjdk:8-jdk variables: ANDROID_TARGET_SDK: "26" - ANDROID_BUILD_TOOLS: "26.0.1" - ANDROID_SDK_TOOLS: "25.2.5" + ANDROID_BUILD_TOOLS: "27.0.0" + ANDROID_SDK_TOOLS_REV: "3859397" before_script: - apt-get --quiet update --yes - - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 - - wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/tools_r${ANDROID_SDK_TOOLS}-linux.zip - - unzip android-sdk.zip -d android-sdk-linux - - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter android-${ANDROID_TARGET_SDK} - - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter platform-tools - - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter build-tools-${ANDROID_BUILD_TOOLS} - - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-android-m2repository - - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-google_play_services - - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-m2repository + - apt-get --quiet install --yes wget unzip lib32stdc++6 lib32z1 + - mkdir $HOME/.android # for sdkmanager configs + - echo 'count=0' > $HOME/.android/repositories.cfg # avoid warning + - wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS_REV}.zip + - mkdir $PWD/android-sdk-linux + - unzip -qq android-sdk.zip -d $PWD/android-sdk-linux - export ANDROID_HOME=$PWD/android-sdk-linux - - export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/ + - echo y | $ANDROID_HOME/tools/bin/sdkmanager --update > /dev/null + - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'tools' > /dev/null + - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'platform-tools' > /dev/null + - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'build-tools;'$ANDROID_BUILD_TOOLS > /dev/null + - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'platforms;android-'$ANDROID_TARGET_SDK > /dev/null + - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'extras;android;m2repository' > /dev/null + - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'extras;google;google_play_services' > /dev/null + - echo y | $ANDROID_HOME/tools/bin/sdkmanager 'extras;google;m2repository' > /dev/null - chmod +x ./gradlew -build_develop: +stages: + - build + +build: + stage: build script: - - ./gradlew assembleDebug + - ./gradlew assembleDebug > /dev/null except: - master artifacts: name: "${CI_BUILD_NAME}" paths: - - app/build/outputs/apk + - app/build/outputs/ diff --git a/VERSION b/VERSION index 1892b926..31e5c843 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.2 +1.3.3 diff --git a/app/build.gradle b/app/build.gradle index 719a0366..d6341ed7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,15 +2,15 @@ apply plugin: 'com.android.application' android { compileSdkVersion 26 - buildToolsVersion "26.0.1" + buildToolsVersion "27.0.0" defaultConfig { vectorDrawables.useSupportLibrary = true applicationId "gr.thmmy.mthmmy" minSdkVersion 19 targetSdkVersion 26 - versionCode 10 - versionName "1.3.2" + versionCode 11 + versionName "1.3.3" archivesBaseName = "mTHMMY-v$versionName" } @@ -19,35 +19,38 @@ android { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } - /*debug { - def date = new Date().format('ddMMyy_HH'); + debug { + def date = new Date().format('ddMMyy_HHmmss') archivesBaseName = archivesBaseName + "-$date" - }*/ + } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:26.0.0' - compile 'com.android.support:design:26.0.0' - compile 'com.android.support:support-v4:26.0.0' - compile 'com.android.support:cardview-v7:26.0.0' - compile 'com.android.support:recyclerview-v7:26.0.0' - compile 'com.google.firebase:firebase-crash:10.2.6' - compile 'com.squareup.okhttp3:okhttp:3.8.0' + compile 'com.android.support:appcompat-v7:26.1.0' + compile 'com.android.support:design:26.1.0' + compile 'com.android.support:support-v4:26.1.0' + compile 'com.android.support:cardview-v7:26.1.0' + compile 'com.android.support:recyclerview-v7:26.1.0' + compile 'com.google.firebase:firebase-crash:11.4.2' + compile 'com.squareup.okhttp3:okhttp:3.9.0' compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0' - compile 'org.jsoup:jsoup:1.10.2' + compile 'org.jsoup:jsoup:1.10.3' compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1' compile 'com.github.PhilJay:MPAndroidChart:v3.0.2' - compile('com.mikepenz:materialdrawer:5.9.2@aar') { + compile('com.mikepenz:materialdrawer:5.9.3@aar') { transitive = true } compile 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar' + compile 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar' compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.7' compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1' //TODO: Deprecated - needs replacement! - compile 'me.zhanghai.android.materialprogressbar:library:1.4.1' + compile 'me.zhanghai.android.materialprogressbar:library:1.4.2' compile 'com.jakewharton.timber:timber:4.5.1' } -apply plugin: 'com.google.gms.google-services' +if (getGradle().getStartParameter().getTaskRequests().toString().contains("Release")){ + apply plugin: 'com.google.gms.google-services' +} diff --git a/app/src/debug/google-services.json b/app/src/debug/google-services.json deleted file mode 100644 index c6718eaa..00000000 --- a/app/src/debug/google-services.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "project_info": { - "project_number": "934432863001", - "firebase_url": "https://mthmmy-debug.firebaseio.com", - "project_id": "mthmmy-debug", - "storage_bucket": "mthmmy-debug.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:934432863001:android:088be0537ff6b292", - "android_client_info": { - "package_name": "gr.thmmy.mthmmy" - } - }, - "oauth_client": [ - { - "client_id": "934432863001-d5oocs1vdi0pcepesi55a41p7enphfcv.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyD4-gwVcb2Rc8zeT8l1v2Lg1DU0QgfGtk8" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0ed23714..118026f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ + diff --git a/app/src/main/assets/mit_libraries.html b/app/src/main/assets/mit_libraries.html index 42b46e78..c0fa7697 100644 --- a/app/src/main/assets/mit_libraries.html +++ b/app/src/main/assets/mit_libraries.html @@ -39,7 +39,7 @@
  • -
    jsoup v1.10.2 (Copyright ©2009-2017, Jonathan Hedley <jonathan@hedley.net>)
    +
    jsoup v1.10.3 (Copyright ©2009-2017, Jonathan Hedley <jonathan@hedley.net>)
  • android-gif-drawable v1.2.7 (Copyright ©2016 Karol Wrótniak, Droids on Roids)
    diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java index 3f23909b..896a5fb5 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/AboutActivity.java @@ -53,28 +53,33 @@ public class AboutActivity extends BaseActivity { trollGif = findViewById(R.id.trollPicFrame); TextView tv = findViewById(R.id.version); - if (tv != null) - tv.setText(getString(R.string.version, versionName)); - - tv.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (mVersionLastPressedTime + TIME_INTERVAL > System.currentTimeMillis()) { - if (mVersionPressedCounter == TIMES_TO_PRESS) { - appBar.setVisibility(View.INVISIBLE); - mainContent.setVisibility(View.INVISIBLE); - trollGif.setVisibility(View.VISIBLE); - drawer.getDrawerLayout().setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + if (tv != null) { + if (BuildConfig.DEBUG) + tv.setText(getString(R.string.version, versionName + "-debug")); + else + tv.setText(getString(R.string.version, versionName)); + + + tv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (mVersionLastPressedTime + TIME_INTERVAL > System.currentTimeMillis()) { + if (mVersionPressedCounter == TIMES_TO_PRESS) { + appBar.setVisibility(View.INVISIBLE); + mainContent.setVisibility(View.INVISIBLE); + trollGif.setVisibility(View.VISIBLE); + drawer.getDrawerLayout().setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + mVersionLastPressedTime = System.currentTimeMillis(); + ++mVersionPressedCounter; + } else { + mVersionLastPressedTime = System.currentTimeMillis(); + mVersionPressedCounter = 0; } - mVersionLastPressedTime = System.currentTimeMillis(); - ++mVersionPressedCounter; - } else { - mVersionLastPressedTime = System.currentTimeMillis(); - mVersionPressedCounter = 0; } - } - }); + }); + } } @@ -95,7 +100,8 @@ public class AboutActivity extends BaseActivity { .setView(webView) .setPositiveButton(android.R.string.ok, null) .show(); - alertDialog.getWindow().setLayout(width, height); + if(alertDialog.getWindow()!=null) + alertDialog.getWindow().setLayout(width, height); } public void displayMITLibraries(View v) { @@ -109,7 +115,8 @@ public class AboutActivity extends BaseActivity { .setView(webView) .setPositiveButton(android.R.string.ok, null) .show(); - alertDialog.getWindow().setLayout(width, height); + if(alertDialog.getWindow()!=null) + alertDialog.getWindow().setLayout(width, height); } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java index 4adb199e..dcd9ab3c 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/forum/ForumFragment.java @@ -125,7 +125,7 @@ public class ForumFragment extends BaseFragment { }); CustomRecyclerView recyclerView = rootView.findViewById(R.id.list); - LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext()); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(recyclerView.getContext()); recyclerView.setLayoutManager(linearLayoutManager); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation()); @@ -133,6 +133,8 @@ public class ForumFragment extends BaseFragment { recyclerView.setAdapter(forumAdapter); swipeRefreshLayout = rootView.findViewById(R.id.swiperefresh); + swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.primary); + swipeRefreshLayout.setColorSchemeResources(R.color.accent); swipeRefreshLayout.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java index 15b9bc36..de128cb1 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentAdapter.java @@ -43,7 +43,7 @@ class RecentAdapter extends RecyclerView.Adapter { public void onBindViewHolder(final ViewHolder holder, final int position) { holder.mTitleView.setText(recentList.get(position).getSubject()); holder.mDateTimeView.setText(recentList.get(position).getDateTimeModified()); - holder.mUserView.setText(context.getString(R.string.byUser, recentList.get(position).getLastUser())); + holder.mUserView.setText(recentList.get(position).getLastUser()); holder.topic = recentList.get(position); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java index ce940cd2..3191cbb9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/recent/RecentFragment.java @@ -99,7 +99,7 @@ public class RecentFragment extends BaseFragment { recentAdapter = new RecentAdapter(getActivity(), topicSummaries, fragmentInteractionListener); CustomRecyclerView recyclerView = rootView.findViewById(R.id.list); - LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext()); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(recyclerView.getContext()); recyclerView.setLayoutManager(linearLayoutManager); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation()); @@ -107,6 +107,8 @@ public class RecentFragment extends BaseFragment { recyclerView.setAdapter(recentAdapter); swipeRefreshLayout = rootView.findViewById(R.id.swiperefresh); + swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.primary); + swipeRefreshLayout.setColorSchemeResources(R.color.accent); swipeRefreshLayout.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override @@ -161,11 +163,20 @@ public class RecentFragment extends BaseFragment { throw new ParseException("Parsing failed (lastUser)"); String dateTime = recent.get(i + 2).text(); - pattern = Pattern.compile("\\[(.*)\\]"); + pattern = Pattern.compile("\\[(.*)]"); matcher = pattern.matcher(dateTime); - if (matcher.find()) + if (matcher.find()) { dateTime = matcher.group(1); - else + if (dateTime.contains(" am") || dateTime.contains(" pm") || + dateTime.contains(" πμ") || dateTime.contains(" μμ")) { + dateTime = dateTime.replaceAll(":[0-5][0-9] ", " "); + } else { + dateTime=dateTime.substring(0,dateTime.lastIndexOf(":")); + } + if (!dateTime.contains(",")) { + dateTime = dateTime.replaceAll(".+? ([0-9])", "$1"); + } + } else throw new ParseException("Parsing failed (dateTime)"); topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java index 3aedfd07..4b7c235b 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadAdapter.java @@ -67,7 +67,7 @@ class UnreadAdapter extends RecyclerView.Adapter { viewHolder.mTitleView.setText(unreadList.get(holder.getAdapterPosition()).getSubject()); viewHolder.mDateTimeView.setText(unreadList.get(holder.getAdapterPosition()).getDateTimeModified()); - viewHolder.mUserView.setText(context.getString(R.string.byUser, unreadList.get(position).getLastUser())); + viewHolder.mUserView.setText(unreadList.get(position).getLastUser()); viewHolder.topic = unreadList.get(holder.getAdapterPosition()); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java index 5fec960f..0141f646 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/main/unread/UnreadFragment.java @@ -111,7 +111,7 @@ public class UnreadFragment extends BaseFragment { }); CustomRecyclerView recyclerView = rootView.findViewById(R.id.list); - LinearLayoutManager linearLayoutManager = new LinearLayoutManager(rootView.findViewById(R.id.list).getContext()); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(recyclerView.getContext()); recyclerView.setLayoutManager(linearLayoutManager); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation()); @@ -119,6 +119,8 @@ public class UnreadFragment extends BaseFragment { recyclerView.setAdapter(unreadAdapter); swipeRefreshLayout = rootView.findViewById(R.id.swiperefresh); + swipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.primary); + swipeRefreshLayout.setColorSchemeResources(R.color.accent); swipeRefreshLayout.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override @@ -172,6 +174,10 @@ public class UnreadFragment extends BaseFragment { dateTime = dateTime.substring(0, dateTime.indexOf("
    ")); dateTime = dateTime.replace("", ""); dateTime = dateTime.replace("", ""); + dateTime = dateTime.replaceAll(":[0-5][0-9] ", " "); + if (!dateTime.contains(",")) { + dateTime = dateTime.replaceAll(".+? ([0-9])", "$1"); + } topicSummaries.add(new TopicSummary(link, title, lastUser, dateTime)); } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java index 24600df5..a83fc610 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/ProfileActivity.java @@ -172,7 +172,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment ThmmyPage.PageCategory target = ThmmyPage.resolvePageCategory(Uri.parse(profileUrl)); if (!target.is(ThmmyPage.PageCategory.PROFILE)) { - Timber.e("Bundle came with a non profile url!\nUrl:\n%s" , profileUrl); + Timber.e("Bundle came with a non profile url!\nUrl:\n%s", profileUrl); Toast.makeText(this, "An error has occurred\n Aborting.", Toast.LENGTH_SHORT).show(); finish(); } @@ -217,6 +217,7 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment //Class variables Document profilePage; Spannable usernameSpan; + Boolean isOnline = false; protected void onPreExecute() { progressBar.setVisibility(ProgressBar.VISIBLE); @@ -261,13 +262,17 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); usernameSpan.setSpan(new RelativeSizeSpan(0.45f) , 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + if (contentsTable.toString().contains("Online") || contentsTable.toString().contains("Συνδεδεμένος")) { - usernameSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#4CAF50")) - , 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } else - usernameSpan.setSpan(new ForegroundColorSpan(Color.GRAY) - , 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + isOnline = true; + } else { + isOnline = false; + /*usernameSpan.setSpan(new ForegroundColorSpan(Color.GRAY) + , 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);*/ + } + usernameSpan.setSpan(new ForegroundColorSpan(Color.parseColor("#26A69A")) + , 2, usernameSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } return true; } catch (SSLHandshakeException e) { @@ -290,8 +295,14 @@ public class ProfileActivity extends BaseActivity implements LatestPostsFragment if (pmFAB.getVisibility() != View.GONE) pmFAB.setEnabled(true); progressBar.setVisibility(ProgressBar.INVISIBLE); - if (usernameSpan != null) usernameView.setText(usernameSpan); - else if (usernameView.getText() != username) usernameView.setText(username); + if (usernameSpan != null) { + if (isOnline) { + usernameView.setTextColor(Color.parseColor("#4CAF50")); + } else { + usernameView.setTextColor(Color.GRAY); + } + usernameView.setText(usernameSpan); + } else if (usernameView.getText() != username) usernameView.setText(username); if (thumbnailUrl != null && !Objects.equals(thumbnailUrl, "")) //noinspection ConstantConditions Picasso.with(getApplicationContext()) diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java index 9a2696ac..b7162495 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsAdapter.java @@ -21,6 +21,7 @@ import me.zhanghai.android.materialprogressbar.MaterialProgressBar; * specified {@link LatestPostsFragment.LatestPostsFragmentInteractionListener}. */ class LatestPostsAdapter extends RecyclerView.Adapter { + private final int VIEW_TYPE_EMPTY = -1; private final int VIEW_TYPE_ITEM = 0; private final int VIEW_TYPE_LOADING = 1; final private LatestPostsFragment.LatestPostsFragmentInteractionListener interactionListener; @@ -38,11 +39,17 @@ class LatestPostsAdapter extends RecyclerView.Adapter { @Override public int getItemViewType(int position) { + if (parsedTopicSummaries.get(position) == null && position == 0) return VIEW_TYPE_EMPTY; return parsedTopicSummaries.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_EMPTY) { + View view = LayoutInflater.from(parent.getContext()). + inflate(R.layout.fragment_latest_posts_empty_message, parent, false); + return new RecyclerView.ViewHolder(view){}; + } if (viewType == VIEW_TYPE_ITEM) { View view = LayoutInflater.from(parent.getContext()). inflate(R.layout.fragment_latest_posts_row, parent, false); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java index 11cb671e..a8d75451 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/latestPosts/LatestPostsFragment.java @@ -50,6 +50,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap private LatestPostsTask profileLatestPostsTask; private MaterialProgressBar progressBar; private boolean isLoadingMore; + private boolean userHasPosts = true; private static final int visibleThreshold = 5; private int lastVisibleItem, totalItemCount; @@ -100,7 +101,8 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap totalItemCount = layoutManager.getItemCount(); lastVisibleItem = layoutManager.findLastVisibleItemPosition(); - if (!isLoadingMore && totalItemCount <= (lastVisibleItem + visibleThreshold)) { + if (userHasPosts && !isLoadingMore && + totalItemCount <= (lastVisibleItem + visibleThreshold)) { isLoadingMore = true; onLoadMore(); } @@ -126,7 +128,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - if (parsedTopicSummaries.isEmpty()) { + if (parsedTopicSummaries.isEmpty() && userHasPosts) { profileLatestPostsTask = new LatestPostsTask(); profileLatestPostsTask.execute(profileUrl + ";sa=showPosts"); pagesLoaded = 1; @@ -186,6 +188,7 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap //TODO: better parse error handling (ParseException etc.) private boolean parseLatestPosts(Document latestPostsPage) { + //td:contains( Sorry, no matches were found) Elements latestPostsRows = latestPostsPage. select("td:has(table:Contains(Show Posts)):not([style]) > table"); if (latestPostsRows.isEmpty()) { @@ -197,6 +200,13 @@ public class LatestPostsFragment extends BaseFragment implements LatestPostsAdap parsedTopicSummaries.remove(parsedTopicSummaries.size() - 1); } + if (!latestPostsRows.select("td:contains(Sorry, no matches were found)").isEmpty() || + !latestPostsRows.select("td:contains(Δυστυχώς δεν βρέθηκε τίποτα)").isEmpty()){ + userHasPosts = false; + parsedTopicSummaries.add(null); + return true; + } + for (Element row : latestPostsRows) { String pTopicUrl, pTopicTitle, pDateTime, pPost; if (Integer.parseInt(row.attr("cellpadding")) == 4) { diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java index fc1867c0..5822d635 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/profile/stats/StatsFragment.java @@ -56,6 +56,7 @@ public class StatsFragment extends Fragment { private MaterialProgressBar progressBar; private boolean haveParsed = false; + private boolean userHasPosts = true; private String generalStatisticsTitle = "", generalStatistics = "", postingActivityByTimeTitle = "", mostPopularBoardsByPostsTitle = "", mostPopularBoardsByActivityTitle = ""; final private List postingActivityByTime = new ArrayList<>(); final private List mostPopularBoardsByPosts = new ArrayList<>(), mostPopularBoardsByActivity = new ArrayList<>(); @@ -123,6 +124,7 @@ public class StatsFragment extends Fragment { * as String parameter!

    */ private class ProfileStatsTask extends AsyncTask { + @Override protected void onPreExecute() { progressBar.setVisibility(ProgressBar.VISIBLE); @@ -160,14 +162,23 @@ public class StatsFragment extends Fragment { } private boolean parseStats(Document statsPage) { + //Doesn't go through all the parsing if this user has no posts + if (!statsPage.select("td:contains(No posts to speak of!)").isEmpty()) { + userHasPosts = false; + } + if (!statsPage.select("td:contains(Δεν υπάρχει καμία αποστολή μηνύματος!)").isEmpty()) { + userHasPosts = false; + } if (statsPage.select("table.bordercolor[align]>tbody>tr").size() != 6) return false; { Elements titleRows = statsPage.select("table.bordercolor[align]>tbody>tr.titlebg"); generalStatisticsTitle = titleRows.first().text(); - postingActivityByTimeTitle = titleRows.get(1).text(); - mostPopularBoardsByPostsTitle = titleRows.last().select("td").first().text(); - mostPopularBoardsByActivityTitle = titleRows.last().select("td").last().text(); + if (userHasPosts) { + postingActivityByTimeTitle = titleRows.get(1).text(); + mostPopularBoardsByPostsTitle = titleRows.last().select("td").first().text(); + mostPopularBoardsByActivityTitle = titleRows.last().select("td").last().text(); + } } { Elements statsRows = statsPage.select("table.bordercolor[align]>tbody>tr:not(.titlebg)"); @@ -177,39 +188,41 @@ public class StatsFragment extends Fragment { generalStatistics += generalStatisticsRow.text() + "\n"; generalStatistics = generalStatistics.trim(); } - { - Elements postingActivityByTimeCols = statsRows.get(1).select(">td").last() - .select("tr").first().select("td[width=4%]"); - int i = -1; - for (Element postingActivityByTimeColumn : postingActivityByTimeCols) { - postingActivityByTime.add(new Entry(++i, Float.parseFloat(postingActivityByTimeColumn - .select("img").first().attr("height")))); + if (userHasPosts) { + { + Elements postingActivityByTimeCols = statsRows.get(1).select(">td").last() + .select("tr").first().select("td[width=4%]"); + int i = -1; + for (Element postingActivityByTimeColumn : postingActivityByTimeCols) { + postingActivityByTime.add(new Entry(++i, Float.parseFloat(postingActivityByTimeColumn + .select("img").first().attr("height")))); + } } - } - { - Elements mostPopularBoardsByPostsRows = statsRows.last().select(">td").get(1) - .select(">table>tbody>tr"); - int i = mostPopularBoardsByPostsRows.size(); - for (Element mostPopularBoardsByPostsRow : mostPopularBoardsByPostsRows) { - Elements dataCols = mostPopularBoardsByPostsRow.select("td"); - mostPopularBoardsByPosts.add(new BarEntry(--i, - Integer.parseInt(dataCols.last().text()))); - mostPopularBoardsByPostsLabels.add(dataCols.first().text()); + { + Elements mostPopularBoardsByPostsRows = statsRows.last().select(">td").get(1) + .select(">table>tbody>tr"); + int i = mostPopularBoardsByPostsRows.size(); + for (Element mostPopularBoardsByPostsRow : mostPopularBoardsByPostsRows) { + Elements dataCols = mostPopularBoardsByPostsRow.select("td"); + mostPopularBoardsByPosts.add(new BarEntry(--i, + Integer.parseInt(dataCols.last().text()))); + mostPopularBoardsByPostsLabels.add(dataCols.first().text()); + } + Collections.reverse(mostPopularBoardsByPostsLabels); } - Collections.reverse(mostPopularBoardsByPostsLabels); - } - { - Elements mostPopularBoardsByActivityRows = statsRows.last().select(">td").last() - .select(">table>tbody>tr"); - int i = mostPopularBoardsByActivityRows.size(); - for (Element mostPopularBoardsByActivityRow : mostPopularBoardsByActivityRows) { - Elements dataCols = mostPopularBoardsByActivityRow.select("td"); - String tmp = dataCols.last().text(); - mostPopularBoardsByActivity.add(new BarEntry(--i, - Float.parseFloat(tmp.substring(0, tmp.indexOf("%"))))); - mostPopularBoardsByActivityLabels.add(dataCols.first().text()); + { + Elements mostPopularBoardsByActivityRows = statsRows.last().select(">td").last() + .select(">table>tbody>tr"); + int i = mostPopularBoardsByActivityRows.size(); + for (Element mostPopularBoardsByActivityRow : mostPopularBoardsByActivityRows) { + Elements dataCols = mostPopularBoardsByActivityRow.select("td"); + String tmp = dataCols.last().text(); + mostPopularBoardsByActivity.add(new BarEntry(--i, + Float.parseFloat(tmp.substring(0, tmp.indexOf("%"))))); + mostPopularBoardsByActivityLabels.add(dataCols.first().text()); + } + Collections.reverse(mostPopularBoardsByActivityLabels); } - Collections.reverse(mostPopularBoardsByActivityLabels); } } return true; @@ -221,6 +234,13 @@ public class StatsFragment extends Fragment { .setText(generalStatisticsTitle); ((TextView) mainContent.findViewById(R.id.general_statistics)) .setText(generalStatistics); + + if (!userHasPosts) { + mainContent.removeViews(2, mainContent.getChildCount() - 2); + //mainContent.removeViews(2, 6); + return; + } + ((TextView) mainContent.findViewById(R.id.posting_activity_by_time_title)) .setText(postingActivityByTimeTitle); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java index 3fe99911..cc08f17d 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/Posting.java @@ -1,14 +1,9 @@ package gr.thmmy.mthmmy.activities.topic; -import android.util.Log; - import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; import okhttp3.Response; import timber.log.Timber; @@ -86,232 +81,4 @@ class Posting { } return REPLY_STATUS.SUCCESSFUL; } - - /** - * This is a fucked up method.. Just don't waste your time here unless you have suicidal - * tendencies. - * - * @param html the html string to be transformed to BBcode - * @return the BBcode string - */ - static String htmlToBBcode(String html) { - Log.d("Cancer", html); - Map bbMap = new HashMap<>(); - Map smileysMap1 = new HashMap<>(); - Map smileysMap2 = new HashMap<>(); - - smileysMap1.put("Smiley", ":)"); - smileysMap1.put("Wink", ";)"); - smileysMap1.put("Cheesy", ":D"); - smileysMap1.put("Grin", ";D"); - smileysMap1.put("Angry", ">:("); - smileysMap1.put("Sad", ":("); - smileysMap1.put("Shocked", ":o"); - smileysMap1.put("Cool", "8))"); - smileysMap1.put("Huh", ":???:"); - smileysMap1.put("Roll Eyes", "::)"); - smileysMap1.put("Tongue", ":P"); - smileysMap1.put("Embarrassed", ":-["); - smileysMap1.put("Lips Sealed", ":-X"); - smileysMap1.put("Kiss", ":-*"); - smileysMap1.put("Cry", ":'("); - smileysMap1.put("heart", "<3"); - smileysMap1.put("kleidaria", "^locked^"); - smileysMap1.put("roll_over", "^rollover^"); - smileysMap1.put("redface", "^redface^"); - smileysMap1.put("confused", "^confused^"); - smileysMap1.put("innocent", "^innocent^"); - smileysMap1.put("sleep", "^sleep^"); - smileysMap1.put("lips_sealed", "^sealed^"); - smileysMap1.put("cool", "^cool^"); - smileysMap1.put("crazy", "^crazy^"); - smileysMap1.put("mad", "^mad^"); - smileysMap1.put("wav", "^wav^"); - smileysMap1.put("BinkyBaby", "^binkybaby^"); - smileysMap1.put("DontKnow", "^dontknow^"); - smileysMap1.put("angry4", ":angry4:"); - smileysMap1.put("angryAndHot", "^angryhot^"); - smileysMap1.put("angry", "^angry^"); - smileysMap1.put("bang_head", "^banghead^"); - smileysMap1.put("CryBaby", "^crybaby^"); - smileysMap1.put("Hello", "^hello^"); - smileysMap1.put("jerk", "^jerk^"); - smileysMap1.put("NoNo", "^nono^"); - smileysMap1.put("NotWorthy", "^notworthy^"); - smileysMap1.put("Off-topic", "^off-topic^"); - smileysMap1.put("Puke", "^puke^"); - smileysMap1.put("Shout", "^shout^"); - smileysMap1.put("Slurp", "^slurp^"); - smileysMap1.put("SuperConfused", "^superconfused^"); - smileysMap1.put("SuperInnocent", "^superinnocent^"); - smileysMap1.put("CellPhone", "^cellPhone^"); - smileysMap1.put("Idiot", "^idiot^"); - smileysMap1.put("Knuppel", "^knuppel^"); - smileysMap1.put("TickedOff", "^tickedOff^"); - smileysMap1.put("Peace", "^peace^"); - smileysMap1.put("Suspicious", "^suspicious^"); - smileysMap1.put("Caffine", "^caffine^"); - smileysMap1.put("argue", "^argue^"); - smileysMap1.put("banned2", "^banned2^"); - smileysMap1.put("banned", "^banned^"); - smileysMap1.put("bath", "^bath^"); - smileysMap1.put("beg", "^beg^"); - smileysMap1.put("bluescreen", "^bluescreen^"); - smileysMap1.put("boil", "^boil^"); - smileysMap1.put("bye", "^bye^"); - smileysMap1.put("callmerip", "^callmerip^"); - smileysMap1.put("carnaval", "^carnaval^"); - smileysMap1.put("clap", "^clap^"); - smileysMap1.put("coffepot", "^coffepot^"); - smileysMap1.put("crap", "^crap^"); - smileysMap1.put("curses", "^curses^"); - smileysMap1.put("funny", "^funny^"); - smileysMap1.put("guitar", "^guitar^"); - smileysMap1.put("kissy", "^kissy^"); - smileysMap1.put("band", "^band^"); - smileysMap1.put("ivres", "^ivres^"); - smileysMap1.put("kaloe", "^kaloe^"); - smileysMap1.put("kremala", "^kremala^"); - smileysMap1.put("moon", "^moon^"); - smileysMap1.put("mopping", "^mopping^"); - smileysMap1.put("mountza", "^mountza^"); - smileysMap1.put("pcsleep", "^pcsleep^"); - smileysMap1.put("pinokio", "^pinokio^"); - smileysMap1.put("poke", "^poke^"); - smileysMap1.put("seestars", "^seestars^"); - smileysMap1.put("sfyri", "^sfyri^"); - smileysMap1.put("spam", "^spam^"); - smileysMap1.put("super", "^super^"); - smileysMap1.put("tafos", "^tafos^"); - smileysMap1.put("tomato", "^tomato^"); - smileysMap1.put("ytold", "^ytold^"); - smileysMap1.put("beer", "^beer^"); - smileysMap1.put("ο fritz!!!", "^fritz^"); - smileysMap1.put("o Wade!!!", "^wade^"); - smileysMap1.put("bonjour", "^hat^"); - smileysMap1.put("bonjour2", "^miss^"); - smileysMap1.put("question", "^que^"); - smileysMap1.put("shifty", "^shifty^"); - smileysMap1.put("shy", "^shy^"); - smileysMap1.put("music_listenning", "^music_listen^"); - smileysMap1.put("bag_face", "^bagface^"); - smileysMap1.put("rotation", "^rotate^"); - smileysMap1.put("love", "^love^"); - smileysMap1.put("speech", "^speech^"); - smileysMap1.put("shocked", "^shocked^"); - smileysMap1.put("extremely_shocked", "^ex_shocked^"); - smileysMap1.put("smurf", "^smurf^"); - smileysMap1.put("monster", "^monster^"); - smileysMap1.put("pig", "^pig^"); - smileysMap1.put("lol", "^lol^"); - - smileysMap2.put("Police", "^Police^"); - smileysMap2.put("foyska", "^fouska^"); - smileysMap2.put("nista", "^nysta^"); - smileysMap2.put("10_7_3", "^sfinaki^"); - smileysMap2.put("yu", "^yue^"); - smileysMap2.put("a-eatpaper", "^eatpaper^"); - smileysMap2.put("lypi", "^lypi^"); - smileysMap2.put("megashok1wq", "^aytoxeir^"); - smileysMap2.put("victory", "^victory^"); - smileysMap2.put("filarakia", "^filarakia^"); - smileysMap2.put("rofl", "^rolfmao^"); - smileysMap2.put("locked", "^lock^"); - smileysMap2.put("facepalm", "^facepalm^"); - - //html stuff on the beginning - bbMap.put("\n ", ""); - //quotes and code headers - bbMap.put("\\s*?
    (.*?(\\n))*?.*?<\\/div>", ""); - bbMap.put("\\s*?
    (.*?(\\n))+?.*?<\\/div>", ""); - bbMap.put("\\s*?
    (.*?(\\n))+?.*?<\\/div>", ""); - bbMap.put("
    ", "\\\n"); - //Non-breaking space - bbMap.put(" ", " "); - //bold - bbMap.put("\\s*?([\\S\\s]+?)<\\/b>", "\\[b\\]$1\\[/b\\]"); - //italics - bbMap.put("\\s*?([\\S\\s]+?)<\\/i>", "\\[i\\]$1\\[/i\\]"); - //underline - bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[u\\]$1\\[/u\\]"); - //deleted - bbMap.put("\\s*?([\\S\\s]+?)<\\/del>", "\\[s\\]$1\\[/s\\]"); - //text color - bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[color=$1\\]$2\\[/color\\]"); - //glow - bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[glow=$1,2,300\\]$2\\[/glow\\]"); - //shadow - bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[shadow=$1,$2\\]$3\\[/shadow\\]"); - //running text - bbMap.put("\\s*?\n ([\\S\\s]+?)\n <\\/marquee>", "\\[move\\]$1\\[/move\\]"); - //alignment - bbMap.put("\\s*?
    \n ([\\S\\s]+?)\n <\\/div>", "\\[center\\]$1\\[/center\\]"); - bbMap.put("\\s*?
    \n ([\\S\\s]+?)\n <\\/div>", "\\[$1\\]$2\\[/$1\\]"); - //preformated - bbMap.put("\\s*?
    ([\\S\\s]+?)<\\/pre>", "\\[pre\\]$1\\[/pre\\]");
    -        //horizontal rule
    -        bbMap.put("\\s*?
    ", "\\[hr\\]"); - //resize - bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[size=$1\\]$3\\[/size\\]"); - //font - bbMap.put("\\s*?([\\S\\s]+?)<\\/span>", "\\[font=$1\\]$2\\[/font\\]"); - //lists - bbMap.put("\\s+
  • (.+?)<\\/li>", "\\[li\\]$1\\[/li\\]"); - bbMap.put("\n\\s+
      ([\\S\\s]+?)\n\\s+<\\/ul>", - "\\[list\\]\n$1\n\\[/list\\]"); - //latex code - bbMap.put("\\s*?", "\\[tex\\]$1\\[/tex\\]"); - //code - bbMap.put("\\s*?
      ((.*?(\\n))+?.*?)<\\/div>", "\\[code\\]$1\\[/code\\]"); - //teletype - bbMap.put("\\s*?([\\S\\s]+?)<\\/tt>", "\\[tt\\]$1\\[/tt\\]"); - //superscript/subscript - bbMap.put("\\s*?([\\S\\s]+?)<\\/sub>", "\\[sub\\]$1\\[/sub\\]"); - bbMap.put("\\s*?([\\S\\s]+?)<\\/sup>", "\\[sup\\]$1\\[/sup\\]"); - //tables - bbMap.put("\\s*?([\\S\\s]+?)<\\/td>", "\\[td\\]$1\\[/td\\]"); - bbMap.put("([\\S\\s]+?)\n <\\/tr>", "\\[tr\\]$1\\[/tr\\]"); - bbMap.put("\\s*?\n \n ([\\S\\s]+?)\n <\\/tbody>\n <\\/table>" - , "\\[table\\]$2\\[/table\\]"); - //videos - bbMap.put("\\s*?
      .+?watch\\?v=(.+?)\"((.|\\n)*?)/div>\n", - "[youtube]https://www.youtube.com/watch?v=$1[/youtube]"); - //ftp - bbMap.put("([\\S\\s]+?)<\\/a>", "\\[fpt=ftp:$1\\]$2\\[/ftp\\]"); - //mailto - bbMap.put("\\s*?([\\S\\s]+?)<\\/a>", "\\[email\\]$2\\[/email\\]"); - //links - bbMap.put("\\s*?([\\S\\s]+?)", "\\[url=$1\\]$2\\[/url\\]"); - //smileys - for (Map.Entry entry : smileysMap1.entrySet()) { - bbMap.put("\n \""", entry.getValue().toString()); - } - for (Map.Entry entry : smileysMap2.entrySet()) { //Those that have empty alt tag - bbMap.put("\n ", entry.getValue().toString()); - } - - bbMap.put("\n \"Undecided\"" - , Matcher.quoteReplacement(":-\\")); - - //html stuff on the end - bbMap.put("\n
      ", ""); - - for (Map.Entry entry : bbMap.entrySet()) { - html = html.replaceAll(entry.getKey().toString(), entry.getValue().toString()); - } - - //img need to be done last or it messes up everything else - html = html.replaceAll("\\s+", - "\\[img width=$2 height=$3\\]$1\\[/img\\]"); - html = html.replaceAll("\\s+", - "\\[img height=$2 width=$3\\]$1\\[/img\\]"); - html = html.replaceAll("\\s+", "\\[img width=$2\\]$1\\[/img\\]"); - html = html.replaceAll("\\s+", "\\[img height=$2\\]$1\\[/img\\]"); - html = html.replaceAll("\\s+", "\\[img\\]$1\\[/img\\]"); - - Log.d("Cancer", html); - return html; - } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java index d95b5a7d..ecffb2f2 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicActivity.java @@ -65,13 +65,14 @@ import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_ import static gr.thmmy.mthmmy.activities.topic.Posting.replyStatus; /** - * Activity for topics. When creating an Intent of this activity you need to bundle a String - * containing this topics's url using the key {@link #BUNDLE_TOPIC_URL} and a String containing - * this topic's title using the key {@link #BUNDLE_TOPIC_TITLE}. + * Activity for parsing and rendering topics. When creating an Intent of this activity you need to + * bundle a String containing this topic's url using the key {@link #BUNDLE_TOPIC_URL}. + * You can also bundle a String containing this topic's title, if its available, using the + * key {@link #BUNDLE_TOPIC_TITLE} for faster title rendering. */ @SuppressWarnings("unchecked") public class TopicActivity extends BaseActivity { - //Class variables + //Activity's variables /** * The key to use when putting topic's url String to {@link TopicActivity}'s Bundle. */ @@ -81,46 +82,110 @@ public class TopicActivity extends BaseActivity { */ public static final String BUNDLE_TOPIC_TITLE = "TOPIC_TITLE"; private static TopicTask topicTask; - //About posts + private MaterialProgressBar progressBar; + private TextView toolbarTitle; + /** + * Holds this topic's base url. For example a topic with url similar to + * "https://www.thmmy.gr/smf/index.php?topic=1.15;topicseen" or + * "https://www.thmmy.gr/smf/index.php?topic=1.msg1#msg1" + * has the base url "https://www.thmmy.gr/smf/index.php?topic=1" + */ + private static String base_url = ""; + /** + * Holds this topic's title. At first this gets the value of the topic title that came with + * bundle and is rendered in the toolbar while parsing this topic. Later, after topic's parsing + * is done, it gets the value of {@link #parsedTitle} if bundle title and parsed title differ. + */ + private String topicTitle; + /** + * Holds this topic's title as parsed from the html source. If this (parsed) title is different + * than the one that came with activity's bundle then the parsed title is preferred over the + * bundle one and gets rendered in the toolbar. + */ + private String parsedTitle; + private RecyclerView recyclerView; + /** + * Holds the url of this page + */ + private String loadedPageUrl = ""; + /** + * Becomes true after user has posted in this topic and the page is being reloaded and false + * when topic's reloading is done + */ + private boolean reloadingPage = false; + //Posts related private TopicAdapter topicAdapter; + /** + * Holds a list of this topic's posts + */ private ArrayList postsList; + /** + * Gets assigned to {@link #postFocus} when there is no post focus information in the url + */ private static final int NO_POST_FOCUS = -1; + /** + * Holds the index of the post that has focus + */ private int postFocus = NO_POST_FOCUS; + /** + * Holds the position in the {@link #postsList} of the post with focus + */ private static int postFocusPosition = 0; - //Reply + //Reply related private FloatingActionButton replyFAB; + /** + * Holds this topic's reply url + */ private String replyPageUrl = null; - //Topic's pages + //Topic's pages related + /** + * Holds current page's index (starting from 1, not 0) + */ private int thisPage = 1; + /** + * Holds this topic's number of pages + */ private int numberOfPages = 1; + /** + * Holds a list of this topic's pages urls + */ private final SparseArray pagesUrls = new SparseArray<>(); - //Page select + //Page select related + /** + * Used for handling bottom navigation bar's buttons long click user interactions + */ private final Handler repeatUpdateHandler = new Handler(); + /** + * Holds the initial time delay before a click on bottom navigation bar is considered long + */ private final long INITIAL_DELAY = 500; private boolean autoIncrement = false; private boolean autoDecrement = false; + /** + * Holds the number of pages to be added or subtracted from current page on each step while a + * long click is held in either next or previous buttons + */ private static final int SMALL_STEP = 1; + /** + * Holds the number of pages to be added or subtracted from current page on each step while a + * long click is held in either first or last buttons + */ private static final int LARGE_STEP = 10; + /** + * Holds the value (index) of the page to be requested when a user interaction with bottom + * navigation bar occurs + */ private Integer pageRequestValue; - //Bottom navigation graphics + //Bottom navigation bar graphics related private LinearLayout bottomNavBar; private ImageButton firstPage; private ImageButton previousPage; private TextView pageIndicator; private ImageButton nextPage; private ImageButton lastPage; - //Topic's info + //Topic's info related private SpannableStringBuilder topicTreeAndMods = new SpannableStringBuilder("Loading..."), topicViewers = new SpannableStringBuilder("Loading..."); - //Other variables - private MaterialProgressBar progressBar; - private TextView toolbarTitle; - private static String base_url = ""; - private String topicTitle; - private String parsedTitle; - private RecyclerView recyclerView; - private String loadedPageUrl = ""; - private boolean reloadingPage = false; @Override @@ -149,6 +214,7 @@ public class TopicActivity extends BaseActivity { toolbarTitle.setMarqueeRepeatLimit(-1); toolbarTitle.setText(topicTitle); toolbarTitle.setSelected(true); + toolbarTitle.setEnabled(false); setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); @@ -171,6 +237,7 @@ public class TopicActivity extends BaseActivity { new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { + v.performClick(); return topicTask != null && topicTask.getStatus() == AsyncTask.Status.RUNNING; } } @@ -179,7 +246,7 @@ public class TopicActivity extends BaseActivity { CustomLinearLayoutManager layoutManager = new CustomLinearLayoutManager( getApplicationContext(), loadedPageUrl); recyclerView.setLayoutManager(layoutManager); - topicAdapter = new TopicAdapter(this, postsList, topicTask); + topicAdapter = new TopicAdapter(this, postsList, base_url, topicTask); recyclerView.setAdapter(topicAdapter); replyFAB = findViewById(R.id.topic_fab); @@ -191,12 +258,8 @@ public class TopicActivity extends BaseActivity { @Override public void onClick(View view) { if (sessionManager.isLoggedIn()) { - postsList.add(null); - topicAdapter.notifyItemInserted(postsList.size()); - topicAdapter.prepareForReply(new ReplyTask(), topicTitle, loadedPageUrl); - replyFAB.hide(); - bottomNavBar.setVisibility(View.GONE); - recyclerView.scrollToPosition(postsList.size() - 1); + PrepareForReply prepareForReply = new PrepareForReply(); + prepareForReply.execute(topicAdapter.getToQuoteList()); } } }); @@ -464,12 +527,10 @@ public class TopicActivity extends BaseActivity { //------------------------------------BOTTOM NAV BAR METHODS END------------------------------------ /** - * An {@link AsyncTask} that handles asynchronous fetching of a topic page and parsing it's - * data. {@link AsyncTask#onPostExecute(Object) OnPostExecute} method calls {@link RecyclerView#swapAdapter} - * to build graphics. - *

      - *

      Calling TopicTask's {@link AsyncTask#execute execute} method needs to have profile's url - * as String parameter!

      + * An {@link AsyncTask} that handles asynchronous fetching of this topic page and parsing of it's + * data. + *

      TopicTask's {@link AsyncTask#execute execute} method needs a topic's url as String + * parameter.

      */ class TopicTask extends AsyncTask { private static final int SUCCESS = 0; @@ -477,6 +538,8 @@ public class TopicActivity extends BaseActivity { private static final int OTHER_ERROR = 2; private static final int SAME_PAGE = 3; + ArrayList localPostsList; + @Override protected void onPreExecute() { progressBar.setVisibility(ProgressBar.VISIBLE); @@ -530,7 +593,15 @@ public class TopicActivity extends BaseActivity { try { Response response = client.newCall(request).execute(); document = Jsoup.parse(response.body().string()); - parse(document); + localPostsList = parse(document); + + //Finds the position of the focused message if present + for (int i = 0; i < localPostsList.size(); ++i) { + if (localPostsList.get(i).getPostIndex() == postFocus) { + postFocusPosition = i; + break; + } + } return SUCCESS; } catch (IOException e) { Timber.i(e, "IO Exception"); @@ -542,14 +613,6 @@ public class TopicActivity extends BaseActivity { } protected void onPostExecute(Integer parseResult) { - //Finds the position of the focused message if present - for (int i = 0; i < postsList.size(); ++i) { - if (postsList.get(i).getPostIndex() == postFocus) { - postFocusPosition = i; - break; - } - } - switch (parseResult) { case SUCCESS: if (topicTitle == null || Objects.equals(topicTitle, "") @@ -560,12 +623,19 @@ public class TopicActivity extends BaseActivity { invalidateOptionsMenu(); } + if (!(postsList.isEmpty() || postsList.size() == 0)) { + recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug + postsList.clear(); + topicAdapter.notifyItemRangeRemoved(0, postsList.size() - 1); + } + postsList.addAll(localPostsList); + topicAdapter.notifyItemRangeInserted(0, postsList.size()); progressBar.setVisibility(ProgressBar.INVISIBLE); - recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug + if (replyPageUrl == null) { replyFAB.hide(); - topicAdapter.customNotifyDataSetChanged(new TopicTask(), false); - } else topicAdapter.customNotifyDataSetChanged(new TopicTask(), true); + topicAdapter.resetTopic(base_url, new TopicTask(), false); + } else topicAdapter.resetTopic(base_url, new TopicTask(), true); if (replyFAB.getVisibility() != View.GONE) replyFAB.setEnabled(true); @@ -582,8 +652,8 @@ public class TopicActivity extends BaseActivity { progressBar.setVisibility(ProgressBar.INVISIBLE); if (replyPageUrl == null) { replyFAB.hide(); - topicAdapter.customNotifyDataSetChanged(new TopicTask(), false); - } else topicAdapter.customNotifyDataSetChanged(new TopicTask(), true); + topicAdapter.resetTopic(base_url, new TopicTask(), false); + } else topicAdapter.resetTopic(base_url, new TopicTask(), true); if (replyFAB.getVisibility() != View.GONE) replyFAB.setEnabled(true); paginationEnabled(true); Toast.makeText(TopicActivity.this, "That's the same page.", Toast.LENGTH_SHORT).show(); @@ -604,7 +674,7 @@ public class TopicActivity extends BaseActivity { * @param topic {@link Document} object containing this topic's source code * @see org.jsoup.Jsoup Jsoup */ - private void parse(Document topic) { + private ArrayList parse(Document topic) { ParseHelpers.Language language = ParseHelpers.Language.getLanguage(topic); //Finds topic's tree, mods and users viewing @@ -646,11 +716,7 @@ public class TopicActivity extends BaseActivity { } } - postsList.clear(); - int oldSize = postsList.size(); - topicAdapter.notifyItemRangeRemoved(0, oldSize); - recyclerView.getRecycledViewPool().clear(); //Avoid inconsistency detected bug - postsList.addAll(TopicParser.parseTopic(topic, language)); + return TopicParser.parseTopic(topic, language); } private void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span) { @@ -703,23 +769,25 @@ public class TopicActivity extends BaseActivity { } } - class ReplyTask extends AsyncTask { + class PrepareForReply extends AsyncTask, Void, Boolean> { + String numReplies, seqnum, sc, topic, buildedQuotes = ""; @Override protected void onPreExecute() { progressBar.setVisibility(ProgressBar.VISIBLE); paginationEnabled(false); replyFAB.setEnabled(false); + replyFAB.hide(); + bottomNavBar.setVisibility(View.GONE); } @Override - protected Boolean doInBackground(String... message) { + protected Boolean doInBackground(ArrayList... quoteList) { Document document; - String numReplies, seqnum, sc, topic; - Request request = new Request.Builder() .url(replyPageUrl + ";wap2") .build(); + try { Response response = client.newCall(request).execute(); document = Jsoup.parse(response.body().string()); @@ -728,22 +796,61 @@ public class TopicActivity extends BaseActivity { seqnum = document.select("input[name=seqnum]").first().attr("value"); sc = document.select("input[name=sc]").first().attr("value"); topic = document.select("input[name=topic]").first().attr("value"); - } catch (IOException e) { - Timber.e(e, "Post failed."); - return false; - } catch (Selector.SelectorParseException e) { - Timber.e(e, "Post failed."); + } catch (IOException | Selector.SelectorParseException e) { + Timber.e(e, "Prepare failed."); return false; } + for (Integer quotePosition : quoteList[0]) { + request = new Request.Builder() + .url("https://www.thmmy.gr/smf/index.php?action=quotefast;quote=" + + postsList.get(quotePosition).getPostIndex() + + ";" + "sesc=" + sc + ";xml") + .build(); + + try { + Response response = client.newCall(request).execute(); + String body = response.body().string(); + buildedQuotes += body.substring(body.indexOf("") + 7, body.indexOf("")); + buildedQuotes += "\n\n"; + } catch (IOException | Selector.SelectorParseException e) { + Timber.e(e, "Quote building failed."); + return false; + } + } + return true; + } + + @Override + protected void onPostExecute(Boolean result) { + postsList.add(null); + topicAdapter.notifyItemInserted(postsList.size()); + topicAdapter.prepareForReply(new ReplyTask(), topicTitle, numReplies, seqnum, sc, + topic, buildedQuotes); + recyclerView.scrollToPosition(postsList.size() - 1); + progressBar.setVisibility(ProgressBar.GONE); + } + } + + class ReplyTask extends AsyncTask { + + @Override + protected void onPreExecute() { + progressBar.setVisibility(ProgressBar.VISIBLE); + paginationEnabled(false); + replyFAB.setEnabled(false); + } + + @Override + protected Boolean doInBackground(String... args) { RequestBody postBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) - .addFormDataPart("message", message[1]) - .addFormDataPart("num_replies", numReplies) - .addFormDataPart("seqnum", seqnum) - .addFormDataPart("sc", sc) - .addFormDataPart("subject", message[0]) - .addFormDataPart("topic", topic) + .addFormDataPart("message", args[1]) + .addFormDataPart("num_replies", args[2]) + .addFormDataPart("seqnum", args[3]) + .addFormDataPart("sc", args[4]) + .addFormDataPart("subject", args[0]) + .addFormDataPart("topic", args[5]) .build(); Request post = new Request.Builder() diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java index fd95cc71..8a94d901 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAdapter.java @@ -10,10 +10,8 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.support.v4.content.res.ResourcesCompat; import android.support.v7.widget.AppCompatImageButton; -import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.TextUtils; @@ -26,7 +24,6 @@ import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.EditText; -import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; @@ -35,14 +32,8 @@ import android.widget.TextView; import com.squareup.picasso.Picasso; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; import java.util.List; -import java.util.Locale; import java.util.Objects; import gr.thmmy.mthmmy.R; @@ -61,7 +52,9 @@ import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_THUMBNAIL_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_URL; import static gr.thmmy.mthmmy.activities.profile.ProfileActivity.BUNDLE_PROFILE_USERNAME; -import static gr.thmmy.mthmmy.activities.topic.Posting.htmlToBBcode; +import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; +import static gr.thmmy.mthmmy.activities.topic.TopicParser.USER_COLOR_WHITE; +import static gr.thmmy.mthmmy.activities.topic.TopicParser.USER_COLOR_YELLOW; import static gr.thmmy.mthmmy.base.BaseActivity.getSessionManager; /** @@ -74,6 +67,7 @@ class TopicAdapter extends RecyclerView.Adapter { private static int THUMBNAIL_SIZE; private final Context context; private String topicTitle; + private String baseUrl; private final ArrayList toQuoteList = new ArrayList<>(); private final List postsList; /** @@ -98,16 +92,18 @@ class TopicAdapter extends RecyclerView.Adapter { private final String[] replyDataHolder = new String[2]; private final int replySubject = 0, replyText = 1; - private String loadedPageUrl = ""; + private String numReplies, seqnum, sc, topic, buildedQuotes; private boolean canReply = false; /** * @param context the context of the {@link RecyclerView} * @param postsList List of {@link Post} objects to use */ - TopicAdapter(Context context, List postsList, TopicActivity.TopicTask topicTask) { + TopicAdapter(Context context, List postsList, String baseUrl, + TopicActivity.TopicTask topicTask) { this.context = context; this.postsList = postsList; + this.baseUrl = baseUrl; THUMBNAIL_SIZE = (int) context.getResources().getDimension(R.dimen.thumbnail_size); for (int i = 0; i < postsList.size(); ++i) { @@ -117,10 +113,19 @@ class TopicAdapter extends RecyclerView.Adapter { this.topicTask = topicTask; } - void prepareForReply(TopicActivity.ReplyTask replyTask, String topicTitle, String loadedPageUrl) { + ArrayList getToQuoteList(){ + return toQuoteList; + } + + void prepareForReply(TopicActivity.ReplyTask replyTask, String topicTitle, String numReplies, + String seqnum, String sc, String topic, String buildedQuotes) { this.replyTask = replyTask; this.topicTitle = topicTitle; - this.loadedPageUrl = loadedPageUrl; + this.numReplies = numReplies; + this.seqnum = seqnum; + this.sc = sc; + this.topic = topic; + this.buildedQuotes = buildedQuotes; } @Override @@ -158,12 +163,8 @@ class TopicAdapter extends RecyclerView.Adapter { //Default post subject replyDataHolder[replySubject] = "Re: " + topicTitle; //Build quotes - String quotes = ""; - for (int quotePosition : toQuoteList) { - quotes += buildQuote(quotePosition); - } - if (!Objects.equals(quotes, "")) - replyDataHolder[replyText] = htmlToBBcode(quotes); + if (!Objects.equals(buildedQuotes, "")) + replyDataHolder[replyText] = buildedQuotes; return new QuickReplyViewHolder(view, new CustomEditTextListener(replySubject), new CustomEditTextListener(replyText)); } @@ -309,6 +310,11 @@ class TopicAdapter extends RecyclerView.Adapter { holder.personalText.setVisibility(View.VISIBLE); } else holder.personalText.setVisibility(View.GONE); + if (mUserColor != USER_COLOR_YELLOW) { + holder.username.setTextColor(mUserColor); + } else { + holder.username.setTextColor(USER_COLOR_WHITE); + } if (mNumberOfStars > 0) { holder.stars.setTypeface(Typeface.createFromAsset(context.getAssets() , "fonts/fontawesome-webfont.ttf")); @@ -396,7 +402,7 @@ class TopicAdapter extends RecyclerView.Adapter { TopicAnimations.animateUserExtraInfoVisibility(holder.username, holder.subject, Color.parseColor("#FFFFFF"), - Color.parseColor("#757575"), v); + Color.parseColor("#757575"), (LinearLayout) v); } }); } else { @@ -460,7 +466,7 @@ class TopicAdapter extends RecyclerView.Adapter { if (holder.quickReply.getText().toString().isEmpty()) return; holder.submitButton.setEnabled(false); replyTask.execute(holder.quickReplySubject.getText().toString(), - holder.quickReply.getText().toString()); + holder.quickReply.getText().toString(), numReplies, seqnum, sc, topic); holder.quickReplySubject.getText().clear(); holder.quickReplySubject.setText("Re: " + topicTitle); @@ -471,7 +477,8 @@ class TopicAdapter extends RecyclerView.Adapter { } } - void customNotifyDataSetChanged(TopicActivity.TopicTask topicTask, boolean canReply) { + void resetTopic(String baseUrl, TopicActivity.TopicTask topicTask, boolean canReply) { + this.baseUrl = baseUrl; this.topicTask = topicTask; this.canReply = canReply; viewProperties.clear(); @@ -479,8 +486,6 @@ class TopicAdapter extends RecyclerView.Adapter { //Initializes properties, array's values will be false by default viewProperties.add(new boolean[3]); } - notifyItemRangeInserted(0, postsList.size()); - //notifyDataSetChanged(); } @Override @@ -492,9 +497,7 @@ class TopicAdapter extends RecyclerView.Adapter { * Custom {@link RecyclerView.ViewHolder} implementation */ private class PostViewHolder extends RecyclerView.ViewHolder { - final CardView cardView; final LinearLayout cardChildLinear; - final FrameLayout postDateAndNumber; final TextView postDate, postNum, username, subject; final ImageView thumbnail; final public WebView post; @@ -510,9 +513,7 @@ class TopicAdapter extends RecyclerView.Adapter { super(view); //Initializes layout's graphic elements //Standard stuff - cardView = view.findViewById(R.id.card_view); cardChildLinear = view.findViewById(R.id.card_child_linear); - postDateAndNumber = view.findViewById(R.id.post_date_and_number_exp); postDate = view.findViewById(R.id.post_date); postNum = view.findViewById(R.id.post_number); thumbnail = view.findViewById(R.id.thumbnail); @@ -544,7 +545,6 @@ class TopicAdapter extends RecyclerView.Adapter { final TextView username; final EditText quickReply, quickReplySubject; final AppCompatImageButton submitButton; - final CustomEditTextListener replySubject, replyText; QuickReplyViewHolder(View quickReply, CustomEditTextListener replySubject , CustomEditTextListener replyText) { @@ -552,10 +552,8 @@ class TopicAdapter extends RecyclerView.Adapter { thumbnail = quickReply.findViewById(R.id.thumbnail); username = quickReply.findViewById(R.id.username); this.quickReply = quickReply.findViewById(R.id.quick_reply_text); - this.replyText = replyText; this.quickReply.addTextChangedListener(replyText); quickReplySubject = quickReply.findViewById(R.id.quick_reply_subject); - this.replySubject = replySubject; quickReplySubject.addTextChangedListener(replySubject); submitButton = quickReply.findViewById(R.id.quick_reply_submit); } @@ -589,7 +587,7 @@ class TopicAdapter extends RecyclerView.Adapter { if (target.is(ThmmyPage.PageCategory.TOPIC)) { //This url points to a topic //Checks if this is the current topic - /*if (Objects.equals(uriString.substring(0, uriString.lastIndexOf(".")), base_url)) { + if (Objects.equals(uriString.substring(0, uriString.lastIndexOf(".")), baseUrl)) { //Gets uri's targeted message's index number String msgIndexReq = uriString.substring(uriString.indexOf("msg") + 3); if (msgIndexReq.contains("#")) @@ -604,9 +602,16 @@ class TopicAdapter extends RecyclerView.Adapter { return true; } } - }*/ - topicTask.execute(uri.toString()); + topicTask.execute(uri.toString()); + } + + Intent intent = new Intent(context, TopicActivity.class); + Bundle extras = new Bundle(); + extras.putString(BUNDLE_TOPIC_URL, uriString); + intent.putExtras(extras); + intent.setFlags(FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); return true; } else if (target.is(ThmmyPage.PageCategory.BOARD)) { Intent intent = new Intent(context, BoardActivity.class); @@ -660,62 +665,6 @@ class TopicAdapter extends RecyclerView.Adapter { } } - @Nullable - private String buildQuote(int quotePosition) { - Date postDate = null; - { - String date = postsList.get(quotePosition).getPostDate(); - if (date != null) { - DateFormat format = new SimpleDateFormat("MMMM d, yyyy, h:m:s a", Locale.ENGLISH); - date = date.replace("Ιανουαρίου", "January"); - date = date.replace("Φεβρουαρίου", "February"); - date = date.replace("Μαρτίου", "March"); - date = date.replace("Απριλίου", "April"); - date = date.replace("Μαΐου", "May"); - date = date.replace("Ιουνίου", "June"); - date = date.replace("Ιουλίου", "July"); - date = date.replace("Αυγούστου", "August"); - date = date.replace("Σεπτεμβρίου", "September"); - date = date.replace("Οκτωβρίου", "October"); - date = date.replace("Νοεμβρίου", "November"); - date = date.replace("Δεκεμβρίου", "December"); - - if (date.contains("Today")) { - date = date.replace("Today at", - Calendar.getInstance().getDisplayName(Calendar.MONTH, - Calendar.LONG, Locale.ENGLISH) - + " " + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - + ", " + Calendar.getInstance().get(Calendar.YEAR) + ","); - } else if (date.contains("Σήμερα")) { - date = date.replace("Σήμερα στις", - Calendar.getInstance().getDisplayName(Calendar.MONTH, - Calendar.LONG, Locale.ENGLISH) - + " " + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - + ", " + Calendar.getInstance().get(Calendar.YEAR) + ","); - if (date.contains("πμ")) date = date.replace("πμ", "am"); - if (date.contains("μμ")) date = date.replace("μμ", "pm"); - } - try { - postDate = format.parse(date); - } catch (ParseException e) { - e.printStackTrace(); - } - } - } - if (postsList.get(quotePosition).getPostIndex() != 0) { - if (postDate != null) { - return "[quote author=" + postsList.get(quotePosition).getAuthor() - + " link=topic=" + ThmmyPage.getTopicId(loadedPageUrl) + ".msg" - + postsList.get(quotePosition).getPostIndex() - + "#msg" + postsList.get(quotePosition).getPostIndex() - + " date=" + postDate.getTime() / 1000 + "]" - + "\n" + postsList.get(quotePosition).getContent() - + "\n" + "[/quote]" + "\n\n"; - } - } - return null; - } - /** * Returns a String with a single FontAwesome typeface character corresponding to this file's * extension. diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java index ae4516ef..4cabbdfb 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicAnimations.java @@ -4,68 +4,67 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.text.TextUtils; import android.view.View; +import android.widget.LinearLayout; import android.widget.TextView; class TopicAnimations { -//--------------------------USER'S INFO VISIBILITY CHANGE ANIMATION METHOD-------------------------- - /** * Method that animates view's visibility changes for user's extra info */ - static void animateUserExtraInfoVisibility(TextView username, TextView subject, - int expandedColor, int collapsedColor, - final View userExtra) { - //If the view is gone fade it in - if (userExtra.getVisibility() == View.GONE) { - userExtra.clearAnimation(); - userExtra.setVisibility(View.VISIBLE); - userExtra.setAlpha(0.0f); + static void animateUserExtraInfoVisibility(final TextView username, final TextView subject, + int expandedColor, final int collapsedColor, + final LinearLayout userExtraInfo) { + //If the view is currently gone it fades it in + if (userExtraInfo.getVisibility() == View.GONE) { + userExtraInfo.clearAnimation(); + userExtraInfo.setVisibility(View.VISIBLE); + userExtraInfo.setAlpha(0.0f); - // Start the animation - userExtra.animate() + //Animation start + userExtraInfo.animate() .alpha(1.0f) .setDuration(300) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - userExtra.setVisibility(View.VISIBLE); + userExtraInfo.setVisibility(View.VISIBLE); } }); - //Show full username + //Shows full username username.setMaxLines(Integer.MAX_VALUE); //As in the android sourcecode username.setEllipsize(null); - //Show full subject + //Shows full subject subject.setTextColor(expandedColor); subject.setMaxLines(Integer.MAX_VALUE); //As in the android sourcecode subject.setEllipsize(null); } - //If the view is visible fade it out + //If the view is currently visible then it fades it out else { - userExtra.clearAnimation(); + userExtraInfo.clearAnimation(); - // Start the animation - userExtra.animate() + //Animation start + userExtraInfo.animate() .alpha(0.0f) .setDuration(300) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - userExtra.setVisibility(View.GONE); - } - }); + userExtraInfo.setVisibility(View.GONE); - username.setMaxLines(1); //As in the android sourcecode - username.setEllipsize(TextUtils.TruncateAt.END); + //Ellipsizes username + username.setMaxLines(1); //As in the android sourcecode + username.setEllipsize(TextUtils.TruncateAt.END); - subject.setTextColor(collapsedColor); - subject.setMaxLines(1); //As in the android sourcecode - subject.setEllipsize(TextUtils.TruncateAt.END); + //Ellipsizes subject + subject.setTextColor(collapsedColor); + subject.setMaxLines(1); //As in the android sourcecode + subject.setEllipsize(TextUtils.TruncateAt.END); + } + }); } } -//------------------------POST'S INFO VISIBILITY CHANGE ANIMATION METHOD END------------------------ - } diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java index 81b1e47f..6a05d83f 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/topic/TopicParser.java @@ -35,7 +35,8 @@ class TopicParser { private static final int USER_COLOR_GREEN = Color.parseColor("#4CAF50"); private static final int USER_COLOR_BLUE = Color.parseColor("#536DFE"); static final int USER_COLOR_PINK = Color.parseColor("#FF4081"); - private static final int USER_COLOR_YELLOW = Color.parseColor("#FFEB3B"); + static final int USER_COLOR_YELLOW = Color.parseColor("#FFEB3B"); + static final int USER_COLOR_WHITE = Color.WHITE; /** * Returns users currently viewing this topic. 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 6a837038..efc78db9 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java +++ b/app/src/main/java/gr/thmmy/mthmmy/base/BaseActivity.java @@ -20,6 +20,7 @@ import android.widget.ImageButton; import android.widget.Toast; import com.mikepenz.fontawesome_typeface_library.FontAwesome; +import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.materialdrawer.AccountHeader; import com.mikepenz.materialdrawer.AccountHeaderBuilder; @@ -156,27 +157,27 @@ public abstract class BaseActivity extends AppCompatActivity { //Drawer Icons homeIcon = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_home) + .icon(GoogleMaterial.Icon.gmd_home) .color(primaryColor); homeIconSelected = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_home) + .icon(GoogleMaterial.Icon.gmd_home) .color(selectedSecondaryColor); - downloadsIcon = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_download) + bookmarksIcon = new IconicsDrawable(this) + .icon(GoogleMaterial.Icon.gmd_bookmark) .color(primaryColor); - downloadsIconSelected = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_download) + bookmarksIconSelected = new IconicsDrawable(this) + .icon(GoogleMaterial.Icon.gmd_bookmark) .color(selectedSecondaryColor); - bookmarksIcon = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_bookmark) + downloadsIcon = new IconicsDrawable(this) + .icon(GoogleMaterial.Icon.gmd_file_download) .color(primaryColor); - bookmarksIconSelected = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_bookmark) + downloadsIconSelected = new IconicsDrawable(this) + .icon(GoogleMaterial.Icon.gmd_file_download) .color(selectedSecondaryColor); loginIcon = new IconicsDrawable(this) @@ -188,11 +189,11 @@ public abstract class BaseActivity extends AppCompatActivity { .color(primaryColor); aboutIcon = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_info_circle) + .icon(GoogleMaterial.Icon.gmd_info) .color(primaryColor); aboutIconSelected = new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_info_circle) + .icon(GoogleMaterial.Icon.gmd_info) .color(selectedSecondaryColor); //Drawer Items @@ -358,14 +359,15 @@ public abstract class BaseActivity extends AppCompatActivity { { drawer.removeItem(DOWNLOADS_ID); loginLogoutItem.withName(R.string.login).withIcon(loginIcon); //Swap logout with login - profileDrawerItem.withName(sessionManager.getUsername()).withIcon(new IconicsDrawable(this) - .icon(FontAwesome.Icon.faw_user) - .paddingDp(10) - .color(ContextCompat.getColor(this, R.color.primary_light)) - .backgroundColor(ContextCompat.getColor(this, R.color.primary))); + profileDrawerItem.withName(sessionManager.getUsername()); + setDefaultAvatar(); } else { loginLogoutItem.withName(R.string.logout).withIcon(logoutIcon); //Swap login with logout - profileDrawerItem.withName(sessionManager.getUsername()).withIcon(sessionManager.getAvatarLink()); + profileDrawerItem.withName(sessionManager.getUsername()); + if(sessionManager.hasAvatar()) + profileDrawerItem.withIcon(sessionManager.getAvatarLink()); + else + setDefaultAvatar(); } accountHeader.updateProfile(profileDrawerItem); drawer.updateItem(loginLogoutItem); @@ -373,6 +375,13 @@ public abstract class BaseActivity extends AppCompatActivity { } } + private void setDefaultAvatar() { + profileDrawerItem.withIcon(new IconicsDrawable(this) + .icon(FontAwesome.Icon.faw_user) + .paddingDp(10) + .color(ContextCompat.getColor(this, R.color.primary_light)) + .backgroundColor(ContextCompat.getColor(this, R.color.primary))); + } //-------------------------------------------LOGOUT------------------------------------------------- @@ -402,6 +411,11 @@ public abstract class BaseActivity extends AppCompatActivity { if (mainActivity != null) mainActivity.updateTabs(); progressDialog.dismiss(); + //if (BaseActivity.this instanceof TopicActivity){ + Intent intent = new Intent(BaseActivity.this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + //} } } //-----------------------------------------LOGOUT END----------------------------------------------- diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java index c14387f1..a00cffb0 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -1,11 +1,13 @@ package gr.thmmy.mthmmy.services; +import android.app.DownloadManager; import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Environment; import android.support.annotation.NonNull; +import android.webkit.MimeTypeMap; import java.io.File; import java.io.FileNotFoundException; @@ -107,7 +109,7 @@ public class DownloadService extends IntentService { Response response = client.newCall(request).execute(); String contentDisposition = response.headers("Content-Disposition").toString(); //check if link provides an attachment - if (contentDisposition.contains("attachment")){ + if (contentDisposition.contains("attachment")) { fileName = contentDisposition.split("\"")[1]; File dirPath = new File(SAVE_DIR); @@ -141,7 +143,7 @@ public class DownloadService extends IntentService { fileName = file.getName(); - Timber.v("Started saving file %s" , fileName); + Timber.v("Started saving file %s", fileName); sendNotification(downloadId, STARTED, fileName); sink = Okio.buffer(Okio.sink(file)); @@ -149,6 +151,12 @@ public class DownloadService extends IntentService { sink.flush(); Timber.i("Download OK!"); sendNotification(downloadId, COMPLETED, fileName); + + // Register download + DownloadManager mManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); + long length = file.length(); + mManager.addCompletedDownload(fileName, "edo mporei na mpei ena description", false, getMimeType(file), SAVE_DIR +File.separator+ fileName, length, false); + } else Timber.e("No attachment in response!"); } catch (FileNotFoundException e) { @@ -203,4 +211,18 @@ public class DownloadService extends IntentService { } + @NonNull + static String getMimeType(@NonNull File file) { + String type = null; + final String url = file.toString(); + final String extension = MimeTypeMap.getFileExtensionFromUrl(url); + if (extension != null) { + type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase()); + } + if (type == null) { + type = ""; // fallback type. You might set it to */* + } + return type; + } + } diff --git a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java index 0d336ae3..d82e349b 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java +++ b/app/src/main/java/gr/thmmy/mthmmy/utils/ScrollAwareFABBehavior.java @@ -34,8 +34,8 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior 0 || (!target.canScrollVertically(-1) && dyConsumed == 0 - && dyUnconsumed < 40)) && child.getVisibility() == View.VISIBLE) { + if (child.getVisibility() == View.VISIBLE && (dyConsumed > 0 + || (!target.canScrollVertically(-1) && dyConsumed == 0 && dyUnconsumed > 50))) { child.hide(new FloatingActionButton.OnVisibilityChangedListener() { @Override public void onHidden(FloatingActionButton fab) { @@ -43,7 +43,8 @@ public class ScrollAwareFABBehavior extends CoordinatorLayout.Behavior int dxUnconsumed, int dyUnconsumed, int type) { super.onNestedScroll(coordinatorLayout, bottomNavBar, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type); - if ((dyConsumed > 0 || (!target.canScrollVertically(-1) && dyConsumed == 0 - && dyUnconsumed < 40)) && bottomNavBar.getVisibility() == View.VISIBLE) { + if (bottomNavBar.getVisibility() == View.VISIBLE && (dyConsumed > 0 + || (!target.canScrollVertically(-1) && dyConsumed == 0 && dyUnconsumed > 50))) { hide(bottomNavBar); - } else if (dyConsumed < 0 && bottomNavBar.getVisibility() != View.VISIBLE) { + } else if (bottomNavBar.getVisibility() == View.INVISIBLE && (dyConsumed < 0 + || (!target.canScrollVertically(-1) && dyConsumed == 0 && dyUnconsumed < -50))) { show(bottomNavBar); } } diff --git a/app/src/main/res/layout-v21/activity_topic_post_row.xml b/app/src/main/res/layout-v21/activity_topic_post_row.xml index a4c6ee2d..7f384f10 100644 --- a/app/src/main/res/layout-v21/activity_topic_post_row.xml +++ b/app/src/main/res/layout-v21/activity_topic_post_row.xml @@ -37,6 +37,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:clickable="true" + android:focusable="true" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp"> @@ -94,6 +95,7 @@ android:background="@color/card_background" android:clickable="true" android:contentDescription="@string/post_quote_button" + android:focusable="true" android:src="@drawable/ic_format_quote_unchecked" /> @@ -102,6 +104,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" + android:focusable="true" android:orientation="vertical" android:paddingLeft="16dp" android:paddingRight="16dp" @@ -174,8 +177,8 @@ android:layout_height="wrap_content" android:gravity="start" android:text="" - android:textColor="@color/card_expand_text_color" - android:textSize="10sp" /> + android:textColor="@color/accent" + android:textSize="11sp" /> + android:textColor="@color/accent" + android:textSize="11sp" /> @@ -212,6 +215,7 @@ android:layout_marginRight="16dp" android:background="@color/card_background" android:clickable="true" + android:focusable="true" android:text="@string/post" /> diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 306d2b76..020c6e03 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -1,6 +1,5 @@ - - + app:popupTheme="@style/ToolbarTheme" /> @@ -30,11 +28,10 @@ android:id="@+id/scrollview" android:layout_width="match_parent" android:layout_height="match_parent" - app:layout_behavior="@string/appbar_scrolling_view_behavior" - android:background="@color/background"> + android:background="@color/primary_light" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - - - - + android:layout_alignParentTop="true" + android:src="@mipmap/ic_launcher" + android:contentDescription="@string/logo" /> + android:textStyle="italic" /> + android:textColor="@color/iron" /> + android:textColor="@color/iron" /> @@ -139,24 +133,24 @@ android:id="@+id/contact_header" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:layout_below="@+id/mit_libs" android:layout_marginTop="20dp" - android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/contact" + android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="@color/accent" - android:layout_below="@+id/mit_libs" - android:layout_alignParentStart="true" android:textStyle="bold" /> + android:textColor="@color/iron" /> @@ -175,7 +169,6 @@ android:layout_gravity="center" android:contentDescription="@string/trollPic" android:foregroundGravity="center" - android:src="@drawable/fun" - /> + android:src="@drawable/fun" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_board_sub_board.xml b/app/src/main/res/layout/activity_board_sub_board.xml index 3b202022..6362e043 100644 --- a/app/src/main/res/layout/activity_board_sub_board.xml +++ b/app/src/main/res/layout/activity_board_sub_board.xml @@ -1,6 +1,5 @@ - + android:textSize="22sp" /> + android:src="@drawable/ic_arrow_drop_down" /> + android:textStyle="italic" /> + android:textSize="12sp" /> + android:textSize="12sp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_board_topic.xml b/app/src/main/res/layout/activity_board_topic.xml index d041cc46..141f3876 100644 --- a/app/src/main/res/layout/activity_board_topic.xml +++ b/app/src/main/res/layout/activity_board_topic.xml @@ -1,6 +1,5 @@ - + android:textSize="18sp" /> + android:src="@drawable/ic_arrow_drop_down" /> + android:textSize="12sp" /> + android:textSize="12sp" /> + android:textSize="12sp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_topic_post_row.xml b/app/src/main/res/layout/activity_topic_post_row.xml index 4581ac89..cc004897 100644 --- a/app/src/main/res/layout/activity_topic_post_row.xml +++ b/app/src/main/res/layout/activity_topic_post_row.xml @@ -37,6 +37,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:clickable="true" + android:focusable="true" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp"> @@ -93,6 +94,7 @@ android:background="@color/card_background" android:clickable="true" android:contentDescription="@string/post_quote_button" + android:focusable="true" android:src="@drawable/ic_format_quote_unchecked" /> @@ -101,6 +103,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" + android:focusable="true" android:orientation="vertical" android:paddingLeft="16dp" android:paddingRight="16dp" @@ -173,8 +176,8 @@ android:layout_height="wrap_content" android:gravity="start" android:text="" - android:textColor="@color/card_expand_text_color" - android:textSize="10sp" /> + android:textColor="@color/accent" + android:textSize="11sp" /> + android:textColor="@color/accent" + android:textSize="11sp" /> @@ -211,6 +214,7 @@ android:layout_marginRight="16dp" android:background="@color/card_background" android:clickable="true" + android:focusable="true" android:text="@string/post" /> diff --git a/app/src/main/res/layout/activity_topic_quick_reply_row.xml b/app/src/main/res/layout/activity_topic_quick_reply_row.xml index 870d0a8c..c77d3c07 100644 --- a/app/src/main/res/layout/activity_topic_quick_reply_row.xml +++ b/app/src/main/res/layout/activity_topic_quick_reply_row.xml @@ -1,6 +1,5 @@ - - @@ -53,7 +52,7 @@ android:contentDescription="@string/post_thumbnail" android:maxHeight="@dimen/thumbnail_size" android:maxWidth="@dimen/thumbnail_size" - android:src="@drawable/ic_default_user_thumbnail"/> + android:src="@drawable/ic_default_user_thumbnail" /> + android:textStyle="bold" /> + tools:ignore="SmallSp" /> + android:inputType="textMultiLine" /> + android:src="@drawable/ic_send" /> diff --git a/app/src/main/res/layout/fragment_forum_board_row.xml b/app/src/main/res/layout/fragment_forum_board_row.xml index 4fdace98..871c5450 100644 --- a/app/src/main/res/layout/fragment_forum_board_row.xml +++ b/app/src/main/res/layout/fragment_forum_board_row.xml @@ -2,19 +2,20 @@ + android:background="@color/primary_lighter" + android:orientation="vertical"> + android:padding="8dp" + android:textAppearance="?attr/textAppearanceListItem" + android:textColor="@color/accent" + android:textSize="16sp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_latest_posts_empty_message.xml b/app/src/main/res/layout/fragment_latest_posts_empty_message.xml new file mode 100644 index 00000000..54dd346b --- /dev/null +++ b/app/src/main/res/layout/fragment_latest_posts_empty_message.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_recent_row.xml b/app/src/main/res/layout/fragment_recent_row.xml index 8f256f2e..7d136a4e 100644 --- a/app/src/main/res/layout/fragment_recent_row.xml +++ b/app/src/main/res/layout/fragment_recent_row.xml @@ -38,7 +38,7 @@ android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_below="@+id/spacer" - android:textColor="@color/secondary_text"/> + android:textColor="@color/accent"/> + android:orientation="vertical"> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_unread_row.xml b/app/src/main/res/layout/fragment_unread_row.xml index 8f256f2e..7d136a4e 100644 --- a/app/src/main/res/layout/fragment_unread_row.xml +++ b/app/src/main/res/layout/fragment_unread_row.xml @@ -38,7 +38,7 @@ android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_below="@+id/spacer" - android:textColor="@color/secondary_text"/> + android:textColor="@color/accent"/> LOGIN
      Don\'t have an account? Continue as guest! - - by %1$s - Child Boards Exp/Coll @@ -51,6 +48,7 @@ Username + This user has no posts yet General Statistics Statistics Posting Activity diff --git a/build.gradle b/build.gradle index 41691e53..cee0d09e 100644 --- a/build.gradle +++ b/build.gradle @@ -4,9 +4,10 @@ buildscript { repositories { jcenter() maven { url "https://jitpack.io" } + maven { url "https://maven.google.com" } } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.0.0' classpath 'com.google.gms:google-services:3.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8b6dacea..9a77e6f4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Mar 08 11:25:21 EET 2017 +#Thu Oct 26 11:21:06 EEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip