diff --git a/package.json b/package.json
index 6f65d84..7331cb2 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"react-native-easy-toast": "^1.2.0",
"react-native-elements": "^3.0.0",
"react-native-modal": "^11.5.6",
+ "react-native-picker-select": "^8.0.4",
"react-native-safe-area-context": "3.1.9",
"react-native-web": "~0.13.12",
"react-redux": "^7.2.0",
diff --git a/src/common/constants.js b/src/common/constants.js
index 09919ff..0dac708 100644
--- a/src/common/constants.js
+++ b/src/common/constants.js
@@ -21,6 +21,15 @@ export const DARK_MODE = 'DARK_MODE';
export const BACK_TO_BACK_MODE = 'BACK_TO_BACK_MODE';
export const MEANING_FIRST = 'MEANING_FIRST';
+// review orders
+export const REVIEW_ORDER = 'REVIEW_ORDER'
+export const RANDOM_ORDER = 'RANDOM_ORDER'
+export const LOWEST_LEVEL_FIRST = 'LOWEST_LEVEL_FIRST'
+export const CURRENT_LEVEL_FIRST = 'CURRENT_LEVEL_FIRST'
+export const ASCENDING_SRS_STAGE = 'ASCENDING_SRS_STAGE'
+export const DESCENDING_SRS_STAGE = 'DESCENDING_SRS_STAGE'
+
+
export const TERMINOLOGY = {
// subject types
diff --git a/src/components/List/ListItem.js b/src/components/List/ListItem.js
index 3d4203b..0d3be99 100644
--- a/src/components/List/ListItem.js
+++ b/src/components/List/ListItem.js
@@ -6,6 +6,7 @@ import { ListItem, Icon } from 'react-native-elements';
import device, {isWeb} from 'src/utils/device';
import useColorScheme from 'src/hooks/useColorScheme';;
import theme from 'src/common/theme';
+import RNPickerSelect from 'react-native-picker-select';
const ListItemComponent = props => {
const colorScheme = useColorScheme();
@@ -27,6 +28,7 @@ const ListItemComponent = props => {
{props.rightIcon && {props.rightIcon}}
{!isWeb() && props.switch && }
{isWeb() && props.switch && {props?.switch?.value ? "On" : "Off"}}
+ {props.picker && }
)
};
@@ -63,4 +65,12 @@ const styles = StyleSheet.create({
}
})
+const pickerStyles = StyleSheet.create({
+ inputWeb: {
+ borderWidth: 0,
+ textAlign: 'right',
+ fontSize: 14,
+ },
+})
+
export default ListItemComponent;
diff --git a/src/features/reviews/useReviewSession.js b/src/features/reviews/useReviewSession.js
index ba2fa78..ee1a615 100644
--- a/src/features/reviews/useReviewSession.js
+++ b/src/features/reviews/useReviewSession.js
@@ -8,7 +8,7 @@ import { MEANING, RADICAL } from 'src/common/constants';
import listToDict from 'src/utils/listToDict';
import queueReviews from 'src/features/reviews/utils/queueReviews';
-import { BACK_TO_BACK_MODE, MEANING_FIRST} from 'src/common/constants';
+import { BACK_TO_BACK_MODE, MEANING_FIRST, REVIEW_ORDER } from 'src/common/constants';
import { useStoreState } from 'easy-peasy';
import adjustQueue from 'src/features/reviews/utils/adjustQueue';
@@ -32,16 +32,18 @@ export default (reviews, subjects) => {
const [ completedCards, setCompletedCards ] = useState({});
const [ incorrectCards, setIncorrectCards ] = useState({});
- // Sort reading-meaning card pairs back-to-back
+ // Sort reading-meaning card pairs back-to-back according to the review order
const userSettings = useStoreState(state => state.session.userSettings);
const backToBackMode = _.get(userSettings, BACK_TO_BACK_MODE);
const meaningFirst = _.get(userSettings, MEANING_FIRST);
+ const reviewOrder = _.get(userSettings, REVIEW_ORDER);
// Re-sort queue when the relevant user settings change
useEffect(() => {
- setQueue(adjustQueue(queue, backToBackMode, meaningFirst))
+ setQueue(adjustQueue(queue, backToBackMode, meaningFirst, reviewOrder))
}, [
- backToBackMode,
- meaningFirst,
+ backToBackMode,
+ meaningFirst,
+ reviewOrder,
]);
// refresh &
@@ -63,8 +65,8 @@ export default (reviews, subjects) => {
setTotalReviews(reviews ? reviews.length : 0);
// create queue
- const _queue = queueReviews(reviews);
- setQueue(adjustQueue(_queue, backToBackMode, meaningFirst));
+ const _queue = queueReviews(reviews, subjects);
+ setQueue(adjustQueue(_queue, backToBackMode, meaningFirst, reviewOrder));
setTotalCards(_queue.length);
}, [
diff --git a/src/features/reviews/utils/adjustQueue.js b/src/features/reviews/utils/adjustQueue.js
index d88becb..3145224 100644
--- a/src/features/reviews/utils/adjustQueue.js
+++ b/src/features/reviews/utils/adjustQueue.js
@@ -9,15 +9,35 @@
import _ from 'lodash';
-import { MEANING, RADICAL } from 'src/common/constants';
+import { MEANING, RADICAL, RANDOM_ORDER, LOWEST_LEVEL_FIRST, CURRENT_LEVEL_FIRST, ASCENDING_SRS_STAGE, DESCENDING_SRS_STAGE } from 'src/common/constants';
const ALLOWED_MAX_DISTANCE = 10;
const ALLOWED_MIN_DISTANCE = 3;
-export default (queue, backToBackMode = false, meaningFirst = false) => {
- const newQueue = queue.slice();
+export default (queue, backToBackMode = false, meaningFirst = false, reviewOrder = RANDOM_ORDER) => {
+
+ let newQueue = queue.slice();
let currentIndex = 0;
+ // sort new queue based on the selected review order
+ switch (reviewOrder) {
+ case RANDOM_ORDER:
+ newQueue = _.shuffle(newQueue);
+ break;
+ case LOWEST_LEVEL_FIRST:
+ newQueue = _.orderBy(newQueue, 'subjectLevel', 'asc')
+ break;
+ case CURRENT_LEVEL_FIRST:
+ newQueue = _.orderBy(newQueue, 'subjectLevel', 'desc')
+ break;
+ case ASCENDING_SRS_STAGE:
+ newQueue = _.orderBy(newQueue, 'review.data.srs_stage', 'asc')
+ break;
+ case DESCENDING_SRS_STAGE:
+ newQueue = _.orderBy(newQueue, 'review.data.srs_stage', 'desc')
+ break;
+ }
+
// avoid recursion to avoid exceeding maximum call stack size
while (currentIndex < queue.length - 1) {
diff --git a/src/features/reviews/utils/queueReviews.js b/src/features/reviews/utils/queueReviews.js
index 3dfbef6..a72fbeb 100644
--- a/src/features/reviews/utils/queueReviews.js
+++ b/src/features/reviews/utils/queueReviews.js
@@ -6,8 +6,7 @@ import adjustQueue from 'src/features/reviews/utils/adjustQueue';
// pick multiple reviews from the list, respecting the
// removed items from the list from the previous loop
-const queueReviews = (reviews, reviewTypesHistory, queue) => {
-
+const queueReviews = (reviews, reviewTypesHistory, queue, subjects) => {
let _reviews = reviews;
let _reviewTypesHistory = reviewTypesHistory;
@@ -22,11 +21,16 @@ const queueReviews = (reviews, reviewTypesHistory, queue) => {
newReviewTypeHistory,
] = pickReviewAndType(_reviews, _reviewTypesHistory);
+ // find the review's subject
+ const subject = subjects.find(subject => subject.id === _.get(review, 'data.subject_id'));
+ const subjectLevel = _.get(subject, "data.level");
+
// add current pick to the queue
queue.push({
id: randomId(),
review,
reviewType,
+ subjectLevel,
});
_reviews = newReviews;
@@ -37,7 +41,7 @@ const queueReviews = (reviews, reviewTypesHistory, queue) => {
return queue;
}
-export default reviews => {
- const queued = queueReviews(reviews, {}, []);
+export default (reviews, subjects) => {
+ const queued = queueReviews(reviews, {}, [], subjects);
return adjustQueue(queued);
};
diff --git a/src/screens/Review/ReviewMenu.js b/src/screens/Review/ReviewMenu.js
index 1a9d886..f2478ea 100644
--- a/src/screens/Review/ReviewMenu.js
+++ b/src/screens/Review/ReviewMenu.js
@@ -10,7 +10,7 @@ import List from 'src/components/List/List';
import Modal, { DURATION_SAFE } from 'src/components/Modal/Modal';
import dialog from 'src/utils/dialog';
import { isWeb } from 'src/utils/device';
-import { SKIP_MODE, QUICK_MODE, DARK_MODE, BACK_TO_BACK_MODE, MEANING_FIRST}
+import { SKIP_MODE, QUICK_MODE, DARK_MODE, BACK_TO_BACK_MODE, MEANING_FIRST, REVIEW_ORDER, RANDOM_ORDER, LOWEST_LEVEL_FIRST, CURRENT_LEVEL_FIRST, ASCENDING_SRS_STAGE, DESCENDING_SRS_STAGE }
from 'src/common/constants';
const ReviewMenu = ({
@@ -33,6 +33,7 @@ const ReviewMenu = ({
const darkMode = _.get(userSettings, DARK_MODE);
const backToBackMode = _.get(userSettings, BACK_TO_BACK_MODE);
const meaningFirst = _.get(userSettings, MEANING_FIRST);
+ const reviewOrder = _.get(userSettings, REVIEW_ORDER, RANDOM_ORDER);
return (
,
+ picker: {
+ onValueChange: (value) => {
+ saveSetting({ key: REVIEW_ORDER, value: value });
+ },
+ placeholder: {},
+ value: reviewOrder,
+ items:
+ [
+ { value: RANDOM_ORDER, label: "Random Order" },
+ { value: LOWEST_LEVEL_FIRST, label: "Lowest Level First" },
+ { value: CURRENT_LEVEL_FIRST, label: "Current Level First" },
+ { value: ASCENDING_SRS_STAGE, label: "Ascending SRS Stage" },
+ { value: DESCENDING_SRS_STAGE, label: "Descending SRS Stage" },
+ ],
+ },
+ },
{
id: 'ses-dark',
title: 'Dark Mode',
diff --git a/yarn.lock b/yarn.lock
index 61c9b90..3126ec4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2795,6 +2795,11 @@
resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.9.7.tgz#769c6b306ea6bbaa1c4a3fffdd183d0cfc30ed7e"
integrity sha512-NAkkT68oF+M9o6El2xeUqZK7magPjG/tAcEbvCbqyhlh3yElKWnI1e1vpbVvFXzTefy67FwYFWOJqBN6U7Mnkg==
+"@react-native-picker/picker@^1.8.3":
+ version "1.16.3"
+ resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-1.16.3.tgz#22750f8d44465432845fa59ce20e69761029b6ef"
+ integrity sha512-Qt40DBg7IEhBN5x2DYPV3B26j5fNhVZcpCestr1IuirneMNtOaIyA9+nPYniL/OBzd9YbpUKbS7XSy/MM9bP3w==
+
"@reduxjs/toolkit@^1.3.5":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.4.0.tgz#ee2e2384cc3d1d76780d844b9c2da3580d32710d"
@@ -14201,6 +14206,14 @@ react-native-modal@^11.5.6:
prop-types "^15.6.2"
react-native-animatable "1.3.3"
+react-native-picker-select@^8.0.4:
+ version "8.0.4"
+ resolved "https://registry.yarnpkg.com/react-native-picker-select/-/react-native-picker-select-8.0.4.tgz#3f7f1f42df69b06e7d2c10338288332a6c40fd10"
+ integrity sha512-orBjPIwBkV5oipyVw263YNMI56f6Kj3p/ejabZoCYYNSG3AiLVVhC2RqsxMgDA7IayyURAW+AlV+mDJyVqLBkg==
+ dependencies:
+ "@react-native-picker/picker" "^1.8.3"
+ lodash.isequal "^4.5.0"
+
react-native-ratings@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/react-native-ratings/-/react-native-ratings-7.3.0.tgz#32e11e4ed944ba8adbbc995d601df3f131619b6f"