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

#89 add feedback option #94

Merged
merged 2 commits into from
Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Calq.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
F1A53D002A196BFF0045C5B0 /* ListBackgroundModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A53CFF2A196BFF0045C5B0 /* ListBackgroundModifier.swift */; };
F1A53D032A196C220045C5B0 /* WeightViewmodel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A53D022A196C220045C5B0 /* WeightViewmodel.swift */; };
F1A59A3E2A6347880039C95E /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A59A3D2A6347880039C95E /* ToastView.swift */; };
F1A6D63B2B52CBDC00E8CD1F /* FeedbackService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A6D63A2B52CBDC00E8CD1F /* FeedbackService.swift */; };
F1A7102B2A4345BF00255F10 /* NewGradeVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A7102A2A4345BF00255F10 /* NewGradeVM.swift */; };
F1A7102D2A43757D00255F10 /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A7102C2A43757D00255F10 /* CardView.swift */; };
F1A710332A437F8300255F10 /* exampleData_v1.json in Resources */ = {isa = PBXBuildFile; fileRef = F1A710322A437F8300255F10 /* exampleData_v1.json */; };
Expand Down Expand Up @@ -212,6 +213,7 @@
F1A53CFF2A196BFF0045C5B0 /* ListBackgroundModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListBackgroundModifier.swift; sourceTree = "<group>"; };
F1A53D022A196C220045C5B0 /* WeightViewmodel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeightViewmodel.swift; sourceTree = "<group>"; };
F1A59A3D2A6347880039C95E /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = "<group>"; };
F1A6D63A2B52CBDC00E8CD1F /* FeedbackService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbackService.swift; sourceTree = "<group>"; };
F1A7102A2A4345BF00255F10 /* NewGradeVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewGradeVM.swift; sourceTree = "<group>"; };
F1A7102C2A43757D00255F10 /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = "<group>"; };
F1A710322A437F8300255F10 /* exampleData_v1.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = exampleData_v1.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -425,6 +427,7 @@
F11257912B48688900BE5D10 /* Util+GradeType.swift */,
F11257862B484AAA00BE5D10 /* Util+Subjects.swift */,
F11257842B484A8E00BE5D10 /* Util+Tests.swift */,
F1A6D63A2B52CBDC00E8CD1F /* FeedbackService.swift */,
);
path = Util;
sourceTree = "<group>";
Expand Down Expand Up @@ -818,6 +821,7 @@
F19B10A529AF84C000B11C82 /* OverviewVM.swift in Sources */,
F17F444A298C4EE7000A3993 /* SubjectListScreen.swift in Sources */,
DD81F6832759091600B4A43B /* JSONUtil.swift in Sources */,
F1A6D63B2B52CBDC00E8CD1F /* FeedbackService.swift in Sources */,
F1A772112A17947A004B8DCC /* Model.xcdatamodeld in Sources */,
F1A05C5F2A642670003734F2 /* StringExtension.swift in Sources */,
DD8813792764D58B00EB6BD8 /* BarChart.swift in Sources */,
Expand Down
35 changes: 35 additions & 0 deletions Calq/Screens/SettingsScreens/SettingsScreen/SettingsScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ struct SettingsScreen: View {
EditSubjectScreen(vm: EditSubjectViewModel(subject: vm.selectedSubjet!), editSubjectPresented: $vm.editSubjectPresented).onDisappear(perform: vm.reloadAndSave)
}
}
.sheet(isPresented: $vm.showFeedbackSheet, content: {
feeedbackSheet()
})
.alert(isPresented: $vm.deleteAlert) {
settingsAlert()
}
Expand Down Expand Up @@ -140,6 +143,10 @@ struct SettingsScreen: View {
UIApplication.shared.open(url)
}
})

SettingsIcon(color: Color(hexString: "c14f9f"), icon: "bubble.right.fill", text: "settings.feedback.title") {
vm.showFeedbackSheet = true
}
}
}

Expand All @@ -163,6 +170,34 @@ struct SettingsScreen: View {
}
}

