diff --git a/.gitignore b/.gitignore index 650c91720..26559eb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,4 @@ bin/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store diff --git a/README.md b/README.md index 5e1d8b77c..8685db9ae 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,90 @@ -# Note Application +# Joke Machine -This is a minimal example demonstrating usage of the -password-protected user part of the API used in lab 5. +### Project for Group #269 +#### Team Name: Joke Machine +#### Domain: Joke Generation and Explanation -You can find more information about the API endpoints in -[the documentation](https://www.postman.com/cloudy-astronaut-813156/csc207-grade-apis-demo/documentation/fg3zkjm/5-password-protected-user). -If your team is considering an application for which it would be convenient to -store data in something like a database, you may find that the API calls demonstrated -here will be useful in your project, as this will allow you to store -an arbitrary JSON object associated with a username and password. -In this application, a single note has a name (the "username" in terms of the API) and the note -can be read by anyone who knows the name — but only edited by someone who -knows the password for it. +## Table of Contents -You can see the documentation in the various files for more information. +* Software Specification +* Features +* Installation Instructions +* Usage +* License +* Feedback and Contributions -## Testing +## Software Specification +Joke Machine is a joke generation and explanation platform that allows users to generate, search for, save, and understand jokes. Users can generate or search up jokes, ask for explanations, and sort their list of favorite jokes based on rating of the jokes. Joke Machine integrates with external APIs for joke generation and explanation to provide rich and diverse humor content. -The repo also includes an example of a use case interactor test, as well as -an example of an end-to-end test which automates button clicks and inspects -the contents of the actual views. This is something we discussed in the lectures -about testing in CA but had not provided a code example of before. Note, one -could also inspect the contents of the ViewModel objects instead when testing -CA to make a similar test which would be less dependent on the details of the -specific UI implementation. +## Features + Joke Generation: Generate new jokes with a variety of themes and styles. + Joke Explanation: Explain jokes, whether generated by the app or provided by the user. + Favorites Management: Save favorite jokes to revisit later. + Search and Filter: + Search for jokes by title or keywords (e.g., themes like "911"). + Search for jokes within saved list of jokes + Filter jokes by rating to find the "funniest" jokes. -## Project Starter Code +## Setup and Installation +* Before setting up the project, make sure you have the correct software installed。 + 1. Java Development Kit (JDK) version 11 or higher: + 2. https://www.oracle.com/java/technologies/javase-downloads.html + 2. IntelliJ IDEA Community or Ultimate Edition: + 3. https://www.jetbrains.com/idea/download/ + -Your team may choose to use this repo as starter code for your project. You could -also use the lab 5 code — or start from an empty repo if your team prefers. +* Once you have the software setup: + 1. Clone the repository: + 2. "https://github.com/GuoYuHeJason/CSC207GroupProject.git" + + 2. Open the Project in IntelliJ: + 3. Launch IntelliJ IDEA. + 4. Go to file and click New --> Project From Version Control. + 5. Paste the clone and open project. + + 5. Install Dependencies: + 6. Ensure that your project dependencies are configured in a build.gradle or pom.xml file. + 7. If using Maven, IntelliJ will automatically import dependencies defined in pom.xml. + If using Gradle, open the build.gradle file, and IntelliJ will synchronize the dependencies. + + 6. Run the Application: + 6. Locate the Main class (or equivalent entry point) in your project. + 7. Right-click on the file and select Run 'Main'. -If you choose to use one of the repositories we have provided, you can either make -a fork of it or copy the subset of code you want into a completely new repository. + +## Usage +### Generating Jokes +* Select the "Generate" button to create a new joke or search up joke by title or keyword +### Explaining Jokes +* If you don’t understand a joke, click on the "Explain Joke" button. + The system will provide an explanation of the joke's humor or meaning. +### Saving Favorites +* Click "favorite" to add a joke to your favorites list. +* Access your favorites anytime from the "favorited" section. +### Searching and Filtering +* Keyword Search: Enter a keyword (e.g., "911") to find jokes related to that theme. +* Funniest Jokes: Use the "Funniest" filter to sort saved jokes by their humor rating. + +## License +This project is released under the Creative Commons CC0 1.0 Universal (CC0) Public Domain Dedication. See LICENSE for details. + +## Feedback and Contributions +Contributing to the Project: +1. Fork the Repository: + * Click the "Fork" button on the top right of the repository page to create a copy of the project under your GitHub account. +2. Clone the Repository: + * "git clone https://github.com/your-username/joke-machine.git" +3. Create a New Branch: + 4. "git checkout -b feature/new-feature" +4. Make Your Changes: + 5. Add or change features +5. Submit a Pull Request: + 6. Commit and push your changes to your fork and open a pull request in the main repository. + 7. Provide a description of your changes explaining why they are valuable. + +We appreciate you for engaging with our Joke Machine! + + + diff --git a/src/main/java/entity/Joke.java b/src/main/java/entity/Joke.java new file mode 100644 index 000000000..4d63ad1ea --- /dev/null +++ b/src/main/java/entity/Joke.java @@ -0,0 +1,27 @@ +package entity; + +// there should be a joke factory, a user factory +public class Joke { + + private final String content; + private String explanation; + private final int score; + + public Joke(String content, int score) { + this.content = content; + this.explanation = "explanation"; + this.score = score; + } + + public String getContent() { + return content; + } + + public String getExplanation() { + return explanation; + } + + public void setExplanation(String explanation) { + this.explanation = explanation; + } +} diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java index e0c57e9a6..746754ea2 100644 --- a/src/main/java/entity/User.java +++ b/src/main/java/entity/User.java @@ -1,5 +1,7 @@ package entity; +import java.util.List; + /** * The representation of a password-protected user for our program. */ @@ -7,10 +9,12 @@ public class User { private final String name; private final String password; + private List favorites; - public User(String name, String password) { + public User(String name, String password, List favorites) { this.name = name; this.password = password; + this.favorites = favorites; } public String getName() { @@ -21,4 +25,12 @@ public String getPassword() { return password; } + public List getFavorites() { + return favorites; + } + + public void addToFavorites(Joke joke) { + this.favorites.add(joke); + } + } diff --git a/src/main/java/use_case/addToFavorite/favoriteDataAcessInterface b/src/main/java/use_case/addToFavorite/favoriteDataAcessInterface new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/java/view/FavoritePanel.java b/src/main/java/view/FavoritePanel.java new file mode 100644 index 000000000..aaf7a324f --- /dev/null +++ b/src/main/java/view/FavoritePanel.java @@ -0,0 +1,135 @@ +package view; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.ActionListener; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; + +/** + * A FavoritePanel that includes a scrollable list of favorite jokes. + */ +public class FavoritePanel extends JPanel { + + // UI Components + private final JTextField keywordField = new JTextField(20); // Text field to enter a keyword + private final JButton searchButton = new JButton("Search"); + private final JButton funniestButton = new JButton("Funniest"); + private final JButton cancelButton = new JButton("Cancel"); + private final DefaultListModel jokeListModel = new DefaultListModel<>(); + private final JList jokeList = new JList<>(jokeListModel); // Scrollable joke list + private final JScrollPane scrollPane = new JScrollPane(jokeList); // Scroll pane for the list + private final JButton goToJokePageButton = new JButton("Go to Joke Page"); + private final JButton goToLoginPageButton = new JButton("Go to Login Page"); + + public FavoritePanel() { + // Set layout + setLayout(new BorderLayout()); + + // Top Panel: Search bar and action buttons + final JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + topPanel.add(new JLabel("Enter Keyword:")); + topPanel.add(keywordField); + topPanel.add(searchButton); + topPanel.add(funniestButton); + topPanel.add(cancelButton); + add(topPanel, BorderLayout.NORTH); + + // Main Content: Scrollable list of favorite jokes + jokeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + add(scrollPane, BorderLayout.CENTER); + + // Bottom Panel: Navigation buttons + final JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + bottomPanel.add(goToJokePageButton); + bottomPanel.add(goToLoginPageButton); + add(bottomPanel, BorderLayout.SOUTH); + + // Populate with dummy data for demonstration + populateDummyData(); + } + + /** + * Populates the joke list with dummy data for testing. + * Remove this method in production. + */ + private void populateDummyData() { + for (int i = 1; i <= 50; i++) { + jokeListModel.addElement("Favorite Joke " + i); + } + } + + /** + * Updates the joke list with the provided list of jokes. + * + * @param jokes the list of jokes to display + */ + public void updateJokeList(java.util.List jokes) { + jokeListModel.clear(); + for (String joke : jokes) { + jokeListModel.addElement(joke); + } + } + + /** + * Gets the keyword entered in the search field. + * + * @return the entered keyword + */ + public String getEnteredKeyword() { + return keywordField.getText().trim(); + } + + /** + * Sets the ActionListener for the search button. + * + * @param listener the ActionListener for the search button + */ + public void setSearchButtonListener(ActionListener listener) { + searchButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the funniest button. + * + * @param listener the ActionListener for the funniest button + */ + public void setFunniestButtonListener(ActionListener listener) { + funniestButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the cancel button. + * + * @param listener the ActionListener for the cancel button + */ + public void setCancelButtonListener(ActionListener listener) { + cancelButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the "Go to Joke Page" button. + * + * @param listener the ActionListener for the navigation button + */ + public void setGoToJokePageButtonListener(ActionListener listener) { + goToJokePageButton.addActionListener(listener); + } + + /** + * Sets the ActionListener for the "Go to Login Page" button. + * + * @param listener the ActionListener for the navigation button + */ + public void setGoToLoginPageButtonListener(ActionListener listener) { + goToLoginPageButton.addActionListener(listener); + } +}