Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add capability to change name of Masjid and class via a settings module. #55

Open
takasurazeem opened this issue Feb 18, 2024 · 1 comment · Fixed by #54
Open

Add capability to change name of Masjid and class via a settings module. #55

takasurazeem opened this issue Feb 18, 2024 · 1 comment · Fixed by #54

Comments

@takasurazeem
Copy link
Owner

No description provided.

@takasurazeem takasurazeem converted this from a draft issue Feb 18, 2024
@takasurazeem takasurazeem moved this from Done to In Progress in Quran Quiz Feb 18, 2024
Copy link

codeautopilot bot commented Feb 18, 2024

Potential solution

The task involves adding the capability to change the name of the Masjid and class via a settings module. The solution requires updating the QuizPreferences structure to include new properties for Masjid and class names, modifying the PDFPreviewView to use these new properties, and ensuring that the Datastore implementations can save and load these new settings. Additionally, the QuizSettingsView will need to provide UI elements for user input, and the QuizViewModel will need to handle the logic for updating and persisting these settings.

How to implement

QuizPreferences.swift

Add new properties for Masjid and class names to the QuizPreferences structure and update the initializer to include these properties.

struct QuizPreferences {
    struct QuizHeader {
        var topRightText: String
        var topLeftText: String
        var masjidName: String
        var className: String
    }
    
    var quizHeader: QuizHeader
    var quizDate = Date.now
    
    init(topRightText: String = "Default Top Right",
         topLeftText: String = "Default Top Left",
         masjidName: String = "Default Masjid",
         className: String = "Default Class") {
        self.quizHeader = QuizHeader(topRightText: topRightText,
                                     topLeftText: topLeftText,
                                     masjidName: masjidName,
                                     className: className)
    }
}

PDFPreviewView.swift

Update the PDFPreviewView to use the new properties from QuizPreferences when generating the PDF.

PDFKitView(
    documentData: PDFGenerator(
        verses: viewModel.quizVerses,
        words: viewModel.wordsForWordsMeaning,
        preferences: viewModel.preferences
    ).generateQuiz()
)

QuizSettingsView.swift

Add TextField views for Masjid and class names and a Button to save the changes.

TextField("Enter Masjid Name", text: $masjidName)
TextField("Enter Class Name", text: $className)
Button("Save Changes", action: saveSettings)

QuizViewModel.swift

Add properties for Masjid and class names and methods to update and save these settings.

@Published var masjidName: String = ""
@Published var className: String = ""

func updateMasjidName(to newName: String) {
    masjidName = newName
    saveSettings()
}

func updateClassName(to newName: String) {
    className = newName
    saveSettings()
}

private func saveSettings() {
    // Save the settings using the Datastore implementation
}

FileDatastore.swift

Ensure that the FileDatastore class can handle saving and loading the new settings. Since the class is generic, no specific changes are needed here, but you may want to add error handling and logging.

let preferencesDatastore = FileDatastore<QuizPreferences>(purpose: "QuizSettings")
preferencesDatastore.save(preferences, forKey: "QuizPreferences")

Datastore.swift

Verify that the concrete implementations of the Datastore protocol can handle string values for Masjid and class names. If necessary, add methods to save and load these settings.

protocol Datastore {
    // Existing methods...
    func saveMasjidName(_ name: String)
    func loadMasjidName() -> String?
    func saveClassName(_ name: String)
    func loadClassName() -> String?
}

Ensure that the concrete classes or structs that conform to the Datastore protocol implement these methods.

Testing and Documentation

Test the changes to ensure that the Masjid and class names are correctly saved, loaded, and displayed. Update documentation to reflect the new functionality.

Click here to create a Pull Request with the proposed solution

Files used for this task:

Changes on QuranMajeed/Foundation/Datastore.swift

The Datastore protocol in QuranMajeed/Foundation/Datastore.swift already provides a generic interface for saving, loading, and deleting data, as well as flushing the entire data store. To support the new feature of changing the name of the Masjid and class via a settings module, we need to ensure that the concrete implementations of this protocol can handle the specific data types for Masjid and class names.

