Skip to content

Commit

Permalink
Merge pull request #1 from jamisonderek/jamisonderek/corefiles
Browse files Browse the repository at this point in the history
Initial check-in for gemini app
  • Loading branch information
d4rks1d33 authored Sep 30, 2024
2 parents 72449e8 + 8ff9c9d commit 2121b05
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 4 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Currently in development stage, here I'm going to upload the .js code that I currently use so that anyone who wants to join and help improve it can make their PRs and also for those C developers who want to help create the native Flipper app and be accessible by everyone from https://lab.flipper.net/apps

# How it is work
## How it is work

Currently the code takes the api key in plain text stored in:

Expand All @@ -18,7 +18,7 @@ I added a menu to show stored APs so the user just need to select to one that wa

I added the source code of the new firmware for the esp32 and also the pre-compile binary for ESP-Flasher app (You can find the binary in the relases section)

# How to flash the firmware using ESP-Flasher
## How to flash the firmware using ESP-Flasher

Go to "Manual flash"

Expand All @@ -35,16 +35,20 @@ Flash it (you need to reboot the board for start using the firmware)
![Captura de pantalla 2024-09-28 213123](https://github.com/user-attachments/assets/031063aa-c4bf-4fbe-baa6-745573cc8411)


# TO DO
## TO DO

--> ~~improve the handling of how the APs are saved, currently it saves them but rewrites the previous one~~ Fixed

--> ~~improve the handling of how the saved APs are sent to the esp32 to avoid re-entering the SSID and password (Improving the previous point this should solve itself)~~ Fixed

--> ~~load the firmware binary for the esp32 (nothing to do here just load the binary)~~

# Screenshots
## Screenshots

![image](https://github.com/user-attachments/assets/3878b4a2-223d-4d23-b395-2d25cf710fed)

![image](https://github.com/user-attachments/assets/777e2d55-f9fd-4c63-bb47-450b020b80e0)

## Native app

The native app is in development. Currently it just shows the main menu and then each option shows "Under construction".
12 changes: 12 additions & 0 deletions application.fam
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
App(
appid="gemini_ia",
name="Gemini IA",
apptype=FlipperAppType.EXTERNAL,
entry_point="gemini_app",
requires=["gui"],
stack_size=2 * 1024,
fap_icon="gemini.png",
fap_category="Misc",
fap_file_assets="Gemini IA",
fap_description="This is an app to interact with Google Gemini IA using the esp32.",
)
Binary file added gemini.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions gemini_app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "gemini_app_i.h"

static bool gemini_app_custom_callback(void* context, uint32_t custom_event) {
furi_assert(context);
GeminiApp* app = context;
return scene_manager_handle_custom_event(app->scene_manager, custom_event);
}

static bool gemini_app_back_event_callback(void* context) {
furi_assert(context);
GeminiApp* app = context;
return scene_manager_handle_back_event(app->scene_manager);
}

static GeminiApp* gemini_app_alloc() {
GeminiApp* app = malloc(sizeof(GeminiApp));
app->scene_manager = scene_manager_alloc(&gemini_scene_handlers, app);
app->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(app->view_dispatcher, gemini_app_custom_callback);
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, gemini_app_back_event_callback);
app->submenu = submenu_alloc();
view_dispatcher_add_view(
app->view_dispatcher, GeminiViewSubmenu, submenu_get_view(app->submenu));
app->widget = widget_alloc();
view_dispatcher_add_view(app->view_dispatcher, GeminiViewWidget, widget_get_view(app->widget));
return app;
}

static void gemini_app_free(GeminiApp* app) {
furi_assert(app);
view_dispatcher_remove_view(app->view_dispatcher, GeminiViewSubmenu);
view_dispatcher_remove_view(app->view_dispatcher, GeminiViewWidget);
scene_manager_free(app->scene_manager);
view_dispatcher_free(app->view_dispatcher);
submenu_free(app->submenu);
widget_free(app->widget);
free(app);
}

int32_t gemini_app(void* p) {
UNUSED(p);
GeminiApp* app = gemini_app_alloc();

Gui* gui = furi_record_open(RECORD_GUI);
view_dispatcher_attach_to_gui(app->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
scene_manager_next_scene(app->scene_manager, GeminiSceneMainMenu);
view_dispatcher_run(app->view_dispatcher);

gemini_app_free(app);
return 0;
}
6 changes: 6 additions & 0 deletions gemini_app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

typedef enum {
GeminiViewSubmenu,
GeminiViewWidget,
} GeminiView;
18 changes: 18 additions & 0 deletions gemini_app_i.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "gemini_app.h"

#include <gui/view_dispatcher.h>
#include <gui/scene_manager.h>
#include <gui/modules/submenu.h>
#include <gui/modules/widget.h>

#include "scenes/gemini_scene.h"

typedef struct GeminiApp GeminiApp;
struct GeminiApp {
SceneManager* scene_manager;
ViewDispatcher* view_dispatcher;
Submenu* submenu;
Widget* widget;
};
30 changes: 30 additions & 0 deletions scenes/gemini_scene.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "gemini_scene.h"

// Generate scene on_enter handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
void (*const gemini_scene_on_enter_handlers[])(void*) = {
#include "gemini_scene_config.h"
};
#undef ADD_SCENE

// Generate scene on_event handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
bool (*const gemini_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
#include "gemini_scene_config.h"
};
#undef ADD_SCENE

// Generate scene on_exit handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
void (*const gemini_scene_on_exit_handlers[])(void* context) = {
#include "gemini_scene_config.h"
};
#undef ADD_SCENE

// Initialize scene handlers configuration structure
const SceneManagerHandlers gemini_scene_handlers = {
.on_enter_handlers = gemini_scene_on_enter_handlers,
.on_event_handlers = gemini_scene_on_event_handlers,
.on_exit_handlers = gemini_scene_on_exit_handlers,
.scene_num = GeminiSceneNum,
};
29 changes: 29 additions & 0 deletions scenes/gemini_scene.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <gui/scene_manager.h>

// Generate scene id and total number
#define ADD_SCENE(prefix, name, id) GeminiScene##id,
typedef enum {
#include "gemini_scene_config.h"
GeminiSceneNum,
} GeminiScene;
#undef ADD_SCENE

extern const SceneManagerHandlers gemini_scene_handlers;

// Generate scene on_enter handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
#include "gemini_scene_config.h"
#undef ADD_SCENE

// Generate scene on_event handlers declaration
#define ADD_SCENE(prefix, name, id) \
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
#include "gemini_scene_config.h"
#undef ADD_SCENE

// Generate scene on_exit handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
#include "gemini_scene_config.h"
#undef ADD_SCENE
2 changes: 2 additions & 0 deletions scenes/gemini_scene_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ADD_SCENE(gemini, main_menu, MainMenu)
ADD_SCENE(gemini, under_construction, UnderConstruction)
130 changes: 130 additions & 0 deletions scenes/gemini_scene_main_menu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include "../gemini_app_i.h"

typedef enum {
GeminiSceneMainMenuIndexSetName,
GeminiSceneMainMenuIndexConnectNewAP,
GeminiSceneMainMenuIndexConnectSavedAP,
GeminiSceneMainMenuIndexStartChatting,
GeminiSceneMainMenuIndexHelp,
} GeminiSceneMainMenuIndex;

typedef enum {
GeminiSceneMainMenuEventSetName,
GeminiSceneMainMenuEventConnectNewAP,
GeminiSceneMainMenuEventConnectSavedAP,
GeminiSceneMainMenuEventStartChatting,
GeminiSceneMainMenuEventHelp,
} GeminiSceneMainMenuEvent;

static void gemini_scene_main_menu_callback(void* context, uint32_t index) {
GeminiApp* app = context;
switch(index) {
case GeminiSceneMainMenuIndexSetName:
scene_manager_handle_custom_event(
app->scene_manager, GeminiSceneMainMenuEventSetName);
break;
case GeminiSceneMainMenuIndexConnectNewAP:
scene_manager_handle_custom_event(
app->scene_manager, GeminiSceneMainMenuEventConnectNewAP);
break;
case GeminiSceneMainMenuIndexConnectSavedAP:
scene_manager_handle_custom_event(
app->scene_manager, GeminiSceneMainMenuEventConnectSavedAP);
break;
case GeminiSceneMainMenuIndexStartChatting:
scene_manager_handle_custom_event(
app->scene_manager, GeminiSceneMainMenuEventStartChatting);
break;
case GeminiSceneMainMenuIndexHelp:
scene_manager_handle_custom_event(
app->scene_manager, GeminiSceneMainMenuEventHelp);
break;
}
}

void gemini_scene_main_menu_on_enter(void* context) {
GeminiApp* app = context;
submenu_reset(app->submenu);
submenu_set_header(app->submenu, "Gemini IA");
submenu_add_item(
app->submenu,
"Set your name",
GeminiSceneMainMenuIndexSetName,
gemini_scene_main_menu_callback,
app);
submenu_add_item(
app->submenu,
"Connect to new AP",
GeminiSceneMainMenuIndexConnectNewAP,
gemini_scene_main_menu_callback,
app);
submenu_add_item(
app->submenu,
"Connect to saved AP",
GeminiSceneMainMenuIndexConnectSavedAP,
gemini_scene_main_menu_callback,
app);
submenu_add_item(
app->submenu,
"Start Chatting",
GeminiSceneMainMenuIndexStartChatting,
gemini_scene_main_menu_callback,
app);
submenu_add_item(
app->submenu,
"Help",
GeminiSceneMainMenuIndexHelp,
gemini_scene_main_menu_callback,
app);

uint32_t index = scene_manager_get_scene_state(app->scene_manager, GeminiSceneMainMenu);
submenu_set_selected_item(app->submenu, index);

view_dispatcher_switch_to_view(app->view_dispatcher, GeminiViewSubmenu);
}

bool gemini_scene_main_menu_on_event(void* context, SceneManagerEvent event) {
GeminiApp* app = context;
bool consumed = false;
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
case GeminiSceneMainMenuEventSetName:
// TODO: Replace with correct scene
scene_manager_next_scene(app->scene_manager, GeminiSceneUnderConstruction);
consumed = true;
break;
case GeminiSceneMainMenuEventConnectNewAP:
// TODO: Replace with correct scene
scene_manager_next_scene(app->scene_manager, GeminiSceneUnderConstruction);
consumed = true;
break;
case GeminiSceneMainMenuEventConnectSavedAP:
// TODO: Replace with correct scene
scene_manager_next_scene(app->scene_manager, GeminiSceneUnderConstruction);
consumed = true;
break;
case GeminiSceneMainMenuEventStartChatting:
// TODO: Replace with correct scene
scene_manager_next_scene(app->scene_manager, GeminiSceneUnderConstruction);
consumed = true;
break;
case GeminiSceneMainMenuEventHelp:
// TODO: Replace with correct scene
scene_manager_next_scene(app->scene_manager, GeminiSceneUnderConstruction);
consumed = true;
break;
}
break;
default:
break;
}

return consumed;
}

void gemini_scene_main_menu_on_exit(void* context) {
GeminiApp* app = context;
scene_manager_set_scene_state(app->scene_manager, GeminiSceneMainMenu, submenu_get_selected_item(app->submenu));
submenu_reset(app->submenu);
}
19 changes: 19 additions & 0 deletions scenes/gemini_scene_under_construction.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "../gemini_app_i.h"

void gemini_scene_under_construction_on_enter(void* context) {
GeminiApp* app = context;
widget_reset(app->widget);
widget_add_string_element(
app->widget, 0, 25, AlignLeft, AlignTop, FontPrimary, "UNDER CONSTRUCTION");
view_dispatcher_switch_to_view(app->view_dispatcher, GeminiViewWidget);
}

bool gemini_scene_under_construction_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false; // event not handled.
}

void gemini_scene_under_construction_on_exit(void* context) {
UNUSED(context);
}

0 comments on commit 2121b05

Please sign in to comment.