/***
+ * @Date: 2024-06-29 18:03:40
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-10 21:34:39
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageModel.h
+ */
+/***
+ * @Date: 2024-06-29 18:03:40
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-10 17:18:42
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/message/include/MessageModel.h
+ */
+/***
* @Date: 2024-06-21 09:56:18
* @LastEditors: Caisking 3449750381@qq.com
* @LastEditTime: 2024-07-08 09:22:12
const MessageListItem *GetMessageListItems() const; // 获取消息列表项
// uint8_t GetMessageListCount() const; // 获取消息列表数量
- bool HasDataJson(); // 判断是否存在数据Json
- bool GetJsonLoadStatus(); // 获取Json加载状态
- std::vector<MessageData> LoadMessageData(); // 加载消息数据
- void SaveMessageData(const std::vector<MessageData> &messageVector); // 保存json数据
- uint8_t GetMessageCount() const; // 获取消息数量
- void SetPopupViewState(bool state); // 设置弹出视图状态
- bool GetPopupViewState(); // 获取弹出视图状态
- void PrintData(const MessageData messageData); // 打印数据
- MessageData *GetCurrentMessageData(); // 获取当前消息数据
- void SetCurrentMessageData(MessageData *data); // 设置当前消息数据
- bool ClearAllData(); // 清除所有数据
- bool DeleteSingleItem(int currentIndex); // 删除单个项
- MessageData *GetNewestData(); // 获取最新信息项
- void SetCurrentIndex(uint8_t index); // 设置当前项
- uint8_t GetCurrentIndex(); // 获取当前项
- bool SetMessageIsread(); // 设置当前项已读
-
+ bool HasDataJson(); // 判断是否存在数据Json
+ bool GetJsonLoadStatus(); // 获取Json加载状态
+ std::vector<MessageData> LoadMessageData(); // 加载消息数据
+ uint8_t GetMessageCount() const; // 获取消息数量
+ void SetPopupViewState(bool state); // 设置弹出视图状态
+ bool GetPopupViewState(); // 获取弹出视图状态
+ void PrintData(const MessageData messageData); // 打印数据
+ MessageData *GetCurrentMessageData(); // 获取当前消息数据
+ void SetCurrentMessageData(MessageData *data); // 设置当前消息数据
+ bool ClearAllData(); // 清除所有数据
+ bool DeleteSingleItem(int currentIndex); // 删除单个项
+ MessageData *GetNewestData(); // 获取最新信息项
+ void SetCurrentIndex(uint8_t index); // 设置当前项
+ uint8_t GetCurrentIndex(); // 获取当前项
+ bool SetMessageIsread(); // 设置当前项已读
+ void DeleteExcessFiles(std::vector<std::string> &filenames); // 删除文件
+ void SaveMessageData(const MessageData data, const int index); // 保存json数据
private:
MessageModel();
MessageModel(const MessageModel &);
static const uint16_t MaxMessageListCount = 10; // 消息列表最大数量
MessageListItem Messages[MaxMessageListCount] = {0, false, nullptr, nullptr, nullptr}; // 消息列表
uint8_t indexCurrent; // 选择的项
+ std::map<int, std::string> fileIndexMap;
bool jsonDataExists{false}; // Json数据存在标志
bool popupViewState{false}; // 弹出视图状态
static MessageCardView *g_pMessageCardView = nullptr;
static const uint32_t BACK_GROUND_COLOR = 0xfff6f6f6;
- static constexpr int16_t More_LIST_POSITION_X = 43;
- static constexpr int16_t More_LIST_POSITION_Y = 120;
- static constexpr int16_t More_SCROLLBLANKSIZE = 35; // 设置此滚动视图的空白大小。
+ static constexpr int16_t MORE_LIST_POSITION_X = 43;
+ static constexpr int16_t MORE_LIST_POSITION_Y = 120;
+ static constexpr int16_t MORE_SCROLLBLANKSIZE = 35; // 设置此滚动视图的空白大小。
static constexpr int16 MAX_SCR_DIS = 1000;
static constexpr int16 LIST_POS = 20;
static constexpr int16 SNUM_2 = 2;
// UIList 的适配器
p_MessageListAdapter = new MessageListAdapter();
- // p_MessageListAdapter->SetItemClickListener(presenter_);
+ p_MessageListAdapter->SetItemClickListener(MessageControlPresenter::GetInstance());
if (MessageList == nullptr)
{
MessageList = new UIList();
}
- MessageList->SetPosition(More_LIST_POSITION_X, More_LIST_POSITION_Y);
- MessageList->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
- MessageList->SetScrollBlankSize(More_SCROLLBLANKSIZE);
- MessageList->SetReboundSize(50);
- MessageList->SetSelectPosition(HORIZONTAL_RESOLUTION / SNUM_2); // middle position
- MessageList->SetDraggable(true);
+ MessageList->SetPosition(MORE_LIST_POSITION_X, MORE_LIST_POSITION_Y, 466, 466);
+ // MessageList->SetScrollStateListener(this);
MessageList->SetThrowDrag(true);
- MessageList->EnableAutoAlign(true);
- MessageList->SetElastic(true); // 设置回弹效果
- MessageList->SetMaxScrollDistance(MAX_SCR_DIS);
+ MessageList->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
+ // 设置手指抬起屏幕后的最大滚动距离
+ MessageList->SetMaxScrollDistance(1000); // 1000: max scroll distance
+ // 设置手指抬起屏幕后的补偿距离
+ MessageList->SetSwipeACCLevel(800); // 800: compensation distance
+ // 设置拖动加速
+ MessageList->SetDragACCLevel(5); // 5: drag acceleration
+ MessageList->SetYScrollBarVisible(true);
MessageList->SetViewId(MAINMESSAGEVIEW);
// SetYScrollBarVisible(true); // 设置滑动滚动条
MessageList->SetAdapter(p_MessageListAdapter);
MessageList->RefreshList();
- /*删除按键*/
- int top = MessageList->GetWidth() + 130;
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "top %d", top);
- InitButtonExt(DeleteButton, 43, top, 380, 100, DELETEALLDATA, STR_CLEANALL, 30);
- DeleteButton->SetOnClickListener((UIView::OnClickListener *)OHOS::MessageControlPresenter::GetInstance());
- Add(DeleteButton);
+ // /*删除按键*/
+ // int top = MessageList->GetWidth() + 130;
+ // WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "top %d", top);
+ // InitButtonExt(DeleteButton, 43, top, 380, 100, DELETEALLDATA, STR_CLEANALL, 30);
+ // DeleteButton->SetOnClickListener((UIView::OnClickListener *)OHOS::MessageControlPresenter::GetInstance());
+ // Add(DeleteButton);
SetDraggable(false);
SetTouchable(false);
#include "cJSON.h"
#include "wearable_log.h"
#include "custom_utils.h"
+#include <algorithm>
+#include <cstring>
+#include <dirent.h>
+#include <map>
+#include <filesystem>
#define MESSAGE_JSON_FILE "user/userdata/message/ancs.json"
-#define PRINTFDATA 1
+#define MESSAGE_JSON_DIR "user/userdata/message/"
+#define PRINTFDATA 0
extern "C" errcode_t uapi_get_TIME_STR(uint32_t time, char *p_time, char date_separator, char time_separator, date_format_t format);
namespace OHOS
{
return (numberOfItems != 0 ? numberOfItems : MaxMessageListCount);
}
-
+ /* -------------------------------------------------------------------------- */
void MessageModel::PrintData(MessageData messagedata)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "--------------------------------------");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Message Read: %d", messagedata.isRead);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "--------------------------------------");
}
+ /*打印文件名数组*/
+ void PrintFileName(const std::vector<std::string> &filenames)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Filenames:");
+ for (const auto &filename : filenames)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", filename.c_str());
+ }
+ }
+
+ /*打印message数组*/
+ void PrintMessageData(const std::vector<MessageData> &MessageVector)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageVector:");
+ for (const auto &message : MessageVector)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Title: %s", message.labelTitle.c_str());
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Details: %s", message.labelDetails.c_str());
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Timestamp: %d", message.timestamp);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "IsRead: %d", message.isRead);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "");
+ }
+ }
+ /*打印map*/
+ void PrintMessageMap(const std::map<int, std::string> &messageMap)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MessageMap:");
+ for (const auto &pair : messageMap)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Key: %d, Value: %s", pair.first, pair.second.c_str());
+ }
+ }
+ /* -------------------------------------------------------------------------- */
/*检查是否存在数据*/
bool MessageModel::HasDataJson()
{
- // 读取record.json文件
- std::ifstream file(MESSAGE_JSON_FILE);
- // 检查文件是否打开成功
- if (!file.is_open())
+ // 打开消息数据目录
+ DIR *dir = opendir(MESSAGE_JSON_DIR);
+ if (dir == nullptr)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unable to open file");
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unable to open MESSAGE_JSON_DIR");
jsonDataExists = false;
return false;
}
- // 检查文件是否为空
- file.seekg(0, std::ios::end);
- if (file.tellg() == 0)
+
+ // 在作用域结束时自动关闭目录
+ struct DirCloser
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File is empty");
- file.close();
+ void operator()(DIR *d) const
+ {
+ if (d)
+ closedir(d);
+ }
+ };
+ std::unique_ptr<DIR, DirCloser> dirPtr(dir);
+
+ // 检查目录是否为空
+ struct dirent *ent;
+ // 是否存在文件标志位
+ bool isEmpty = true;
+ while ((ent = readdir(dir)) != nullptr)
+ {
+ // 过滤掉当前目录和上级目录
+ if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+ {
+ continue;
+ }
+ // 普通文件
+ if (ent->d_type == DT_REG || ent->d_type == DT_UNKNOWN)
+ {
+ isEmpty = false;
+ break;
+ }
+ }
+
+ if (isEmpty)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "No data files found in MESSAGE_JSON_DIR");
jsonDataExists = false;
return false;
}
- // 关闭文件
- file.close();
jsonDataExists = true;
return true;
}
+
/*加载json函数*/
+ /*
+ 加载messagejson文件夹 MESSAGE_JSON_DIR
+ 文件夹里面的文件[一条数据]一个文件 按序号命名,0.json 1.json 2.json...
+ 需要建立一个文件名和数组下标对应的map ->方便进行对文件操作?
+ 最多加载10条数据(先按序号排序??)
+ 如果还有多余的遍历删除序号最小的文件(消息最早的)
+ 获取到一个 MessageData 数组返回
+
+ 1.遍历文件夹的每一个文件 排序
+ 2.先加载?
+ 3.每次加载一个文件 更新一下map
+ 4.超过10条。后面的文件直接删除
+ 5.返回数组
+ */
+
+ /*遍历文件夹*/
+ std::vector<std::string> GetFileNamesInDirectory(const std::string &directory)
+ {
+ std::vector<std::string> filenames;
+ DIR *dir;
+ struct dirent *ent;
+ if ((dir = opendir(directory.c_str())) != nullptr)
+ {
+ while ((ent = readdir(dir)) != nullptr)
+ {
+ std::string fileName = ent->d_name;
+ if (fileName != "." && fileName != "..")
+ {
+ // 2.遍历文件夹里面的文件名生成文件名数组
+ if (ent->d_type == DT_REG || ent->d_type == DT_UNKNOWN) // 普通文件
+ {
+ filenames.push_back(fileName);
+ // printf("GetFileNamesInDirectory:%s\r\n", fileName.c_str());
+ }
+ else if (ent->d_type == DT_DIR) // 目录
+ {
+ continue;
+ }
+ }
+ }
+ closedir(dir);
+ return filenames;
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s is null!", directory.c_str());
+ return filenames;
+ }
+
+ /*文件名数组 删除多余项*/
+ void MessageModel::DeleteExcessFiles(std::vector<std::string> &filenames)
+ {
+ if (filenames.size() > MaxMessageListCount)
+ {
+ int numFilesToDelete = filenames.size() - MaxMessageListCount;
+ for (int i = 0; i < numFilesToDelete; i++)
+ {
+ std::remove(filenames[i].c_str()); // 删除文件
+ filenames.erase(filenames.begin() + i); // 从数组中删除相应的文件名
+ }
+ }
+ }
+
+ /*message json 加载*/
std::vector<MessageData> MessageModel::LoadMessageData()
{
- std::ifstream file(MESSAGE_JSON_FILE);
- if (!file.is_open())
+ std::vector<MessageData> MessageVector; // 返回的数据列表
+ std::vector<std::string> filenames; // 文件名数组
+
+ // 1.检查消息目录是否存在
+ filenames = GetFileNamesInDirectory(MESSAGE_JSON_DIR);
+ // 3.检查文件夹是否为空
+ if (filenames.empty())
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open file");
- return std::vector<MessageData>();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Message directory is empty");
+ return MessageVector;
}
- std::string jsonData((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
- file.close();
- cJSON *root = cJSON_Parse(jsonData.c_str());
- cJSON *dataArray = cJSON_GetObjectItem(root, "infor");
- int dataCount = cJSON_GetArraySize(dataArray);
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "dataCount is %d", dataCount);
+ // 4.文件名排序
+ std::sort(filenames.begin(), filenames.end());
+
+ // 5.文件数量超出限制删除多余文件
+ DeleteExcessFiles(filenames); // 删除多余文件
- std::vector<MessageData> MessageVector;
- for (int i = 0; i < dataCount; i++)
+ // 6.解析json
+ for (int i = 0; i < filenames.size(); i++)
{
- cJSON *item = cJSON_GetArrayItem(dataArray, i);
+ std::ifstream file((MESSAGE_JSON_DIR + filenames[i]));
+ if (!file.is_open())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unable to open file %s ", filenames[i].c_str());
+ continue; // 跳过当前文件
+ }
+
+ std::string jsonData((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
+ file.close();
+
+ cJSON *root = cJSON_Parse(jsonData.c_str());
+ if (root == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Failed to parse JSON in file %s ", filenames[i].c_str());
+ continue; // 跳过当前文件
+ }
+
MessageData messagedata;
- messagedata.labelTitle = cJSON_GetObjectItem(item, "title")->valuestring;
- messagedata.labelDetails = cJSON_GetObjectItem(item, "msg")->valuestring;
+ messagedata.labelTitle = cJSON_GetObjectItem(root, "title")->valuestring;
+ messagedata.labelDetails = cJSON_GetObjectItem(root, "msg")->valuestring;
+ messagedata.isRead = cJSON_GetObjectItem(root, "read")->valueint;
// 获取时间
- uint32 timestamp = cJSON_GetObjectItem(item, "time")->valueint;
+ uint32 timestamp = cJSON_GetObjectItem(root, "time")->valueint;
messagedata.timestamp = timestamp;
char labelTime[20];
if (uapi_get_TIME_STR(timestamp, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC)
messagedata.labelTime = std::string(labelTime);
}
- // 这里根据解析的 JSON 数据类型修改 messagedata.isRead 的精确类型
- messagedata.isRead = cJSON_GetObjectItem(item, "read")->valueint;
- // PrintData(messagedata);
+ // 生成json数组数组
MessageVector.push_back(messagedata);
+ // 维护map 映射文件名和数组下标
+ fileIndexMap[i] = filenames[i];
+ cJSON_Delete(root);
}
- cJSON_Delete(root);
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadMessageJson is ok");
+
+#if PRINTFDATA
+ PrintFileName(filenames);
+ PrintMessageData(MessageVector);
+ PrintMessageMap(fileIndexMap);
+#endif
return MessageVector;
}
+
void MessageModel::InitMessageListItems()
{
// 读取json数据
// PrintData(messageData);
// 获取是否读取 来信 信息内容 时间
Messages[count] = {count, messageData.isRead, messageData.labelTitle, messageData.labelDetails, messageData.labelTime};
- // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "the count is %d", count);
}
- // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "the Messages.Size is %d", Messages.size());
}
}
const MessageListItem *MessageModel::GetMessageListItems() const
return popupViewState;
}
/*保存json数据*/
- void MessageModel::SaveMessageData(const std::vector<MessageData> &messageVector)
+ void MessageModel::SaveMessageData(const MessageData data, const int index)
{
cJSON *root = cJSON_CreateObject();
- cJSON *dataArray = cJSON_CreateArray();
- for (const auto &message : messageVector)
- {
- cJSON *item = cJSON_CreateObject();
- cJSON_AddStringToObject(item, "title", message.labelTitle.c_str());
- cJSON_AddStringToObject(item, "msg", message.labelDetails.c_str());
- cJSON_AddNumberToObject(item, "time", message.timestamp);
- cJSON_AddNumberToObject(item, "read", message.isRead);
-
- cJSON_AddItemToArray(dataArray, item);
- }
-
- cJSON_AddItemToObject(root, "infor", dataArray);
+ cJSON *item = cJSON_CreateObject();
+ cJSON_AddStringToObject(item, "title", data.labelTitle.c_str());
+ cJSON_AddStringToObject(item, "msg", data.labelDetails.c_str());
+ cJSON_AddNumberToObject(item, "time", data.timestamp);
+ cJSON_AddNumberToObject(item, "read", data.isRead);
std::string jsonString = cJSON_Print(root);
cJSON_Delete(root);
- std::ofstream file(MESSAGE_JSON_FILE);
+ std::ofstream file(fileIndexMap[index]);
if (file.is_open())
{
file << jsonString;
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SetMessageData is ok");
}
}
- // 清除所有数据
+ // 清除所有数据[删除文件夹内所有文件]
bool MessageModel::ClearAllData()
{
- if (uapi_delete_files(MESSAGE_JSON_FILE))
- {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ClearAllData is ok");
- return true;
- }
+
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ClearAllData is ok");
+ return true;
+
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ClearAllData is fail");
return false;
}
- // 删除单个项
+ // 删除单个项 [通过 map 删除]
bool MessageModel::DeleteSingleItem(int currentIndex)
{
- std::vector<MessageData> messageVector = LoadMessageData();
-
- if (currentIndex < 0 || currentIndex >= messageVector.size())
+ if (currentIndex < 0 || currentIndex >= fileIndexMap.size())
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid index for deletion");
return false;
}
- if (messageVector.size() == 1)
- {
- // 如果是最后一条数据则需要直接删除文件
- return ClearAllData();
- }
-
- messageVector.erase(messageVector.begin() + currentIndex);
- SaveMessageData(messageVector);
+ uapi_delete_files(fileIndexMap[currentIndex].c_str());
+ fileIndexMap.erase(currentIndex);
return true;
}
// 设置当前项已读
if (!messageVector.empty())
{
messageVector[GetCurrentIndex()].isRead = true;
- SaveMessageData(messageVector);
+
+ // SaveMessageData(messageVector);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Message marked as read and data saved");
return true;
}