Since the Datastore protocol uses an associated type T, it can support any data type, including strings, which are likely the data type needed for Masjid and class names. Therefore, the protocol itself does not need to be modified to support the new feature.

However, it is important to ensure that the concrete classes or structs that conform to the Datastore protocol in the application are capable of handling string values and that they are set up to save and retrieve the Masjid and class names using specific keys.

The tasks for the concrete implementations, such as FileDatastore, will involve updating methods to include saving and loading the new settings for Masjid and class names. This will likely involve adding new keys for these settings and ensuring that the save and load methods can handle string values.

In summary, the Datastore protocol itself does not require changes for this task, but the concrete implementations must be verified or updated to ensure they can handle the new settings. The focus should be on the classes or structs that conform to this protocol and their ability to persist and retrieve string values associated with the new feature.

Changes on QuranMajeed/Info.plist

For the Info.plist file, there is no immediate need to add keys or strings related to permissions or usage descriptions for the task described. The task involves adding functionality to change the name of a Masjid and class via a settings module, which does not inherently require new permissions or usage descriptions.

However, if the new settings involve accessing sensitive user data or integrating with other services that require permissions (e.g., cloud storage for syncing settings), then appropriate keys and strings would need to be added to the Info.plist file.

Since the task description does not specify such requirements, the Info.plist file can remain unchanged for the scope of this task. If future requirements necessitate changes to this file, those can be addressed at that time.

Changes on QuranMajeed/Quiz/Main/View/Quiz/PDFPreviewView.swift

To address the task of binding the Masjid and class names to the appropriate Text views in the PDFPreviewView.swift file, you will need to modify the PDFPreviewView struct to use the updated QuizPreferences structure that includes the new properties for Masjid and class names.

Here's a practical proposal to solve the task:

  1. Ensure that the QuizPreferences structure is updated to include properties for the Masjid and class names. This should be handled in the QuizPreferences.swift file by another agent.

  2. Once the QuizPreferences structure is updated, modify the PDFPreviewView struct to use these new properties when generating the PDF. Specifically, you will need to update the PDFGenerator initializer call to pass the new Masjid and class names.

  3. Remove the @AppStorage properties for masjidName and className if they are no longer needed because the names will be managed through the QuizPreferences structure.

Here's an example of how you might modify the PDFPreviewView struct:

struct PDFPreviewView: View {
    @ObservedObject var viewModel: QuizView.ViewModel
    
    var body: some View {
        NavigationLink {
            VStack {
                // ... (other code remains unchanged)

                // Update the PDFKitView initializer to use the updated QuizPreferences
                PDFKitView(
                    documentData: PDFGenerator(
                        verses: viewModel.quizVerses,
                        words: viewModel.wordsForWordsMeaning,
                        preferences: QuizPreferences(
                            quizHeader: QuizPreferences.QuizHeader(
                                topRightText: viewModel.preferences.className, // Updated to use viewModel
                                topLeftText: viewModel.preferences.masjidName  // Updated to use viewModel
                            )
                        )
                    )
                    .generateQuiz()
                )
                // ... (other code remains unchanged)
            }
        } label: {
            // ... (label code remains unchanged)
        }
    }
}

In the above code, viewModel.preferences.className and viewModel.preferences.masjidName are placeholders for where you would access the updated class and Masjid names from the QuizPreferences structure. You will need to ensure that the viewModel has access to the updated QuizPreferences that includes these properties.

Remember to test the changes to ensure that the Masjid and class names are correctly displayed in the PDF preview and that the PDF document is generated as expected with the new settings.

Changes on QuranMajeed/Quiz/QuizSettings/QuizPreferences.swift

To solve the task for the QuizPreferences.swift file, we need to add properties to the QuizPreferences structure that will hold the new Masjid and class names. Here's a practical proposal for the changes:

//
//  QuizPreferences.swift
//  Al-Tanzeel
//
//  Created by Takasur Azeem on 16/02/2024.
//  Copyright © 2024 Islam. All rights reserved.
//

import Foundation

struct QuizPreferences {
    struct QuizHeader {
        var topRightText: String
        var topLeftText: String
        var masjidName: String // New property for Masjid name
        var className: String // New property for class name
    }
    
