Skip to content

Commit

Permalink
Merge branch 'release/1.50'
Browse files Browse the repository at this point in the history
  • Loading branch information
eadm committed Dec 28, 2017
2 parents 1ad3940 + 9535961 commit aed87bc
Show file tree
Hide file tree
Showing 46 changed files with 1,435 additions and 105 deletions.
12 changes: 9 additions & 3 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,13 @@
-keep interface org.stepic.droid.configuration.** { *; }
-dontwarn org.stepic.droid.configuration.**

#BottomNavigationHelper uses reflection for changing this field (watch support updates for removing the reflection)
-keepclassmembers class android.support.design.internal.BottomNavigationMenuView {
boolean mShiftingMode;
#keep javascript interfaces
-keepattributes JavascriptInterface
-keep public class org.stepic.droid.ui.custom.LatexSupportableWebView$OnScrollWebListener
-keepclassmembers class org.stepic.droid.ui.custom.LatexSupportableWebView$OnScrollWebListener {
public *;
}

-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
4 changes: 4 additions & 0 deletions app/src/main/assets/wysiwyg.css
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,8 @@

.step-text__limit-value {
margin-left: 1em;
}

::-webkit-scrollbar {
display: none;
}
2 changes: 2 additions & 0 deletions app/src/main/java/org/stepic/droid/analytic/Analytic.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface Code {
String CODE_FULLSCREEN_PRESSED = "code_fullscreen_pressed";
String CODE_RESET_PRESSED = "code_reset_pressed";
String CHOOSE_NULL = "code_choose_null";
String CODE_EDITOR_ERROR = "code_editor_error";
}

interface Search {
Expand Down Expand Up @@ -270,6 +271,7 @@ interface Error {
String TEMPLATE_WAS_NULL = "error_code_template_null";
String COURSE_COLLECTION_EMPTY = "course_collection_empty";
String FEEDBACK_BROKEN = "feedback_broken";
String CANT_FIND_VIDEO_FILE_WITH_FILES_PROVIDER = "cant_find_video_file_with_file_provider";
}

interface Web {
Expand Down
34 changes: 29 additions & 5 deletions app/src/main/java/org/stepic/droid/code/ui/CodeEditor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
import org.stepic.droid.analytic.Analytic
import org.stepic.droid.base.App
import org.stepic.droid.code.highlight.ParserContainer
import org.stepic.droid.code.highlight.syntaxhighlight.ParseResult
Expand Down Expand Up @@ -54,6 +55,9 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
@Inject
lateinit var codeAnalyzer: CodeAnalyzer

@Inject
lateinit var analytic: Analytic

private val LINE_NUMBERS_MARGIN_PX = DpPixelsHelper.convertDpToPixel(LINE_NUMBERS_MARGIN_DP).toInt()

private val highlightPublisher = PublishSubject.create<Editable>()
Expand All @@ -77,6 +81,8 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
p
}

private var isAttached = false

var lang = ""
set(value) {
field = value
Expand Down Expand Up @@ -107,12 +113,24 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0

override fun onAttachedToWindow() {
super.onAttachedToWindow()
isAttached = true
initListeners()
addTextChangedListener(this)
}

private fun initListeners() {
compositeDisposable.clear()

if (!isAttached) return
compositeDisposable.add(
spanPublisher
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { updateHighlight(it) }
.subscribe({ updateHighlight(it) }, {
analytic.reportError(Analytic.Code.CODE_EDITOR_ERROR, it)
spanPublisher.onNext(emptyList()) // to avoid cyclic error's call due to publish subject behavior
initListeners()
})
)

compositeDisposable.add(
Expand All @@ -122,24 +140,30 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
RxOptional(parserContainer.prettifyParser?.parse(lang, it.toString()))
}
.unwrapOptional()
.subscribe(spanPublisher::onNext)
.subscribe(spanPublisher::onNext) {
analytic.reportError(Analytic.Code.CODE_EDITOR_ERROR, it)
initListeners()
}
)

compositeDisposable.add(
layoutChangesPublisher
.debounce(SCROLL_DEBOUNCE_MS, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { spanPublisher.value?.let(this::updateHighlight) }
.subscribe({ spanPublisher.value?.let(this::updateHighlight) }, {
analytic.reportError(Analytic.Code.CODE_EDITOR_ERROR, it)
initListeners()
})
)

addTextChangedListener(this)
afterTextChanged(editableText)
}

override fun onDetachedFromWindow() {
isAttached = false
removeTextChangedListener(this)
compositeDisposable.dispose()
compositeDisposable.clear()
super.onDetachedFromWindow()
}

Expand Down
10 changes: 7 additions & 3 deletions app/src/main/java/org/stepic/droid/core/ScreenManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

Expand Down Expand Up @@ -66,6 +65,7 @@
import org.stepic.droid.ui.fragments.SectionsFragment;
import org.stepic.droid.util.AndroidVersionKt;
import org.stepic.droid.util.AppConstants;
import org.stepic.droid.util.GenericFileProvider;
import org.stepic.droid.util.StringUtil;
import org.stepic.droid.web.ViewAssignment;

Expand Down Expand Up @@ -338,8 +338,12 @@ public void showVideo(Activity sourceActivity, @Nullable Video cachedVideo, @Nul
//android 7 do not work with file scheme (we need content with authority)
//check https://stackoverflow.com/questions/38200282/android-os-fileuriexposedexception-file-storage-emulated-0-test-txt-exposed
//we do not need add file scheme. it will be added due to getUriForFile
File file = new File(videoPath);
videoUri = FileProvider.getUriForFile(sourceActivity, sourceActivity.getPackageName() + AppConstants.FILE_PROVIDER_AUTHORITY, file);
try {
File file = new File(videoPath);
videoUri = GenericFileProvider.getUriForFile(sourceActivity, sourceActivity.getPackageName() + AppConstants.FILE_PROVIDER_AUTHORITY, file);
} catch (Exception e) {
analytic.reportError(Analytic.Error.CANT_FIND_VIDEO_FILE_WITH_FILES_PROVIDER, e);
}
}
}
Intent intent = new Intent(Intent.ACTION_VIEW, videoUri);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package org.stepic.droid.core.presenters

import android.support.annotation.MainThread
import android.support.annotation.WorkerThread
import android.support.v4.util.ArraySet
import android.support.v4.util.LongSparseArray
import android.util.Patterns
import org.stepic.droid.analytic.Analytic
import org.stepic.droid.base.Client
import org.stepic.droid.concurrency.MainHandler
Expand All @@ -14,7 +17,10 @@ import org.stepic.droid.notifications.StepikNotificationManager
import org.stepic.droid.notifications.badges.NotificationsBadgesManager
import org.stepic.droid.notifications.model.Notification
import org.stepic.droid.notifications.model.NotificationType
import org.stepic.droid.util.DateTimeHelper
import org.stepic.droid.util.not
import org.stepic.droid.util.putIfAbsent
import org.stepic.droid.util.substringOrNull
import org.stepic.droid.web.Api
import timber.log.Timber
import java.util.*
Expand Down Expand Up @@ -70,6 +76,7 @@ class NotificationListPresenter
}
mainHandler.post {
notificationList.addAll(notifications)
resolveNotificationsDateGroup()
wasShown.set(true)
view?.onNeedShowNotifications(notificationList) ?: wasShown.set(false)
}
Expand Down Expand Up @@ -106,15 +113,46 @@ class NotificationListPresenter
it.htmlText?.isNotBlank() ?: false
}

