Skip to content

Commit

Permalink
Merge pull request #19 from magicbell-io/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
josuemontano authored Dec 30, 2021
2 parents a636123 + 8e9280d commit e54f55b
Show file tree
Hide file tree
Showing 36 changed files with 1,433 additions and 485 deletions.
353 changes: 57 additions & 296 deletions Example/Example.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion Example/Example/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import UIKit
import MagicBell
import UserNotifications

let magicBell = MagicBell(apiKey: "34ed17a8482e44c765d9e163015a8d586f0b3383", logLevel: .debug)
// Application available instance of MagicBell
let magicBell = MagicBell(
apiKey: "34ed17a8482e44c765d9e163015a8d586f0b3383",
logLevel: .debug
)

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand Down
28 changes: 28 additions & 0 deletions Example/Example/Helpers/Appearance.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Appearance.swift
// Example
//
// Created by Joan Martin on 28/12/21.
//

import Foundation
import UIKit

extension UIColor {
static let magicBell = UIColor(rgb: 0x6113A3)
}


enum Appearance {
static func apply() {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .magicBell
appearance.titleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.white // nav text color
]
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = UINavigationBar.appearance().standardAppearance
UINavigationBar.appearance().tintColor = .white
}
}
File renamed without changes.
16 changes: 16 additions & 0 deletions Example/Example/Helpers/UIHostingViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// UIHostingViewController.swift
// Example
//
// Created by Joan Martin on 28/12/21.
//

import Foundation
import UIKit
import SwiftUI

class HostingController<ContentView>: UIHostingController<ContentView> where ContentView: View {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
40 changes: 39 additions & 1 deletion Example/Example/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
//

import UIKit
import SwiftUI
import MagicBell

enum Style {
case uiKit
case swiftUI
}

// Change style to determine how to run the app
let style: Style = .uiKit
// let style: Style = .swiftUI

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

Expand All @@ -17,7 +28,34 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are
// new (see `application:configurationForConnectingSceneSession` instead).
// guard let _ = (scene as? UIWindowScene) else { return }

guard let scene = scene as? UIWindowScene else {
return
}

Appearance.apply()

window = UIWindow(windowScene: scene)

// Defining the user to test
let userBell = magicBell.forUser(email: "john@doe.com")

switch style {
case .uiKit:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let viewController = storyboard.instantiateInitialViewController() as? MagicBellStoreViewController else {
fatalError("Invalid Storyboard")
}
viewController.userBell = userBell
window?.rootViewController = viewController
case .swiftUI:
let store = userBell.store.forAll()
window?.rootViewController = HostingController(rootView: NavigationView {
MagicBellView(store: store)
})
}

window?.makeKeyAndVisible()
}

func sceneDidDisconnect(_ scene: UIScene) {
Expand Down
172 changes: 172 additions & 0 deletions Example/Example/SwiftUI/MagicBellView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
//
// MagicBellView.swift
// Example
//
// Created by Joan Martin on 28/12/21.
//

import SwiftUI
import MagicBell
import struct MagicBell.Notification

struct MagicBellView: View {
let store: NotificationStore

@ObservedObject
private var bell: NotificationStorePublisher

init(store: NotificationStore) {
self.store = store
self.bell = NotificationStorePublisher(store)
}

enum SheetType {
case none
case notification(Notification)
case globalActions
}

@State var presentSheet = false
@State var sheetType: SheetType = .none

var body: some View {
List {
Section {
ForEach(bell.notifications, id: \.id) { notification in
Button {
sheetType = .notification(notification)
presentSheet = true
} label: {
HStack {
VStack(alignment: .leading) {
Text(notification.title)
.font(Font.system(size: 16, weight: .semibold))
Spacer()
.frame(height: 8)
Text(notification.content ?? "No Content")
.font(Font.system(size: 14, weight: .regular))
}
Spacer()
if !notification.isRead {
Circle()
.fill(Color(UIColor.magicBell))
.frame(width: 6, height: 6)
}
}
.padding([.top, .bottom], 3)
}
.buttonStyle(.plain)
}
} header: {
Text("\(bell.totalCount) Notifications (\(bell.unreadCount) unread)")
} footer: {
if bell.hasNextPage {
Button {
store.fetch()
} label: {
HStack {
Spacer()
Text("Load More")
Spacer()
}
}
}
}
}
.refreshable {
// Pull-to-refresh action
store.refresh()
}
.listRowInsets(.none)
.listStyle(.grouped)
.navigationBarTitle("MagicBell", displayMode: .inline)
.navigationBarItems(
trailing: Button(action: {
sheetType = .globalActions
presentSheet = true
}, label: {
ZStack(alignment: .top) {
Image("magicbellicon")
.renderingMode(.template)
.colorMultiply(.white)
if bell.unseenCount > 0 {
HStack {
Spacer()
Text("\(bell.unseenCount)")
.font(Font.system(size: 12, weight: .bold))
.padding([.trailing, .leading], 3)
.foregroundColor(.white)
.background(Color.red)
.cornerRadius(10)
}
}
}
})
)
.onAppear {
if store.isEmpty {
store.refresh()
}
}
.actionSheet(isPresented: $presentSheet) {
switch sheetType {
case .none:
fatalError("Should never happen")
case .notification(let notification):
return actionSheetFor(notification)
case .globalActions:
return globalActionSheet()
}
}
}

private func globalActionSheet() -> ActionSheet {
ActionSheet(
title: Text("Action"),
buttons: [
.default(Text("Mark all read")) {
_ = store.markAllRead()
},
.default(Text("Mark all seen")) {
_ = store.markAllSeen()
},
.cancel()
]
)
}

private func actionSheetFor(_ notification: Notification) -> ActionSheet {
ActionSheet(
title: Text(notification.title),
buttons: [
.default(Text("\(notification.isRead ? "Mark unread" : "Mark read")")) {
if notification.isRead {
_ = store.markAsUnread(notification)
} else {
_ = store.markAsRead(notification)
}
},
.default(Text("\(notification.isArchived ? "Unarchive": "Archive")")) {
if notification.isArchived {
_ = store.unarchive(notification)
} else {
_ = store.archive(notification)
}
},
.destructive(Text("Delete")) {
_ = store.delete(notification)
},
.cancel()
]
)
}
}

struct MagicBellView_Previews: PreviewProvider {
static let user = magicBell.forUser(email: "john@doe.com")
static var previews: some View {
NavigationView {
MagicBellView(store: user.store.forAll())
}
}
}
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit e54f55b

Please sign in to comment.