    var quizHeader: QuizHeader
    var quizDate = Date.now
    
    // Initializer to set default values or load existing settings
    init(topRightText: String = "Default Top Right",
         topLeftText: String = "Default Top Left",
         masjidName: String = "Default Masjid",
         className: String = "Default Class") {
        self.quizHeader = QuizHeader(topRightText: topRightText,
                                     topLeftText: topLeftText,
                                     masjidName: masjidName,
                                     className: className)
    }
}

With these changes, the QuizPreferences structure now includes properties for the Masjid and class names. The initializer is also updated to allow setting default values or loading existing settings for these new properties. This will facilitate the persistence and retrieval of the Masjid and class names in the data store, which will be handled in the Datastore.swift and FileDatastore.swift files by another agent.

Changes on QuranMajeed/Quiz/QuizSettings/QuizSettingsView.swift

To solve the task of adding the capability to change the name of the Masjid and class via a settings module, we need to modify the QuizSettingsView.swift file to include TextFields for user input and a button to save the changes. Here's a practical proposal for the changes:

  1. Add two TextField views to allow the user to input new names for the Masjid and the class.
  2. Add a Button that will save the changes made by the user to the AppStorage.

Here's the updated code for QuizSettingsView.swift:

import SwiftUI

struct QuizSettingsView: View {
    @AppStorage("MasjidName") private var masjidName: String = ""
    @AppStorage("ClassName") private var className: String = ""
    private let masjidNameLabel: String = "Masjid Name"
    private let classNameLabel: String = "Class Name"
    
    var body: some View {
        List {
            Section(header: Text("Settings")) {
                VStack(alignment: .leading) {
                    Text(masjidNameLabel)
                        .font(.headline)
                    TextField("Enter Masjid Name", text: $masjidName)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding(.bottom)
                    
                    Text(classNameLabel)
                        .font(.headline)
                    TextField("Enter Class Name", text: $className)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding(.bottom)
                    
                    Button(action: saveSettings) {
                        Text("Save Changes")
                            .bold()
                            .frame(maxWidth: .infinity)
                    }
                    .buttonStyle(RoundedRectangleButtonStyle())
                }
                .padding()
            }
        }
        .navigationTitle("Quiz Settings")
    }
    
    private func saveSettings() {
        // Code to save the settings will be implemented here.
        // This could involve updating the ViewModel or directly saving to AppStorage if that's the chosen approach.
    }
}

struct RoundedRectangleButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .clipShape(RoundedRectangle(cornerRadius: 8))
            .scaleEffect(configuration.isPressed ? 0.95 : 1)
    }
}

struct QuizSettingsView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationStack {
            QuizSettingsView()
        }
    }
}

In this updated code, we have:

  • Added TextField views for the Masjid and class names.
  • Included a Button with an action saveSettings that will be responsible for saving the changes.
  • Used @AppStorage property wrappers to bind the text fields to persistent storage.
  • Provided a RoundedRectangleButtonStyle to style the save button.

The saveSettings function is where you would implement the logic to save the settings. Depending on the architecture of the app, this could involve updating a ViewModel, sending a message to a controller, or directly saving to AppStorage. The specifics of this function will depend on the rest of the app's code and architecture.

Changes on QuranMajeed/Quiz/Main/ViewModel/QuizViewModel.swift

To implement the capability to change the name of the Masjid and class via a settings module in the QuizViewModel.swift file, you should follow these steps:

  1. Define Properties for Masjid and Class Names:
    Add two new @Published properties to the ViewModel class to hold the current Masjid and class names. These properties will be observed by the view for changes.
@Published var masjidName: String = ""
@Published var className: String = ""
  1. Create Methods to Update Names:
    Implement methods within the ViewModel class to update the Masjid and class names. These methods will be called when the user submits the new names from the settings view.
func updateMasjidName(to newName: String) {
    masjidName = newName
    saveSettings()
}

func updateClassName(to newName: String) {
    className = newName
    saveSettings()
}
  1. Persisting Changes:
    Create a saveSettings method that will persist the changes to the data store. This method will interact with the Datastore class or any other persistence service you have in your application.