notifications.forEach {
val notificationHtmlText = it.htmlText ?: ""
val userIdToNotificationsIndexes = LongSparseArray<MutableList<Int>>() // userId -> notifications index where avatar should be set
val userIds = ArraySet<Long>()

notifications.forEachIndexed { index, notification ->
val notificationHtmlText = notification.htmlText ?: ""
val fixedHtml = notificationHtmlText.replace("href=\"/", "href=\"$baseUrl/")
it.htmlText = fixedHtml
notification.htmlText = fixedHtml

if (notification.type == NotificationType.comments) {
extractUserAvatarUrl(notification)?.let { userId ->
userIdToNotificationsIndexes.putIfAbsent(userId, ArrayList())
userIdToNotificationsIndexes[userId].add(index)
userIds.add(userId)
}
}
}

if (userIds.isNotEmpty()) {
api.getUsers(userIds.toLongArray()).execute().body()?.users?.forEach {
val avatar = it.getAvatarPath()
userIdToNotificationsIndexes[it.id.toLong()].forEach { notificationIndex ->
notifications[notificationIndex].userAvatarUrl = avatar
}
}
}

Timber.d("after filter size is %d", notifications.size)
return notifications
}

@WorkerThread
private fun extractUserAvatarUrl(notification: Notification): Long? {
val matcher = Regex(Patterns.WEB_URL.pattern()) // used kotlin Regex instead of android Pattern due to unstable work of Pattern on different Android versions
notification.htmlText?.let { matcher.find(it) } ?.groupValues?.firstOrNull()?.let { userUrl ->
val start = userUrl.lastIndexOf('/')
return userUrl.substringOrNull(start + 1)?.toLongOrNull()
}
return null
}

