Skip to content

Commit 237c3eb

Browse files
committed
chore: update README.md
1 parent bd43405 commit 237c3eb

File tree

1 file changed

+90
-55
lines changed

1 file changed

+90
-55
lines changed

README.md

Lines changed: 90 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
11
<p align="center">
2-
<img alt="A" title="B" src="https://github.com/user-attachments/assets/65f88513-376c-4778-906e-a0722c463678" width="150">
3-
<h1 align="center"> Giffy</h1>
2+
<!-- <img alt="A" title="B" src="https://github.com/user-attachments/assets/65f88513-376c-4778-906e-a0722c463678" width="150">
3+
<h1 align="center"> Giffy</h1> -->
4+
<img width="1000" alt="Giffy Thumbnail" src="https://github.com/user-attachments/assets/1b3c8c8f-6d87-4d67-baaa-aa35d1a97f71" />
45
<p align="center">
5-
<br>
6-
7-
<p align="center">
8-
<img alt="A" title="B" src="https://github.com/uwaisalqadri/GiphyGIF/assets/55146646/2d216304-130c-4007-8308-efbf85f0732d" width="200">
9-
<img alt="B" title="B" src="https://github.com/uwaisalqadri/GiphyGIF/assets/55146646/cb299bd3-6aff-4dd4-9ed8-990a55a098b6" width="200">
10-
<img alt="C" title="C" src="https://github.com/uwaisalqadri/GiphyGIF/assets/55146646/b7eb36c1-7e7b-42f9-a2f9-cbd090b7659b" width="200">
11-
<img alt="D" title="D" src="https://github.com/uwaisalqadri/GiphyGIF/assets/55146646/591de856-cc69-414f-bf41-7b319d1236f2" width="200">
12-
</p>
13-
14-
156

167
## <a name="introduction"></a> 🤖 Introduction
178

18-
Giphy Client App built with some of the interesting iOS tech such as **TCA (The Composable Architecture by Point-Free)**, **Swinject**, Beautiful UI built with **SwiftUI**, **Clean Architecture with Generic Protocol Approach**, **SPM Modularization** and **XcodeGen!**
9+
A GIF app built with exciting iOS technologies, including **TCA (The Composable Architecture by pointfree.co)**, **Swinject**, and a beautiful UI crafted with **SwiftUI**. It follows **Clean Architecture with a Generic Protocol Approach**, incorporates **SPM Modularization**, and leverages **XcodeGen** for project structure management!
1910

2011
**Module**
2112

22-
* **`Giffy`**: the main app with presentation layer
23-
* **`Common`**: domain and data layer
24-
* **`CommonUI`**: common utils and assets
25-
* **`Core`**: generic protocol for _DataSource_ and _Interactor_
13+
* **`Giffy`**: The main app containing the presentation layer
14+
* **`Common`**: Handles the domain and data layers
15+
* **`CommonUI`**: Includes common utilities and assets
16+
* **`Core`**: Defines generic protocols for _DataSource_ and _Interactor_
2617

2718
## Table of Contents
2819