private func saveSettings() {
    // Assuming Datastore has methods to save settings
    Datastore.shared.saveMasjidName(masjidName)
    Datastore.shared.saveClassName(className)
}
  1. Loading Initial Settings:
    In the init method or a dedicated loadSettings method, load the initial Masjid and class names from the data store and assign them to the properties.
init(
    theQuranRepository: QuranRepository
) {
    self.theQuranRepository = theQuranRepository
    // ... existing code ...
    loadSettings()
}

private func loadSettings() {
    masjidName = Datastore.shared.loadMasjidName() ?? "Default Masjid"
    className = Datastore.shared.loadClassName() ?? "Default Class"
}
  1. Error Handling:
    Add error handling to the methods that interact with the data store. This will ensure that any issues with saving or loading settings are properly managed.
private func saveSettings() {
    do {
        try Datastore.shared.saveMasjidName(masjidName)
        try Datastore.shared.saveClassName(className)
    } catch {
        // Handle the error, possibly by showing an alert to the user
    }
}
  1. Update the View:
    Ensure that the view that displays the Masjid and class names is bound to the masjidName and className properties of the ViewModel. This way, any changes to these properties will be reflected in the UI.

Remember to also update the Datastore class or the relevant persistence service to handle the new settings for Masjid and class names. This includes adding methods to save and load these settings, as well as updating any models or structures that represent the persisted data.

Changes on QuranMajeed/Foundation/FileDatastore.swift

To update the FileDatastore.swift to include saving and loading the new Masjid and class name settings, you will need to ensure that the FileDatastore class can handle these new settings. Since the FileDatastore class is generic and supports Codable data, you can save and load any Codable structure, including the new settings.

Here's a practical proposal for updating the FileDatastore class:

  1. Define the Settings Structure: First, ensure that there is a Codable structure that represents the settings you want to save, including the Masjid and class names. This structure should be defined in a different file, likely QuizPreferences.swift.

  2. Update Save and Load Methods: The save and load methods in FileDatastore are already generic and should work for any Codable data, including the new settings structure. No changes are required here unless you want to add specific error handling or logging for the new settings.

  3. Error Handling and Logging: Consider improving error handling and logging within the save, load, delete, and flush methods to provide more detailed feedback, especially since you are adding new functionality that might require debugging.

  4. Testing: After the new settings structure is defined and integrated into the app, write unit tests to ensure that the FileDatastore can save and load the new settings correctly. Test cases should include saving new settings, loading existing settings, handling errors or missing files, and ensuring that the flush method does not inadvertently delete the new settings.

  5. Documentation: Update the documentation/comments within the FileDatastore class to reflect the new capability of handling Masjid and class name settings.

Here is an example of how the settings structure might look in QuizPreferences.swift:

struct QuizPreferences: Codable {
    var masjidName: String
    var className: String
    // ... other properties
}

And here is how you might use the FileDatastore to save and load these settings:

let preferencesDatastore = FileDatastore<QuizPreferences>(purpose: "QuizSettings")

// To save the settings
let preferences = QuizPreferences(masjidName: "New Masjid", className: "New Class")
preferencesDatastore.save(preferences, forKey: "QuizPreferences")

// To load the settings
if let loadedPreferences = preferencesDatastore.load(forKey: "QuizPreferences") {
    print("Loaded Masjid Name: \(loadedPreferences.masjidName)")
    print("Loaded Class Name: \(loadedPreferences.className)")
}

Remember to handle the possibility of the settings not existing yet when the app is first launched or after a flush. You may want to provide default values or prompt the user to enter these details if they are not found.

Disclaimer: This comment was entirely generated using AI. Be aware that the information provided may be incorrect.

Current plan usage: 21.08%

Have feedback or need help?
Discord
Documentation
[email protected]

@takasurazeem takasurazeem linked a pull request Feb 18, 2024 that will close this issue
@takasurazeem takasurazeem moved this from In Progress to Done in Quran Quiz Feb 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Archived in project
Development

Successfully merging a pull request may close this issue.

1 participant