fun loadMore() {
if (isLoading.get() || !hasNextPage) {
return
Expand All @@ -135,6 +173,7 @@ class NotificationListPresenter
}
mainHandler.post {
notificationList.addAll(notifications)
resolveNotificationsDateGroup()
view?.onNeedShowNotifications(notificationList)
}
}
Expand Down Expand Up @@ -277,6 +316,28 @@ class NotificationListPresenter
}
}

private fun resolveNotificationsDateGroup() {
var groupId = -1
var groupDay = -1
var groupYear = -1
notificationList.forEach { notification ->
notification.time?.let { time ->
val date = DateTimeHelper.toCalendar(time)
date.timeZone = TimeZone.getDefault()

val day = date.get(Calendar.DAY_OF_YEAR)
val year = date.get(Calendar.YEAR)
if (day != groupDay || year != groupYear) {
groupDay = day
groupYear = year
groupId++
}

notification.dateGroup = groupId
}
}
}

override fun attachView(view: NotificationListView) {
super.attachView(view)
internetEnabledListenerClient.subscribe(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ data class Notification(
@SerializedName("html_text")
var htmlText: String? = null,
var action: String? = null,
var course_id: Long? = null
var course_id: Long? = null,
var userAvatarUrl: String? = null,
var notificationText: CharSequence? = null,
var dateGroup: Int = 0
)

enum class NotificationType(val channel: StepikNotificationChannel) {
Expand Down
15 changes: 13 additions & 2 deletions app/src/main/java/org/stepic/droid/services/LoadService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.stepic.droid.analytic.Analytic;
import org.stepic.droid.base.App;
import org.stepic.droid.model.Assignment;
import org.stepic.droid.model.CachedVideo;
import org.stepic.droid.model.DownloadEntity;
import org.stepic.droid.model.Lesson;
import org.stepic.droid.model.Progress;
Expand Down Expand Up @@ -126,8 +127,18 @@ private void addDownload(String url, long fileId, String title, Step step, long
// FIXME: 20.10.15 this simple check doesn't work if file is loading and at this moment adding to Download manager Queue,
// FIXME: 20.10.15 but this is not useless, because, work if file exists on the disk.
// FIXME: 20.10.15 For 'singleton' file of Video (or Step) at storage use UI and Broadcasts.
storeStateManager.updateStepAfterDeleting(step);
return;
CachedVideo video = databaseFacade.getCachedVideoById(fileId);
if (video == null) {
FileUtil.cleanDirectory(downloadFolderAndFile); // remove file that not present in database
} else {
if (video.getStepId() != step.getId()) {
// trying to link video again
video.setStepId(step.getId());
databaseFacade.addVideo(video);
}
storeStateManager.updateStepAfterDeleting(step);
return;
}
}

Uri target = Uri.fromFile(downloadFolderAndFile);
Expand Down
Loading

0 comments on commit aed87bc

Please sign in to comment.