WIP: Experimenting with Lager for Redux like implementation

This commit is contained in:
Chris Josten 2021-03-23 02:13:56 +01:00
parent b9b08ab384
commit 1f09650721
14 changed files with 465 additions and 17 deletions

View File

@ -5,6 +5,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
set(CMAKE_AUTOMOC ON)
cmake_policy(SET CMP0048 NEW)
set(CMAKE_CXX_STANDARD 17)
include(ExternalProjectBackCompat)
include(TargetLinkSys)
# Options
option(PLATFORM_SAILFISHOS "Build SailfishOS version of application" OFF)

View File

@ -0,0 +1,10 @@
# Provides backwards compatibility for FetchContent_MakeAvailable
if(${CMAKE_VERSION} VERSION_LESS 3.14)
macro(FetchContent_MakeAvailable NAME)
FetchContent_GetProperties(${NAME})
if(NOT ${NAME}_POPULATED)
FetchContent_Populate(${NAME})
add_subdirectory(${${NAME}_SOURCE_DIR} ${${NAME}_BINARY_DIR})
endif()
endmacro()
endif()

29
cmake/TargetLinkSys.cmake Normal file
View File

@ -0,0 +1,29 @@
# From https://stackoverflow.com/questions/52135983/cmake-target-link-libraries-include-as-system-to-suppress-compiler-warnings
function(target_link_libraries_system target)
set(options PRIVATE PUBLIC INTERFACE)
cmake_parse_arguments(TLLS "${options}" "" "" ${ARGN})
foreach(op ${options})
if(TLLS_${op})
set(scope ${op})
endif()
endforeach(op)
set(libs ${TLLS_UNPARSED_ARGUMENTS})
foreach(lib ${libs})
get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
if(lib_include_dirs)
if(scope)
target_include_directories(${target} SYSTEM ${scope} ${lib_include_dirs})
else()
target_include_directories(${target} SYSTEM PRIVATE ${lib_include_dirs})
endif()
else()
message("Warning: ${lib} doesn't set INTERFACE_INCLUDE_DIRECTORIES. No include_directories set.")
endif()
if(scope)
target_link_libraries(${target} ${scope} ${lib})
else()
target_link_libraries(${target} ${lib})
endif()
endforeach()
endfunction(target_link_libraries_system)

View File