@@ -37,7 +28,7 @@ Giphy Client App built with some of the interesting iOS tech such as **TCA (The
3728
## <a name="features"></a> 🦾 Features
3829

3930
- Sharing, Copy-Pasting, and AirDropping GIFs and Stickers
40-
- Search GIFs from various sources (Giphy and Tenor
31+
- Search GIFs from various sources (Giphy and Tenor)
4132
- Save Favorite GIFs
4233
- Widget, Live Activty, and Dynamic Island
4334
- Animations!
@@ -140,9 +131,11 @@ public struct FavoriteReducer: Reducer {
140131
```
141132

142133
**Composing** the Reducer
134+
143135
```swift
144136
struct MainTabView: View {
145137
let store: StoreOf<MainTabReducer>
138+
@StateObject var tabState = MainTabStateHolder()
146139

147140
var body: some View {
148141
WithViewStore(store, observe: \.selectedTab) { viewStore in
@@ -164,60 +157,102 @@ struct MainTabView: View {
164157
action: \.search
165158
)
166159
)
167-
}
168-
160+
169161
. . . .
170162

163+
}
164+
165+
if !tabState.isShowShare {
166+
VStack {
167+
Spacer()
168+
CapsuleTabView(
169+
currentTab: viewStore.binding(
170+
send: MainTabReducer.Action.selectedTabChanged
171+
)
172+
).padding(.bottom, 20)
173+
}
174+
}
171175
}
172-
}
176+
.animation(.easeInOut(duration: 0.2), value: viewStore.state)
177+
}.environmentObject(tabState)
173178
}
174179
}
175180
}
176181
```
177182

178-
_"consistent and understandable"_ **- Point-Free**
183+
_"consistent and understandable"_ **- pointfree.co**
179184

180185

181186
Let your _**Store**_(d) _**Reducer**_ update the View
182187

183188
```swift
184189
struct FavoriteView: View {
190+
@Environment(\.dismiss) var pop
185191
let store: StoreOf<FavoriteReducer>
186192

187193
var body: some View {
188194
WithViewStore(store, observe: { $0 }) { viewStore in
189-
ScrollView {
190-
SearchField { query in
191-
viewStore.send(.fetch(request: query))
192-
}.padding(.vertical, 20)
193-
194-
if viewStore.state.list.isEmpty {
195-
FavoriteEmptyView()
196-
.padding(.top, 50)
195+
ZStack {
196+
ScrollView(.vertical, showsIndicators: false) {
197+
SearchField { query in
198+
viewStore.send(.fetch(request: query))
199+
}
200+
.padding(.horizontal, 16)
201+
.padding(.vertical, 20)
202+
.padding(.top, 52)
203+
204+
if viewStore.state.list.isEmpty {
205+
FavoriteEmptyView()
206+
.padding(.top, 50)
207+
}
208+
209+
LazyVStack {
210+
ForEach(viewStore.state.list, id: \.id) { item in
211+
GiffyRow(
212+
isFavorite: true,
213+
giphy: item,
214+
onTapRow: { giphy in
215+
viewStore.send(.showDetail(item: giphy))
216+
},
217+
onFavorite: { giphy in
218+
viewStore.send(.removeFavorite(item: giphy, request: ""))
219+
},
220+
onShare: { image in
221+
viewStore.send(.showShare(image))
222+
}
223+
)
224+
.padding(.horizontal, 16)
225+
.padding(.bottom, 20)
226+
}
227+
}
228+
}
229+
.scrollDismissesKeyboard(.immediately)
230+
.animation(.easeInOut(duration: 0.2), value: viewStore.list.count)
231+
.navigationBarBackButtonHidden(false)
232+
.navigationBarTitleDisplayMode(.inline)
233+
.showDialog(
234+
shouldDismissOnTapOutside: true,
235+
isShowing: viewStore.binding(
236+
get: { $0.shareImage != nil },
237+
send: .showShare(nil)
238+
)
239+
) {
240+
ShareView(store: viewStore.share)
241+
}
242+
.onAppear {
243+
viewStore.send(.fetch())
244+
}
245+
.onReceive(viewStore.state.detailDisappear) { _ in
246+
viewStore.send(.fetch())
197247
}
198248

199-
LazyVStack {
200-
ForEach(viewStore.state.list, id: \.id) { item in
201-
GiphyItemRow(
202-
isFavorite: true,
203-
giphy: item,
204-
onTapRow: { giphy in
205-
viewStore.send(.showDetail(item: giphy))
206-
},
207-
onFavorite: { giphy in
208-
viewStore.send(.removeFavorite(item: giphy, request: ""))
209-
}
210-
)
211-
.padding(.horizontal, 20)
212-
.padding(.bottom, 20)
249+
VStack {
250+
FavoriteToolbar(title: Localizable.titleFavorite.tr()) {
251+
pop()
213252
}
253+
Spacer()
214254
}
215255
}
216-
.padding(.horizontal, 10)
217-
.navigationTitle(FavoriteString.titleFavorite.localized)
218-
.onAppear {
219-
viewStore.send(.fetch(request: ""))
220-
}
221256
}
222257
}
223258
}
@@ -297,7 +332,9 @@ Injection.resolve()
297332
Read more about [**Swinject**](https://github.com/Swinject/Swinject)
298333

299334
## <a name="buy-me-coffee"></a> ☕️ Buy Me a Coffee
300-
If you like this project please support me by <a href="https://www.buymeacoffee.com/uwaisalqadri" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee" height=32></a> ;-)
335+
<a href="https://www.buymeacoffee.com/uwaisalqadri" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me A Coffee" height=32></a>
336+
<br>
337+
👆 Support me 👆
301338

302339
## <a name="project-structure"></a> 🏛 Project Structure
303340

@@ -311,9 +348,8 @@ If you like this project please support me by <a href="https://www.buymeacoffee.
311348
- `Favorite`
312349
- `Search`
313350

314-
315-
- `**GiffyWidget**`
316-
- `**GiffyTests**`
351+
- **`GiffyWidget`**
352+
- **`GiffyTests`**
317353

318354
**`Modules`**:
319355

@@ -332,8 +368,7 @@ If you like this project please support me by <a href="https://www.buymeacoffee.
332368

333369
**`CommonUI`**:
334370
- `Assets`
335-
- `Extensions`
336-
- `Modifier`
371+
- `ReusableViews`
337372
- `Utils`
338373

339374
[**`Core`**](https://github.com/uwaisalqadri/CoreModule):

0 commit comments

Comments
 (0)