Skip to content

Commit

Permalink
Merge pull request #12 from learn-english-community/feature/streaks
Browse files Browse the repository at this point in the history
feat: Streaks functionality
  • Loading branch information
christolis authored Jul 14, 2023
2 parents 466a8c2 + 28e3eff commit 95e3a2a
Show file tree
Hide file tree
Showing 10 changed files with 391 additions and 8 deletions.
12 changes: 11 additions & 1 deletion app/src/main/java/bot/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import bot.cmd.*;
import bot.listener.ReadyListener;
import bot.service.UserService;
import bot.task.StreakResetTask;
import com.deepl.api.Translator;
import com.mongodb.BasicDBObject;
import io.github.cdimascio.dotenv.Dotenv;
Expand All @@ -12,6 +14,7 @@
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.extern.log4j.Log4j2;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
Expand Down Expand Up @@ -43,6 +46,8 @@ public class App implements ApplicationRunner {
public static List<EventListener> listeners = new ArrayList<>();
public static List<BotCommand> commands;

@Getter private static JDA jda;

@Autowired private MongoTemplate mongoTemplate;

@Autowired private WOTDHandler wotdHandler;
Expand Down Expand Up @@ -92,7 +97,7 @@ public void launch() {
listeners.forEach(jdaBuilder::addEventListeners);
commands.forEach(jdaBuilder::addEventListeners);

JDA jda = jdaBuilder.build();
jda = jdaBuilder.build();
jda.awaitReady();

Optional<Guild> guildOptional = jda.getGuilds().stream().findFirst();
Expand Down Expand Up @@ -146,6 +151,11 @@ public void launch() {
wotdHandler.executeCron(guild);
});

// Streak reset handling
scheduler.schedule(
Constants.CRON_HOURLY,
new StreakResetTask(SpringContext.getBean(UserService.class)));

} catch (Exception e) {
e.printStackTrace();
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/bot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class Constants {

public static final String CRON_DAILY_MORNING = "0 7 * * *";
public static final String CRON_DAILY_MIDDLE = "0 15 * * *";
public static final String CRON_HOURLY = "0 * * * *";
public static final String CRON_TEST = "* * * * *";

public static final String TOTD_API_URL = "https://conversation-starter1.p.rapidapi.com/";
Expand All @@ -18,5 +19,7 @@ public class Constants {

public static final int MAX_JOURNAL_WORD_QUALITY = 4;

public static final int MIN_POINTS_FOR_STREAK = 20;

public static final String DATABASE_NAME = "learn_english";
}
2 changes: 1 addition & 1 deletion app/src/main/java/bot/cmd/JournalCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public void onButtonInteraction(ButtonInteractionEvent event) {
}

if (id.contains("flashcard-quit")) {
FlashcardQuiz.getInstance(user.getId()).ifPresent(quiz -> quiz.finish(true));
FlashcardQuiz.getInstance(user.getId()).ifPresent(quiz -> quiz.finish(true, false));
return;
}

Expand Down
28 changes: 28 additions & 0 deletions app/src/main/java/bot/cmd/StreakCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package bot.cmd;

import bot.service.UserService;
import bot.view.StreakView;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.stereotype.Component;

@Component
public class StreakCommand extends BotCommand {

private final UserService userService;

public StreakCommand(UserService userService) {
super("streak", "Check out your streak", true);
this.userService = userService;
}

@Override
public void execute(SlashCommandInteractionEvent event) {
String userId = event.getUser().getId();
StreakView view = new StreakView();

event.reply("")
.setEphemeral(true)
.setEmbeds(view.getStreak(userService.getUser(userId)))
.queue();
}
}
35 changes: 34 additions & 1 deletion app/src/main/java/bot/entity/User.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package bot.entity;

import bot.App;
import bot.entity.session.Session;
import bot.entity.word.JournalWord;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import lombok.*;
import net.dv8tion.jda.api.entities.Message;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
Expand All @@ -19,4 +23,33 @@ public class User {

/** A list of all the words the user has saved. */
private List<JournalWord> words;

/** Holds an object with points accumulated for each day of the week. */
@Builder.Default private List<Integer> weeklyPoints = generateWeeklyPoints();

private List<Session> sessions;

private Map<String, Long> lastActivity;

/** Holds information about the user's streaks. */
private int currentStreak;

private int maximumStreak;

private static List<Integer> generateWeeklyPoints() {
return new ArrayList<>(Collections.nCopies(7, 0));
}

public void sendPrivateTemporaryMessage(String content) {
App.getJda()
.retrieveUserById(discordId)
.queue(
user -> {
user.openPrivateChannel()
.flatMap(channel -> channel.sendMessage(content))
.delay(30, TimeUnit.SECONDS)
.flatMap(Message::delete)
.queue();
});
}
}
29 changes: 29 additions & 0 deletions app/src/main/java/bot/entity/session/Session.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package bot.entity.session;

import lombok.Builder;
import lombok.Getter;

/**
* Represents a session.
*
* <p>This is mostly used to record past sessions, primarily to keep track of user streaks and for
* future metric aggregation.
*/
@Getter
public class Session {
private int index;

private final Type type;

private final long timestamp;

@Builder
public Session(Type type, long timestamp) {
this.type = type;
this.timestamp = timestamp;
}

public enum Type {
JOURNAL_QUIZ
}
}
25 changes: 20 additions & 5 deletions app/src/main/java/bot/quiz/FlashcardQuiz.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package bot.quiz;

import bot.Constants;
import bot.entity.session.Session;
import bot.quiz.question.FlashcardQuestion;
import bot.quiz.question.Question;
import bot.service.UserService;
import bot.view.StreakView;
import java.awt.*;
import java.util.*;
import java.util.List;
Expand Down Expand Up @@ -80,8 +82,16 @@ public void showQuestion() {
channel.deleteMessageById(success.getId())
.queueAfter(10L, TimeUnit.SECONDS);
});
finish(false);
} else finish(true);
finish(false, false);
} else {
Session session =
Session.builder()
.timestamp(System.currentTimeMillis())
.type(Session.Type.JOURNAL_QUIZ)
.build();
userService.saveSession(getUser().getId(), session);
finish(true, true);
}

return;
}
Expand Down Expand Up @@ -114,20 +124,25 @@ public void start() {
showQuestion();
}

public void finish(boolean announce) {
public void finish(boolean announce, boolean complete) {
if (announce) {
EmbedBuilder embed = new EmbedBuilder();
StreakView streakView = new StreakView();

embed.setTitle("End of exercise");
embed.setDescription("You reached the end of your exercise! 💪");
embed.setColor(Constants.EMBED_COLOR);
embed.setImage("https://media.tenor.com/MDTYbqilAxgAAAAC/ogvhs-high-five.gif");

channel.sendMessageEmbeds(embed.build())
if (complete) userService.addDayPoints(user.getId(), 20);

bot.entity.User savedUser = userService.getUser(user.getId());

channel.sendMessageEmbeds(List.of(embed.build(), streakView.getStreak(savedUser)))
.queue(
success -> {
channel.deleteMessageById(success.getId())
.queueAfter(10L, TimeUnit.SECONDS);
.queueAfter(30L, TimeUnit.SECONDS);
});
}

Expand Down
Loading

0 comments on commit 95e3a2a

Please sign in to comment.