@ -1,45 +1,72 @@
project(jellyfin-qt VERSION 0.1.0)
find_package(Qt5 5.6 COMPONENTS Multimedia Network Qml WebSockets REQUIRED)
include(GNUInstallDirs)
include(FetchContent)
################################################################################
# Libraries #
################################################################################
find_package(Qt5 5.6 COMPONENTS Multimedia Network Qml WebSockets REQUIRED)
find_package(Boost REQUIRED)
find_package(Zug)
if(NOT Zug_FOUND)
message(STATUS "Using zug from FetchContent")
set(zug_BUILD_TESTS OFF)
set(zug_BUILD_EXAMPLES OFF)
set(zug_BUILD_DOCS OFF)
FetchContent_Declare(zug
GIT_REPOSITORY https://github.com/arximboldi/zug
GIT_TAG 266cc7fcc01f546c4fd0dabf3a26c71ddc7f3e7d)
FetchContent_MakeAvailable(zug)
endif()
find_package(Immer)
if(NOT Immer_FOUND)
message(STATUS "Using Immer from FetchContent")
message(STATUS "Immer not installed; Retrieving Immer with FetchContent")
set(immer_BUILD_TESTS OFF)
set(immer_BUILD_EXAMPLES OFF)
set(immer_BUILD_DOCS OFF)
set(immer_BUILD_EXTRAS OFF)
FetchContent_Declare(immer GIT_REPOSITORY https://github.com/arximboldi/immer GIT_TAG
800ddb04e528a3e83e69e8021d7e872e7c34cbcd)
FetchContent_Declare(immer
GIT_REPOSITORY https://github.com/arximboldi/immer
GIT_TAG 800ddb04e528a3e83e69e8021d7e872e7c34cbcd)
FetchContent_MakeAvailable(immer)
endif()
find_package(Lager)
if(NOT Lager_FOUND)
message(STATUS "Using lager from FetchContent")
message(STATUS "Lager not installed; Retrieving lager with FetchContent")
set(lager_BUILD_TESTS OFF)
set(lager_BUILD_EXAMPLES OFF)
set(lager_BUILD_DOCS OFF)
set(lager_EMBED_RESOURCES_PATH OFF)
FetchContent_Declare(lager GIT_REPOSITORY https://github.com/arximboldi/lager GIT_TAG
71eca6b0ebbccf3e0e54324b6967f047e49ba92d)
FetchContent_Declare(lager
GIT_REPOSITORY https://github.com/arximboldi/lager
GIT_TAG 71eca6b0ebbccf3e0e54324b6967f047e49ba92d)
FetchContent_MakeAvailable(lager)
endif()
find_package(cereal)
if(NOT cereal_FOUND)
set(JUST_INSTALL_CEREAL ON)
FetchContent_Declare(cereal GIT_REPOSITORY https://github.com/USCiLab/cereal GIT_TAG v1.3.0)
FetchContent_Declare(cereal
GIT_REPOSITORY https://github.com/USCiLab/cereal
GIT_TAG v1.3.0)
FetchContent_MakeAvailable(cereal)
endif()
################################################################################
# TARGETS #
################################################################################
# Includes the automatically generated files.
include(GeneratedSources.cmake)
set(jellyfin-qt_SOURCES
# src/DTO/dto.cpp
src/library/reducer.cpp
src/model/item.cpp
src/support/jsonconv.cpp
src/support/loader.cpp
@ -58,6 +85,13 @@ list(APPEND jellyfin-qt_SOURCES ${openapi_SOURCES})
set(jellyfin-qt_HEADERS
# include/JellyfinQt/DTO/dto.h
include/JellyfinQt/network/actions.h
include/JellyfinQt/network/networkrequest.h
include/JellyfinQt/network/reducer.h
include/JellyfinQt/network/store.h
include/JellyfinQt/library/actions.h
include/JellyfinQt/library/reducer.h
include/JellyfinQt/library/store.h
include/JellyfinQt/model/item.h
include/JellyfinQt/support/jsonconv.h
include/JellyfinQt/support/loader.h
@ -72,25 +106,38 @@ set(jellyfin-qt_HEADERS
include/JellyfinQt/serverdiscoverymodel.h
include/JellyfinQt/websocket.h)
list(APPEND jellyfin-qt_SOURCES ${openapi_HEADERS})
list(APPEND jellyfin-qt_HEADERS ${openapi_HEADERS})
add_definitions(-DSAILFIN_VERSION=\"${SAILFIN_VERSION}\")
if (PLATFORM_SAILFISHOS)
add_definitions(-DPLATFORM_SAILFISHOS=1)
endif()
add_library(jellyfin-qt ${jellyfin-qt_SOURCES} ${jellyfin-qt_HEADERS})
add_library(JellyfinQt ${jellyfin-qt_SOURCES} ${jellyfin-qt_HEADERS})
if(${CMAKE_VERSION} VERSION_GREATER "3.16.0")
target_precompile_headers(jellyfin-qt PRIVATE ${jellyfin-qt_HEADERS})
target_precompile_headers(JellyfinQt PRIVATE ${jellyfin-qt_HEADERS})
endif()
target_include_directories(jellyfin-qt
target_include_directories(JellyfinQt
PUBLIC "include" "generated/include"
)
target_link_libraries(jellyfin-qt PUBLIC Qt5::Core Qt5::Multimedia Qt5::Network Qt5::Qml Qt5::WebSockets)
set_target_properties(jellyfin-qt PROPERTIES CXX_VISIBILITY_PRESET default)
install(TARGETS jellyfin-qt
target_link_libraries(JellyfinQt
PUBLIC Qt5::Core Qt5::Multimedia Qt5::Network Qt5::Qml Qt5::WebSockets)
target_link_libraries_system(JellyfinQt
PUBLIC
cereal
zug
immer
lager)
set_target_properties(JellyfinQt PROPERTIES CXX_VISIBILITY_PRESET default)
install(TARGETS JellyfinQt
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
export(TARGETS jellyfin-qt FILE JellyfinQtConfig.cmake)
install(TARGETS JellyfinQt EXPORT JellyfinQtTargets)
# export(TARGETS jellyfin-qt lager immer cereal FILE JellyfinQtConfig.cmake)

View File

@ -0,0 +1,41 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_LIBRARY_ACTIONS_H
#define JELLYFIN_LIBRARY_ACTIONS_H
#include <string>
#include <variant>
namespace Jellyfin {
namespace Library {
struct fetchItem {
std::string itemId;
};
struct fetchItemChildren {
std::string parentItemId;
};
using Action = std::variant<fetchItem, fetchItemChildren>;
} // NS Library
} // NS Jellyfin
#endif //JELLYFIN_LIBRARY_ACTIONS_H

View File

@ -0,0 +1,41 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2021 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_LIBRARY_REDUCER_H
#define JELLYFIN_LIBRARY_REDUCER_H
#include <utility>
#include <lager/context.hpp>
#include <lager/util.hpp>
#include "actions.h"
#include "store.h"
namespace Jellyfin {
namespace Library {
using ItemListResult = std::pair<ItemListStore, lager::effect<Action>>;
ItemListResult update(ItemListStore store, Action action);
}
}
#endif // JELLYFIN_LIBRARY_REDUCER_H

View File

@ -0,0 +1,46 @@
/*
* Sailfin: a Jellyfin client written using Qt
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_LIBRARY_STORE_H
#define JELLYFIN_LIBRARY_STORE_H
#include <string>
#include <immer/map.hpp>
#include "../DTO/baseitemdto.h"
namespace Jellyfin {
namespace Library {
/**
* @brief Stores information about one Jellyfin Item.
*/
struct ItemStore {
std::string id;
std::string name;
};
struct ItemListStore {
immer::map<std::string, ItemStore> itemList;
};
}
}
#endif // JELLYFIN_LIBRARY_STORE_H

View File

@ -0,0 +1,39 @@
/*
* Sailfin: a Jellyfin client written using Qt
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_NETWORK_ACTIONS_H
#define JELLYFIN_NETWORK_ACTIONS_H
#include <variant>
#include "reducer.h"
namespace Jellyfin {
namespace Network {
struct makeRequest {
};
using Action = std::variant<makeRequest, int>;
} // NS Network
} // NS Jellyfin
#endif // JELLYFIN_NETWORK_ACTIONS_H

View File

@ -0,0 +1,44 @@
/*
* Sailfin: a Jellyfin client written using Qt
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_NETWORK_NETWORKREQUEST_H
#define JELLYFIN_NETWORK_NETWORKREQUEST_H
#include <string>
namespace Jellyfin {
namespace Network {
enum HttpMethod {
GET,
PUT,
POST,
DELETE
};
struct NetworkRequest {
std::string url;
HttpMethod method;
};
} // NS Network
} // NS Jellyfin
#endif // JELLYFIN_NETWORK_NETWORKREQUEST_H

View File

@ -0,0 +1,32 @@
/*
* Sailfin: a Jellyfin client written using Qt
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_NETWORK_REDUCER_H
#define JELLYFIN_NETWORK_REDUCER_H
namespace Jellyfin {
namespace Network {
} // NS Network
} // NS Jellyfin
#endif // JELLYFIN_NETWORK_REDUCER_H

View File

@ -0,0 +1,38 @@
/*
* Sailfin: a Jellyfin client written using Qt
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_NETWORK_STORE_H
#define JELLYFIN_NETWORK_STORE_H
#include <string>
#include "networkrequest.h"
namespace Jellyfin {
namespace Network {
struct NetworkRequestStore {
};
} // NS Network
} // NS Jellyfin
#endif // JELLYFIN_NETWORK_STORE_H

View File

@ -0,0 +1,40 @@
/*
* Sailfin: a Jellyfin client written using Qt
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef JELLYFIN_NETWORK_STORE_H
#define JELLYFIN_NETWORK_STORE_H
#include <string>
#include <immer/vector.hpp>
#include "networkrequest.h"
namespace Jellyfin {
namespace Network {
struct NetworkRequestStore {
immer::vector
};
} // NS Network
} // NS Jellyfin
#endif // JELLYFIN_NETWORK_STORE_H

View File

@ -0,0 +1,37 @@
/*
* Sailfin: a Jellyfin client written using Qt
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <JellyfinQt/library/reducer.h>
namespace Jellyfin {
namespace Library {
ItemListResult update(ItemListStore store, Action action) {
return std::visit(
lager::visitor {
[&](const fetchItem &a) -> ItemListResult {
return {store, lager::noop};
},
[&](const fetchItemChildren &a) -> ItemListResult {
return {store, lager::noop};
},
}, action);
}
} // NS Library
} // NS Jellyfin

View File

@ -4,12 +4,13 @@ set(sailfin_SOURCES
qt5_add_resources(sailfin_RESOURCES qml.qrc)
add_executable(sailfin ${sailfin_SOURCES} ${sailfin_RESOURCES})
target_link_libraries(sailfin PUBLIC Qt5::Gui Qt5::Qml Qt5::Quick jellyfin-qt)
target_link_libraries(sailfin PRIVATE Qt5::Gui Qt5::Qml Qt5::Quick JellyfinQt)
install(TARGETS sailfin
RUNTIME DESTINATION bin
)
install(DIRECTORY translations
DESTINATION share/harbour-sailfin
FILES_MATCHING PATTERN "*.qm"