Skip to content

Commit

Permalink
Initial implementation of purchase collection.
Browse files Browse the repository at this point in the history
  • Loading branch information
Joaoaraujo97 committed Jun 19, 2024
1 parent b2c6b3c commit 9e98536
Show file tree
Hide file tree
Showing 50 changed files with 638 additions and 59 deletions.
44 changes: 44 additions & 0 deletions assets/collections/0_chatGPT_premium.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"id": "0_chatGPT_premium",
"name": "teste",
"description": "teste",
"category": "Premium",
"tags": [
"ChatGPT"
],
"isPremium": true,
"appStoreId": "com.olmps.memo_099_in_app_purchase_deck",
"playStoreId": null,
"contributors": [
{
"name": "chatGPT",
"url": "https://www.linkedin.com/",
"imageUrl": "https://media-exp1.licdn.com/dms/image/C4E03AQFYmdJJeE9gmA/profile-displayphoto-shrink_400_400/0/1517688960443?e=1631750400&v=beta&t=bpxRB_CL0-3CaT4nzadf1PKpSblm2I_Z7yjm6gEdaBM"
}
],
"memos": [
{
"uniqueId": "03c9a8d5-9e27-4ec2-8a3c-7bf20431b890",
"question": [
{
"insert": "Testes e mais testes\n"
}
],
"answer": [
{
"insert": "Isso é mais conhecido como "
},
{
"insert": "testes",
"attributes": {
"bold": true,
"underline": true
}
},
{
"insert": ".\n"
}
]
}
]
}
5 changes: 4 additions & 1 deletion assets/collections/bdd_fundamentos_01.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"name": "BDD - Fundamentos",
"description": "Existem diversos paradigmas de desenvolvimento de software. Dentre estes, está o desenvolvimento orientado a comportamento (BDD). Neste deck, vamos conhecer um pouco sobre o BDD, uma das melhores formas de otimizar tanto seu processo de desenvolvimento quanto o produto final gerado.",
"category": "Testes",
"tags": ["tests", "bdd"],
"tags": [
"tests",
"bdd"
],
"contributors": [
{
"name": "Nicolas Nascimento",
Expand Down
5 changes: 4 additions & 1 deletion assets/collections/comecando_com_git.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"name": "Começando com Git",
"description": "\"Git é um sistema de controle de versões distribuído, usado principalmente no desenvolvimento de software, mas pode ser usado para registrar o histórico de edições de qualquer tipo de arquivo. O Git foi inicialmente projetado e desenvolvido por Linus Torvalds para o desenvolvimento do kernel Linux, mas foi adotado por muitos outros projetos.\" - Wikipedia, 2021.",
"category": "Versionamento",
"tags": ["git", "versionamento"],
"tags": [
"git",
"versionamento"
],
"contributors": [
{
"name": "@matuella",
Expand Down
6 changes: 5 additions & 1 deletion assets/collections/ecossistema_do_flutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
"name": "Ecossistema do Flutter - Fundamentos",
"description": "\"Flutter é um kit de desenvolvimento de interface de usuário (UI toolkit), de código aberto, criado pelo Google, que possibilita a criação de aplicativos compilados nativamente. Atualmente pode compilar para Android, iOS, Windows, Mac, Linux, Google Fuchsia e Web.\" - Wikipedia, 2021.",
"category": "Flutter",
"tags": ["flutter", "framework", "cross-platform"],
"tags": [
"flutter",
"framework",
"cross-platform"
],
"contributors": [
{
"name": "@matuella",
Expand Down
5 changes: 4 additions & 1 deletion assets/collections/fundamentos_scrum.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"name": "Fundamentos do Scrum",
"description": "O Scrum é um framework de gerenciamento de projetos, da organização ao desenvolvimento ágil de produtos complexos e adaptativos com o mais alto valor possível, através de várias técnicas, utilizado desde o início de 1990 e que atualmente é utilizado em mais de 60% dos projetos ágeis em todo o mundo. - Wikipedia, 2021",
"category": "Scrum",
"tags": ["agile", "scrum"],
"tags": [
"agile",
"scrum"
],
"contributors": [
{
"name": "Olympus",
Expand Down
5 changes: 4 additions & 1 deletion assets/collections/guia_scrum.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"name": "Guia do Scrum",
"description": "O guia do scrum é um documento pequeno, que descreve tudo o que existe no Scrum. Muitas pessoas que dizem conhecer o Scrum, nunca leram o documento. Não pode ser pela quantidade de páginas, que são menos de 20. O guia do scrum estabelece pilares, valores, artefatos, papéis e responsabilidades para que uma equipe possa organizar o seu fluxo de trabalho, encontrando formas de priorizar o trabalho a ser realizado, acompanhar dificuldades e progresso, revisar o trabalho feito e ainda garantir ações de melhoria ao longo do tempo.",
"category": "Scrum",
"tags": ["agile", "scrum"],
"tags": [
"agile",
"scrum"
],
"contributors": [
{
"name": "Daniel Wildt",
Expand Down
5 changes: 4 additions & 1 deletion assets/collections/kotlin_fundamentos_01.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"name": "Kotlin - Fundamentos",
"description": "Nessa coleção de memórias você vai ser introduzido na linguagem de programação Kotlin. Embora ler a documentação do Kotlin seja fácil e agradável, aprender por exemplos é um tipo diferente de diversão (confira os links abaixo).",
"category": "Kotlin",
"tags": ["kotlin", "linguagem de programação"],
"tags": [
"kotlin",
"linguagem de programação"
],
"contributors": [
{
"name": "Lucas Montano",
Expand Down
4 changes: 3 additions & 1 deletion assets/collections/manifesto_agil.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"name": "Manifesto Ágil",
"description": "Em Fevereiro de 2001, no Snowbird ski resort em Utah, 17 pessoas se apresentam para falar, se divertir e encontrar caminhos comuns nas práticas de engenharia e organização de projetos que vinham testando, validando e aprendendo. O que emerge deste encontro de 2 dias foi o Agile ‘Software Development’ Manifesto. Representantes de diferentes metodologias estavam presentes nesta data: Extreme Programming, SCRUM, DSDM, Adaptive Software Development, Crystal, Feature-Driven Development, Pragmatic Programming, e outras pessoas que eram simpáticas a necessidade de alternativas para projetos direcionados por documentação, normalmente direcionados por processos de desenvolvimento de software pesados. Todos signatários terminam o encontro com o termo Agile, termo que aparece em cena por indicação de Martin Fowler, que já aparecia na cena de eXtreme Programming anos anteriores.",
"category": "Metodologia Ágil",
"tags": ["agile"],
"tags": [
"agile"
],
"contributors": [
{
"name": "Daniel Wildt",
Expand Down
5 changes: 4 additions & 1 deletion assets/collections/swift_fundamentos_01.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"name": "Fundamentos de Swift I",
"description": "\"Swift é uma linguagem de programação desenvolvida pela Apple para desenvolvimento no iOS, macOS, watchOS, tvOS e Linux. O compilador usa a infraestrutura do LLVM e é distribuído junto do Xcode desde a versão 6.\" - Wikipedia, 2021",
"category": "Swift",
"tags": ["swift", "linguagem de programação"],
"tags": [
"swift",
"linguagem de programação"
],
"contributors": [
{
"name": "@matuella",
Expand Down
Binary file added assets/images/icons/2.0x/lock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/icons/3.0x/lock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/icons/lock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 8 additions & 5 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -165,7 +165,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down Expand Up @@ -212,10 +212,12 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
Expand Down Expand Up @@ -266,6 +268,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down Expand Up @@ -379,7 +382,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down Expand Up @@ -461,7 +464,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -512,7 +515,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
1 change: 1 addition & 0 deletions lib/application/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class AppRoot extends StatelessWidget {
executionServices.overrideWithValue(state.executionServices),
progressServices.overrideWithValue(state.progressServices),
resourceServices.overrideWithValue(state.resourceServices),
collectionPurchaseServices.overrideWithValue(state.collectionPurchaseServices)
],
child: _LoadedAppRoot(),
),
Expand Down
2 changes: 2 additions & 0 deletions lib/application/constants/dimensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const double genericBorderHeight = 2;
const textTagBorderRadius = BorderRadius.all(Radius.circular(2));
const double cardBorderWidth = 4;

const double collectionsBlurSize = 5;

const double resourceLinkEmojiTextSize = 20;

const double iconSize = 24;
Expand Down
3 changes: 3 additions & 0 deletions lib/application/constants/exception_strings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ String descriptionForException(BaseException exception) {

case ExceptionType.failedToOpenUrl:
return 'Algo deu errado ao tentar abrir o link!';

case ExceptionType.failedPurchase:
return 'Algo deu errado ao tentar realizar a compra!';
default:
return 'Algo deu errado. Por favor tente novamente';
}
Expand Down
4 changes: 4 additions & 0 deletions lib/application/constants/images.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum ImageKey {
folder,
italic,
link,
lock,
organize,
settings,
trash,
Expand Down Expand Up @@ -61,6 +62,8 @@ extension ImageKeyPath on ImageKey {
return '$_editorIconsRoot/italic.png';
case ImageKey.link:
return '$_iconsRoot/link.png';
case ImageKey.lock:
return '$_iconsRoot/lock.png';
case ImageKey.organize:
return '$_iconsRoot/organize.png';
case ImageKey.settings:
Expand Down Expand Up @@ -100,6 +103,7 @@ final dragAsset = ImageKey.drag.path;
final folderAsset = ImageKey.folder.path;
final italicAsset = ImageKey.italic.path;
final linkAsset = ImageKey.link.path;
final lockAsset = ImageKey.lock.path;
final organizeAsset = ImageKey.organize.path;
final settingsAsset = ImageKey.settings.path;
final trashAsset = ImageKey.trash.path;
Expand Down
4 changes: 4 additions & 0 deletions lib/application/constants/strings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const collectionsSectionHeaderSeeAll = 'Ver todos';

const collectionsStartNow = 'Começar Agora';

const collectionPurchase = 'Deseja comprar este Deck?';
const collectionSuccessPurchase = 'Deck comprado com sucesso!';

String collectionsEmptyTitleSegment(CollectionsSegment segment) {
switch (segment) {
case CollectionsSegment.explore:
Expand Down Expand Up @@ -186,6 +189,7 @@ const memos = 'Memos';
const next = 'Próximo';
const cancel = 'Cancelar';
const remove = 'Remover';
const purchase = 'Comprar';

const recallLevel = 'Nível de Fixação';

Expand Down
1 change: 0 additions & 1 deletion lib/application/pages/execution/execution_terminal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ class _TerminalQuillEditor extends StatelessWidget {
padding: EdgeInsets.symmetric(
vertical: dimens.terminalWindowHeaderHeight, horizontal: context.rawSpacing(Spacing.medium)),
autoFocus: false,
readOnly: true,
showCursor: false,
expands: false,
enableInteractiveSelection: false,
Expand Down
81 changes: 62 additions & 19 deletions lib/application/pages/home/collections/collections_list_view.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:layoutr/common_layout.dart';
import 'package:memo/application/constants/strings.dart' as strings;
import 'package:memo/application/coordinator/routes_coordinator.dart';
import 'package:memo/application/theme/theme_controller.dart';
import 'package:memo/application/utils/bottom_sheet.dart';
import 'package:memo/application/utils/scaffold_messenger.dart';
import 'package:memo/application/view-models/home/collections_vm.dart';
import 'package:memo/application/view-models/item_metadata.dart';
import 'package:memo/application/widgets/theme/custom_button.dart';
import 'package:memo/application/widgets/theme/item_collection_card.dart';
import 'package:memo/core/faults/errors/inconsistent_state_error.dart';

Expand All @@ -14,25 +19,47 @@ class CollectionsListView extends ConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
// Builds the respective widget based on the item's `ItemMetadata` subtype.
final item = items[index];

if (item is CollectionsCategoryMetadata) {
return _CollectionsSectionHeader(title: item.name)
.withOnlyPadding(context, top: Spacing.xLarge, bottom: Spacing.small);
} else if (item is CollectionItem) {
return buildCollectionCardFromItem(
item,
padding: context.symmetricInsets(vertical: Spacing.large, horizontal: Spacing.small),
onTap: () => readCoordinator(ref).navigateToCollectionDetails(item.id),
).withOnlyPadding(context, bottom: Spacing.medium);
}

throw InconsistentStateError.layout('Unsupported subtype (${item.runtimeType}) of `CollectionItemMetadata`');
},
final vm = ref.watch(collectionsVM.notifier);

ref.listen(collectionsVM, (_, state) {
if (state is PurchaseCollectionFailed) {
Navigator.of(context).pop();
showExceptionSnackBar(ref, state.exception);
}
if (state is PurchaseCollectionSuccess) {
Navigator.of(context).pop();
showSnackBar(
ref,
const SnackBar(content: Text(strings.collectionSuccessPurchase)),
);
}
});

return RefreshIndicator(
onRefresh: vm.onRefresh,
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
// Builds the respective widget based on the item's `ItemMetadata` subtype.
final item = items[index];

if (item is CollectionsCategoryMetadata) {
return _CollectionsSectionHeader(title: item.name)
.withOnlyPadding(context, top: Spacing.xLarge, bottom: Spacing.small);
} else if (item is CollectionItem) {
return buildCollectionCardFromItem(
item,
padding: context.symmetricInsets(vertical: Spacing.large, horizontal: Spacing.small),
onTap: item.isVisible
? () async => collectionPurchaseBottomSheet(context, () => vm.purchaseCollection(item.id))
: () => readCoordinator(ref).navigateToCollectionDetails(item.id),
isVisible: item.isVisible,
).withOnlyPadding(context, bottom: Spacing.medium);
}

throw InconsistentStateError.layout('Unsupported subtype (${item.runtimeType}) of `CollectionItemMetadata`');
},
),
);
}
}
Expand All @@ -50,3 +77,19 @@ class _CollectionsSectionHeader extends ConsumerWidget {
return Text(title, style: sectionTitleStyle);
}
}

/// This Modal Bottom Sheet representing the option to purchase a specific `Collection`.
Future<void> collectionPurchaseBottomSheet(BuildContext context, VoidCallback? onPressed) =>
showSnappableDraggableModalBottomSheet<void>(
context,
title: strings.collectionPurchase,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
context.verticalBox(Spacing.xLarge),
PrimaryElevatedButton(text: strings.purchase, onPressed: onPressed),
context.verticalBox(Spacing.medium),
SecondaryElevatedButton(text: strings.cancel, onPressed: Navigator.of(context).pop),
],
).withAllPadding(context, Spacing.medium),
);
Loading

0 comments on commit 9e98536

Please sign in to comment.