func feeedbackSheet() -> some View {
VStack {
Text("settings.feedback.title")
.font(.headline)

if vm.feedbackError {
Text("settings.feedback.error")
.foregroundColor(.red)
}

TextEditor(text: $vm.feedbackContent)
.multilineTextAlignment(.leading)
.background(Color.gray.opacity(0.3))
.cornerRadius(8)
.frame(minHeight: 50)
.shadow(radius: 5)

Text("\(vm.feedbackContent.count)settings.feedback.textlimit")
.foregroundColor(vm.feedbackContent.count >= 1000 ? .red : .gray)
.font(.footnote)

Button("settings.feedback.button", action: {
vm.sendFeedback()
}).disabled(vm.feedbackContent.count >= 1000)
.buttonStyle(PrimaryStyle())
}.padding()
}

func contextAction_addGradeButton() -> some View {
Button {
tabBarVM.selectedIndex = 2
Expand Down
15 changes: 15 additions & 0 deletions Calq/Screens/SettingsScreens/SettingsScreen/SettingsVM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class SettingsViewModel: ObservableObject {
@Published var importedJson: String = ""
@Published var importeJsonURL: URL = URL(fileURLWithPath: "")

// Feedback
@Published var feedbackContent: String = "ABC"
@Published var showFeedbackSheet = false
@Published var feedbackError = false

func reloadAndSave() {
saveCoreData()
subjects = Util.getAllSubjects()
Expand Down Expand Up @@ -96,4 +101,14 @@ class SettingsViewModel: ObservableObject {
selectedSubjet = subject
editSubjectPresented = true
}

func sendFeedback() {
if FeedbackService.sendFeedback(feedbackContent) {
showFeedbackSheet = false
feedbackContent = "ABC"
feedbackError = false
} else {
feedbackError = true
}
}
}
4 changes: 4 additions & 0 deletions Calq/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
"settingsWeight"= "Wertung ändern";
"settingsLoadDemo"= "Demo Daten laden";
"settingsDelete"= "Daten löschen";
"settings.feedback.title"="Feedback";
"settings.feedback.button"="Feedback schicken";
"%lldsettings.feedback.textlimit"="Zeichenanzahl: %lld/1000";
"settings.feedback.error"="Etwas ist schief gelaufen :c";

"editSubjectNameInvalid"="Name ungültig";
"editSubjecNameInvalidChars"="Name darf keine Sonderzeichen/Zahlen etc. enthalten oder leer sein";
Expand Down
4 changes: 4 additions & 0 deletions Calq/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
"settingsWeight"= "Change Weigth";
"settingsLoadDemo"= "Load Demo Data";
"settingsDelete"= "Delete Data";
"settings.feedback.title"="Feedback";
"settings.feedback.button"="Send Feedback";
"%lldsettings.feedback.textlimit"="Characters count: %lld/1000";
"settings.feedback.error"="Something went wrong :c";

"editSubjectNameInvalid"="Name invalid";
"editSubjecNameInvalidChars"="Name should not include special characters or be empty";
Expand Down
50 changes: 50 additions & 0 deletions Calq/lib/Util/FeedbackService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// FeedbackService.swift
// Calq
//
// Created by Kiara on 13.01.24.
//

import Foundation
import UIKit

class FeedbackService {
static let version = "Version: \(appVersion) Build: \(buildVersion)"
static let app = Bundle.main.infoDictionary?["CFBundleName"] ?? "Calq"
static let device = UIDevice.current.name + " iOS: " + UIDevice.current.systemVersion

static func sendFeedback(_ content: String) -> Bool {
guard let url = URL(string: "https://discord.com/api/webhooks/1195726763649671168/XQATWsv9xGYVdamGsZDuc6kPX3hGyu5v5iC_wWssqErq2riswmA3vriFKMbiOcq6Pvxs") else { return false }
let message = "\(content)\n-----------------------\n**\(version)**\n*\(device)*"

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "content-type")
request.httpBody = makeEmbed(message)

let task = URLSession.shared.dataTask(with: request)
task.resume()
return true
}

private static func makeEmbed(_ content: String) -> Data {
let feedback = Feedback(embeds: [Feedback.Embed(title: "\(app) Feedback", color: "7194610", description: content)])

do {
let data = try JSONEncoder().encode(feedback)
return data
} catch {
return Data()
}
}
}

struct Feedback: Codable {
var embeds: [Embed]

struct Embed: Codable {
var title: String
var color: String
var description: String
}
}