Skip to content

Instantly share code, notes, and snippets.

@marcmartino
Last active January 30, 2019 03:39
Show Gist options
  • Save marcmartino/f2b79c10d3e8fd1ed1a0be3270a9f675 to your computer and use it in GitHub Desktop.
Save marcmartino/f2b79c10d3e8fd1ed1a0be3270a9f675 to your computer and use it in GitHub Desktop.
CardQueues Snippets
type Card = {
id: number,
phrase: string,
translation: string,
};
type CardQueue = Card[] | "Completed";
type CardQueues = [CardQueue, CardQueue];
type UpdatedQueues = {
updatedAt: Date,
queues: CardQueues,
}
type FetchedCards = {
data: {
getNextCards: Card[]
}
}
type UpdatedQueuesUnit = {
updatedAt: Date,
queues: [[],[]]
}
import {
head,
tail,
prop,
tryCatch,
F,
curry,
} from "ramda";
// import fetch from "node-fetch";
const nextCardsQuery = (lastId: number, listId: number): string =>
`query { getNextCards(listId:${listId},prevCardId:${lastId},limit:4) { id phrase translation }}`;
const cardQueueHead = (q: CardQueue): Card | undefined =>
q instanceof Array && q.length > 0
? head(q)
: undefined;
const cardQueueTail = (q: CardQueue): CardQueue =>
q instanceof Array
? tail(q)
: q;
const cardQueueLength = (q: CardQueue): number =>
q instanceof Array
? q.length
: 0;
export const updatedQueuesUnit: UpdatedQueuesUnit =
({
updatedAt: (new Date(0)),
queues: [[],[]]
});
const newReviewQueue = (updatedAt: Date, q: CardQueue): Promise<CardQueue> =>
Promise.resolve([]);
const fetchNewCards = (query: string): Promise<CardQueue> =>
fetch('https://altavista.com/graphql', {
method: "POST",
headers: {
"Content-Type": "application/json",
'x-api-key': '<poop-key>',
},
body: JSON.stringify({ query, }),
})
.then((resp) => resp.json())
.then(({ data: { getNextCards, }, }: FetchedCards) =>
getNextCards.length
? getNextCards
: "Completed");
const newNextQueue = async (q: CardQueue): Promise<CardQueue> => {
if (q instanceof Array && q.length <= 5) {
const newCards = await fetchNewCards(nextCardsQuery(prop('id', q[q.length - 1]), 1));
if (newCards === "Completed" && q.length === 0) {
return "Completed";
}
return [...q, ...(newCards instanceof Array ? newCards : [])];
}
return q;
}
export const nextCard = ([reviews, nexts]: CardQueues): [(Card | undefined), CardQueues] =>
[
cardQueueHead(reviews) || cardQueueHead(nexts),
[
cardQueueTail(reviews),
cardQueueLength(cardQueueTail(reviews)) === cardQueueLength(reviews)
? cardQueueTail(nexts)
: nexts]
];
export const updateQueues = async ({ updatedAt, queues: [reviews, nexts], }: UpdatedQueues): Promise<UpdatedQueues> => {
const updatedQueues: CardQueues = await Promise.all([
newReviewQueue(updatedAt, reviews), newNextQueue(nexts)]);
return {
queues: updatedQueues,
updatedAt: (new Date()),
};
}
const storageKey = (listId: number, userId: number): string =>
`queue-${userId}-${listId}`;
const serializeCardQueues = (qs: UpdatedQueues): string | false =>
JSON.stringify(qs);
const deserializeCardQueues = (str: string): UpdatedQueues => JSON.parse(str);
const curriedSetLocalStorage = curry(localStorage.setItem)
export const saveQueues = (listId: number, userId: number) =>
(qs: UpdatedQueues): Promise<UpdatedQueues | false> => {
const serializedQueue = tryCatch(serializeCardQueues, F)(qs);
const saved = typeof serializedQueue === "string"
? tryCatch(curriedSetLocalStorage(storageKey(listId, userId)), F)(serializedQueue)
: false;
return saved === false
? Promise.resolve(F())
: Promise.resolve(qs);
}
export const loadQueues = (listId: number, userId: number): Promise<UpdatedQueues | UpdatedQueuesUnit> => {
const storedData = localStorage.getItem(storageKey(listId, userId));
return storedData !== null
? Promise.resolve(deserializeCardQueues(storedData))
: Promise.resolve(updatedQueuesUnit);
}
// const main = async () => {
// const updatedQ = await updateQueues({updatedAt: new Date('1/1/19'), queues: testQueues,})
// console.log(updatedQ);
// console.log(nextCard(updatedQ.queues));
// console.log(await updateQueues(updatedQ));
// };
// main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment