Compare commits
17 Commits
dev-854d09
...
dev-c3a7d1
Author | SHA1 | Date | |
---|---|---|---|
c3a7d1521a | |||
fc994ab758 | |||
605a730b59 | |||
3e15798afc | |||
cf697622cb | |||
05b0a2f514 | |||
c887fdac8a | |||
4b0d9595ac | |||
5ac318d1bf | |||
eaa8f1dd16 | |||
b88fffd959 | |||
858b9dfcfa | |||
bc8b631b84 | |||
52278f6726 | |||
29fd1bfb62 | |||
998000aa3a | |||
e66f4651d0 |
8
.github/workflows/cd.yml
vendored
8
.github/workflows/cd.yml
vendored
@ -68,7 +68,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static
|
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
|
||||||
|
|
||||||
# setup vs env
|
# setup vs env
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
@ -79,7 +79,7 @@ jobs:
|
|||||||
#- uses: ilammy/setup-nasm@v1
|
#- uses: ilammy/setup-nasm@v1
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF
|
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||||
@ -122,7 +122,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static
|
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
|
||||||
|
|
||||||
# setup vs env
|
# setup vs env
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
@ -133,7 +133,7 @@ jobs:
|
|||||||
#- uses: ilammy/setup-nasm@v1
|
#- uses: ilammy/setup-nasm@v1
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DTOMATO_ASAN=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF
|
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DTOMATO_ASAN=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
||||||
|
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -59,7 +59,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static
|
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static pkgconf:x64-windows
|
||||||
|
|
||||||
# setup vs env
|
# setup vs env
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
@ -70,7 +70,7 @@ jobs:
|
|||||||
#- uses: ilammy/setup-nasm@v1
|
#- uses: ilammy/setup-nasm@v1
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF
|
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDL3IMAGE_VENDORED=ON -DSDL3IMAGE_DEPS_SHARED=ON -DSDL3IMAGE_JXL=OFF -DSDL3IMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
||||||
|
2
external/solanaceae_contact
vendored
2
external/solanaceae_contact
vendored
Submodule external/solanaceae_contact updated: e40271670b...e8b069c803
2
external/solanaceae_message3
vendored
2
external/solanaceae_message3
vendored
Submodule external/solanaceae_message3 updated: f9f70a05b1...96b76dc67f
2
external/solanaceae_message_serializer
vendored
2
external/solanaceae_message_serializer
vendored
Submodule external/solanaceae_message_serializer updated: 1409485ef1...e574c4f779
2
external/solanaceae_tox
vendored
2
external/solanaceae_tox
vendored
Submodule external/solanaceae_tox updated: 25857b8aa7...2807239dea
250
external/toxcore/CMakeLists.txt
vendored
250
external/toxcore/CMakeLists.txt
vendored
@ -1,214 +1,62 @@
|
|||||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.9...3.16 FATAL_ERROR)
|
||||||
|
|
||||||
|
set(EXPERIMENTAL_API ON CACHE BOOL "" FORCE)
|
||||||
|
set(UNITTEST OFF CACHE BOOL "" FORCE)
|
||||||
|
set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
add_subdirectory(./c-toxcore)
|
||||||
|
|
||||||
|
# the ideal case
|
||||||
|
#add_library(toxcore ALIAS toxcore_static)
|
||||||
|
|
||||||
|
# the sad case
|
||||||
|
add_library(toxcore INTERFACE)
|
||||||
|
|
||||||
|
target_link_libraries(toxcore INTERFACE toxcore_static)
|
||||||
|
|
||||||
|
# HACK: "install" api headers into binary dir
|
||||||
|
configure_file(
|
||||||
|
./c-toxcore/toxcore/tox.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/tox/tox.h
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
configure_file(
|
||||||
|
./c-toxcore/toxcore/tox_events.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/tox/tox_events.h
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
configure_file(
|
||||||
|
./c-toxcore/toxcore/tox_private.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/tox/tox_private.h
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
configure_file(
|
||||||
|
./c-toxcore/toxencryptsave/toxencryptsave.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/tox/toxencryptsave.h
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
configure_file(
|
||||||
|
./c-toxcore/toxav/toxav.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/tox/toxav.h
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(toxcore INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||||
|
|
||||||
|
# HACK: support old libsodium find
|
||||||
|
# libs should handle this case themselfs
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
set(TOX_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c-toxcore/")
|
|
||||||
|
|
||||||
# TODO: shared
|
|
||||||
add_library(toxcore STATIC
|
|
||||||
${TOX_DIR}third_party/cmp/cmp.c
|
|
||||||
${TOX_DIR}third_party/cmp/cmp.h
|
|
||||||
|
|
||||||
${TOX_DIR}toxcore/announce.c
|
|
||||||
${TOX_DIR}toxcore/announce.h
|
|
||||||
${TOX_DIR}toxcore/bin_pack.c
|
|
||||||
${TOX_DIR}toxcore/bin_pack.h
|
|
||||||
${TOX_DIR}toxcore/bin_unpack.c
|
|
||||||
${TOX_DIR}toxcore/bin_unpack.h
|
|
||||||
${TOX_DIR}toxcore/ccompat.c
|
|
||||||
${TOX_DIR}toxcore/ccompat.h
|
|
||||||
${TOX_DIR}toxcore/crypto_core.c
|
|
||||||
${TOX_DIR}toxcore/crypto_core.h
|
|
||||||
${TOX_DIR}toxcore/crypto_core_pack.c
|
|
||||||
${TOX_DIR}toxcore/crypto_core_pack.h
|
|
||||||
${TOX_DIR}toxcore/DHT.c
|
|
||||||
${TOX_DIR}toxcore/DHT.h
|
|
||||||
${TOX_DIR}toxcore/events/conference_connected.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_invite.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_message.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_peer_list_changed.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_peer_name.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_title.c
|
|
||||||
${TOX_DIR}toxcore/events/dht_get_nodes_response.c
|
|
||||||
${TOX_DIR}toxcore/events/events_alloc.c
|
|
||||||
${TOX_DIR}toxcore/events/events_alloc.h
|
|
||||||
${TOX_DIR}toxcore/events/file_chunk_request.c
|
|
||||||
${TOX_DIR}toxcore/events/file_recv.c
|
|
||||||
${TOX_DIR}toxcore/events/file_recv_chunk.c
|
|
||||||
${TOX_DIR}toxcore/events/file_recv_control.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_connection_status.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_lossless_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_lossy_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_message.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_name.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_read_receipt.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_request.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_status.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_status_message.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_typing.c
|
|
||||||
${TOX_DIR}toxcore/events/self_connection_status.c
|
|
||||||
${TOX_DIR}toxcore/events/group_custom_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/group_custom_private_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/group_invite.c
|
|
||||||
${TOX_DIR}toxcore/events/group_join_fail.c
|
|
||||||
${TOX_DIR}toxcore/events/group_message.c
|
|
||||||
${TOX_DIR}toxcore/events/group_moderation.c
|
|
||||||
${TOX_DIR}toxcore/events/group_password.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_exit.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_join.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_limit.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_name.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_status.c
|
|
||||||
${TOX_DIR}toxcore/events/group_privacy_state.c
|
|
||||||
${TOX_DIR}toxcore/events/group_private_message.c
|
|
||||||
${TOX_DIR}toxcore/events/group_self_join.c
|
|
||||||
${TOX_DIR}toxcore/events/group_topic.c
|
|
||||||
${TOX_DIR}toxcore/events/group_topic_lock.c
|
|
||||||
${TOX_DIR}toxcore/events/group_voice_state.c
|
|
||||||
${TOX_DIR}toxcore/forwarding.c
|
|
||||||
${TOX_DIR}toxcore/forwarding.h
|
|
||||||
${TOX_DIR}toxcore/friend_connection.c
|
|
||||||
${TOX_DIR}toxcore/friend_connection.h
|
|
||||||
${TOX_DIR}toxcore/friend_requests.c
|
|
||||||
${TOX_DIR}toxcore/friend_requests.h
|
|
||||||
${TOX_DIR}toxcore/group.c
|
|
||||||
${TOX_DIR}toxcore/group.h
|
|
||||||
${TOX_DIR}toxcore/group_announce.c
|
|
||||||
${TOX_DIR}toxcore/group_announce.h
|
|
||||||
${TOX_DIR}toxcore/group_moderation.c
|
|
||||||
${TOX_DIR}toxcore/group_moderation.h
|
|
||||||
${TOX_DIR}toxcore/group_chats.c
|
|
||||||
${TOX_DIR}toxcore/group_chats.h
|
|
||||||
${TOX_DIR}toxcore/group_common.h
|
|
||||||
${TOX_DIR}toxcore/group_connection.c
|
|
||||||
${TOX_DIR}toxcore/group_connection.h
|
|
||||||
${TOX_DIR}toxcore/group_onion_announce.c
|
|
||||||
${TOX_DIR}toxcore/group_onion_announce.h
|
|
||||||
${TOX_DIR}toxcore/group_pack.c
|
|
||||||
${TOX_DIR}toxcore/group_pack.h
|
|
||||||
${TOX_DIR}toxcore/LAN_discovery.c
|
|
||||||
${TOX_DIR}toxcore/LAN_discovery.h
|
|
||||||
${TOX_DIR}toxcore/list.c
|
|
||||||
${TOX_DIR}toxcore/list.h
|
|
||||||
${TOX_DIR}toxcore/logger.c
|
|
||||||
${TOX_DIR}toxcore/logger.h
|
|
||||||
${TOX_DIR}toxcore/Messenger.c
|
|
||||||
${TOX_DIR}toxcore/Messenger.h
|
|
||||||
${TOX_DIR}toxcore/mem.c
|
|
||||||
${TOX_DIR}toxcore/mem.h
|
|
||||||
${TOX_DIR}toxcore/mono_time.c
|
|
||||||
${TOX_DIR}toxcore/mono_time.h
|
|
||||||
${TOX_DIR}toxcore/net_crypto.c
|
|
||||||
${TOX_DIR}toxcore/net_crypto.h
|
|
||||||
${TOX_DIR}toxcore/network.c
|
|
||||||
${TOX_DIR}toxcore/network.h
|
|
||||||
${TOX_DIR}toxcore/onion_announce.c
|
|
||||||
${TOX_DIR}toxcore/onion_announce.h
|
|
||||||
${TOX_DIR}toxcore/onion.c
|
|
||||||
${TOX_DIR}toxcore/onion_client.c
|
|
||||||
${TOX_DIR}toxcore/onion_client.h
|
|
||||||
${TOX_DIR}toxcore/onion.h
|
|
||||||
${TOX_DIR}toxcore/ping_array.c
|
|
||||||
${TOX_DIR}toxcore/ping_array.h
|
|
||||||
${TOX_DIR}toxcore/ping.c
|
|
||||||
${TOX_DIR}toxcore/ping.h
|
|
||||||
${TOX_DIR}toxcore/shared_key_cache.c
|
|
||||||
${TOX_DIR}toxcore/shared_key_cache.h
|
|
||||||
${TOX_DIR}toxcore/state.c
|
|
||||||
${TOX_DIR}toxcore/state.h
|
|
||||||
${TOX_DIR}toxcore/TCP_client.c
|
|
||||||
${TOX_DIR}toxcore/TCP_client.h
|
|
||||||
${TOX_DIR}toxcore/TCP_common.c
|
|
||||||
${TOX_DIR}toxcore/TCP_common.h
|
|
||||||
${TOX_DIR}toxcore/TCP_connection.c
|
|
||||||
${TOX_DIR}toxcore/TCP_connection.h
|
|
||||||
${TOX_DIR}toxcore/TCP_server.c
|
|
||||||
${TOX_DIR}toxcore/TCP_server.h
|
|
||||||
${TOX_DIR}toxcore/timed_auth.c
|
|
||||||
${TOX_DIR}toxcore/timed_auth.h
|
|
||||||
${TOX_DIR}toxcore/tox_api.c
|
|
||||||
${TOX_DIR}toxcore/tox.c
|
|
||||||
${TOX_DIR}toxcore/tox_dispatch.c
|
|
||||||
${TOX_DIR}toxcore/tox_dispatch.h
|
|
||||||
${TOX_DIR}toxcore/tox_event.c
|
|
||||||
${TOX_DIR}toxcore/tox_event.h
|
|
||||||
${TOX_DIR}toxcore/tox_events.c
|
|
||||||
${TOX_DIR}toxcore/tox_events.h
|
|
||||||
${TOX_DIR}toxcore/tox.h
|
|
||||||
${TOX_DIR}toxcore/tox_private.c
|
|
||||||
${TOX_DIR}toxcore/tox_private.h
|
|
||||||
${TOX_DIR}toxcore/tox_pack.h
|
|
||||||
${TOX_DIR}toxcore/tox_pack.c
|
|
||||||
${TOX_DIR}toxcore/tox_unpack.c
|
|
||||||
${TOX_DIR}toxcore/tox_unpack.h
|
|
||||||
${TOX_DIR}toxcore/util.c
|
|
||||||
${TOX_DIR}toxcore/util.h
|
|
||||||
|
|
||||||
${TOX_DIR}toxencryptsave/defines.h
|
|
||||||
${TOX_DIR}toxencryptsave/toxencryptsave.c
|
|
||||||
${TOX_DIR}toxencryptsave/toxencryptsave.h
|
|
||||||
)
|
|
||||||
|
|
||||||
# HACK: "install" api headers into self
|
|
||||||
# this is dirty, should be binary dir
|
|
||||||
# TODO: add the others
|
|
||||||
configure_file(
|
|
||||||
${TOX_DIR}toxcore/tox.h
|
|
||||||
${TOX_DIR}tox/tox.h
|
|
||||||
@ONLY
|
|
||||||
)
|
|
||||||
configure_file(
|
|
||||||
${TOX_DIR}toxcore/tox_events.h
|
|
||||||
${TOX_DIR}tox/tox_events.h
|
|
||||||
@ONLY
|
|
||||||
)
|
|
||||||
configure_file(
|
|
||||||
${TOX_DIR}toxcore/tox_private.h
|
|
||||||
${TOX_DIR}tox/tox_private.h
|
|
||||||
@ONLY
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(toxcore PRIVATE "${TOX_DIR}toxcore")
|
|
||||||
target_include_directories(toxcore PUBLIC "${TOX_DIR}")
|
|
||||||
|
|
||||||
target_compile_definitions(toxcore PUBLIC USE_IPV6=1)
|
|
||||||
#target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_DEBUG)
|
|
||||||
target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_INFO)
|
|
||||||
|
|
||||||
find_package(unofficial-sodium CONFIG QUIET)
|
|
||||||
find_package(sodium QUIET)
|
find_package(sodium QUIET)
|
||||||
if(unofficial-sodium_FOUND) # vcpkg
|
if(unofficial-sodium_FOUND) # vcpkg
|
||||||
if(TARGET unofficial-sodium::sodium)
|
if(TARGET unofficial-sodium::sodium)
|
||||||
target_link_libraries(toxcore unofficial-sodium::sodium)
|
target_link_libraries(toxcore INTERFACE unofficial-sodium::sodium)
|
||||||
endif()
|
endif()
|
||||||
if(TARGET unofficial-sodium::sodium_config_public)
|
if(TARGET unofficial-sodium::sodium_config_public)
|
||||||
target_link_libraries(toxcore unofficial-sodium::sodium_config_public)
|
target_link_libraries(toxcore INTERFACE unofficial-sodium::sodium_config_public)
|
||||||
endif()
|
endif()
|
||||||
elseif(sodium_FOUND)
|
elseif(sodium_FOUND)
|
||||||
target_link_libraries(toxcore sodium)
|
target_link_libraries(toxcore INTERFACE sodium)
|
||||||
else()
|
else()
|
||||||
message(SEND_ERROR "missing libsodium")
|
message(SEND_ERROR "missing libsodium")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
target_link_libraries(toxcore ws2_32 iphlpapi)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_package(pthreads QUIET)
|
|
||||||
if(TARGET PThreads4W::PThreads4W)
|
|
||||||
target_link_libraries(toxcore PThreads4W::PThreads4W)
|
|
||||||
else()
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
target_link_libraries(toxcore Threads::Threads)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(DHT_Bootstrap EXCLUDE_FROM_ALL
|
|
||||||
${TOX_DIR}other/DHT_bootstrap.c
|
|
||||||
${TOX_DIR}other/bootstrap_node_packets.h
|
|
||||||
${TOX_DIR}other/bootstrap_node_packets.c
|
|
||||||
${TOX_DIR}testing/misc_tools.h
|
|
||||||
${TOX_DIR}testing/misc_tools.c
|
|
||||||
)
|
|
||||||
target_link_libraries(DHT_Bootstrap toxcore)
|
|
||||||
|
|
||||||
|
@ -52,14 +52,16 @@ add_executable(tomato
|
|||||||
./sdl_clipboard_utils.hpp
|
./sdl_clipboard_utils.hpp
|
||||||
./sdl_clipboard_utils.cpp
|
./sdl_clipboard_utils.cpp
|
||||||
|
|
||||||
./file_selector.hpp
|
./chat_gui/theme.hpp
|
||||||
./file_selector.cpp
|
./chat_gui/theme.cpp
|
||||||
|
./chat_gui/contact_list.hpp
|
||||||
./send_image_popup.hpp
|
./chat_gui/contact_list.cpp
|
||||||
./send_image_popup.cpp
|
./chat_gui/file_selector.hpp
|
||||||
|
./chat_gui/file_selector.cpp
|
||||||
./settings_window.hpp
|
./chat_gui/send_image_popup.hpp
|
||||||
./settings_window.cpp
|
./chat_gui/send_image_popup.cpp
|
||||||
|
./chat_gui/settings_window.hpp
|
||||||
|
./chat_gui/settings_window.cpp
|
||||||
|
|
||||||
./tox_ui_utils.hpp
|
./tox_ui_utils.hpp
|
||||||
./tox_ui_utils.cpp
|
./tox_ui_utils.cpp
|
||||||
|
314
src/chat_gui/contact_list.cpp
Normal file
314
src/chat_gui/contact_list.cpp
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
#include "./contact_list.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/contact/components.hpp>
|
||||||
|
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
//#include <imgui/imgui_internal.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
static void drawIconDirectLines(
|
||||||
|
const ImVec2 p0,
|
||||||
|
const ImVec2 p1_o,
|
||||||
|
const ImU32 col,
|
||||||
|
const float thickness
|
||||||
|
) {
|
||||||
|
#define PLINE(x0, y0, x1, y1) \
|
||||||
|
ImGui::GetWindowDrawList()->AddLine( \
|
||||||
|
{p0.x + p1_o.x*(x0), p0.y + p1_o.y*(y0)}, \
|
||||||
|
{p0.x + p1_o.x*(x1), p0.y + p1_o.y*(y1)}, \
|
||||||
|
col, \
|
||||||
|
thickness \
|
||||||
|
);
|
||||||
|
|
||||||
|
// arrow 1
|
||||||
|
// (3,1) -> (9,7)
|
||||||
|
PLINE(0.3f, 0.1f, 0.9f, 0.7f)
|
||||||
|
// (9,7) -> (9,5)
|
||||||
|
PLINE(0.9f, 0.7f, 0.9f, 0.5f)
|
||||||
|
// (9,7) -> (7,7)
|
||||||
|
PLINE(0.9f, 0.7f, 0.7f, 0.7f)
|
||||||
|
|
||||||
|
// arrow 2
|
||||||
|
// (7,9) -> (1,3)
|
||||||
|
PLINE(0.7f, 0.9f, 0.1f, 0.3f)
|
||||||
|
// (1,3) -> (3,3)
|
||||||
|
PLINE(0.1f, 0.3f, 0.3f, 0.3f)
|
||||||
|
// (1,3) -> (1,5)
|
||||||
|
PLINE(0.1f, 0.3f, 0.1f, 0.5f)
|
||||||
|
#undef PLINE
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawIconDirect(
|
||||||
|
const ImVec2 p0,
|
||||||
|
const ImVec2 p1_o,
|
||||||
|
const ImU32 col_main,
|
||||||
|
const ImU32 col_back
|
||||||
|
) {
|
||||||
|
// dark background
|
||||||
|
// the circle looks bad in light mode
|
||||||
|
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
|
||||||
|
drawIconDirectLines(p0, p1_o, col_back, 4.0f);
|
||||||
|
drawIconDirectLines(p0, p1_o, col_main, 1.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawIconCloud(
|
||||||
|
const ImVec2 p0,
|
||||||
|
const ImVec2 p1_o,
|
||||||
|
const ImU32 col_main,
|
||||||
|
const ImU32 col_back
|
||||||
|
) {
|
||||||
|
std::array<ImVec2, 19> points {{
|
||||||
|
{0.2f, 0.9f},
|
||||||
|
{0.8f, 0.9f},
|
||||||
|
{0.9f, 0.8f},
|
||||||
|
{0.9f, 0.7f},
|
||||||
|
{0.7f, 0.7f},
|
||||||
|
{0.9f, 0.5f},
|
||||||
|
{0.9f, 0.4f},
|
||||||
|
{0.8f, 0.2f},
|
||||||
|
{0.6f, 0.2f},
|
||||||
|
{0.5f, 0.3f},
|
||||||
|
{0.5f, 0.5f},
|
||||||
|
{0.4f, 0.4f},
|
||||||
|
{0.3f, 0.4f},
|
||||||
|
{0.2f, 0.5f},
|
||||||
|
{0.2f, 0.6f},
|
||||||
|
{0.3f, 0.7f},
|
||||||
|
{0.1f, 0.7f},
|
||||||
|
{0.1f, 0.8f},
|
||||||
|
{0.2f, 0.9f},
|
||||||
|
}};
|
||||||
|
for (auto& v : points) {
|
||||||
|
v.y -= 0.1f;
|
||||||
|
v = {p0.x + p1_o.x*v.x, p0.y + p1_o.y*v.y};
|
||||||
|
}
|
||||||
|
// the circle looks bad in light mode
|
||||||
|
//ImGui::GetWindowDrawList()->AddCircleFilled({p0.x + p1_o.x*0.5f, p0.y + p1_o.y*0.5f}, p1_o.x*0.5f, col_back);
|
||||||
|
ImGui::GetWindowDrawList()->AddPolyline(points.data(), points.size(), col_back, ImDrawFlags_None, 4.f);
|
||||||
|
ImGui::GetWindowDrawList()->AddPolyline(points.data(), points.size(), col_main, ImDrawFlags_None, 1.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderAvatar(
|
||||||
|
const Theme& th,
|
||||||
|
ContactTextureCache& contact_tc,
|
||||||
|
const Contact3Handle c,
|
||||||
|
ImVec2 box
|
||||||
|
) {
|
||||||
|
// deploy dummy of same size and check visibility
|
||||||
|
const auto orig_curser_pos = ImGui::GetCursorPos();
|
||||||
|
ImGui::Dummy(box);
|
||||||
|
if (ImGui::IsItemVisible()) {
|
||||||
|
ImGui::SetCursorPos(orig_curser_pos); // reset for actual img
|
||||||
|
|
||||||
|
ImVec4 color_current = th.getColor<ThemeCol_Contact::avatar_offline>();
|
||||||
|
if (c.all_of<Contact::Components::ConnectionState>()) {
|
||||||
|
const auto c_state = c.get<Contact::Components::ConnectionState>().state;
|
||||||
|
if (c_state == Contact::Components::ConnectionState::State::direct) {
|
||||||
|
color_current = th.getColor<ThemeCol_Contact::avatar_online_direct>();
|
||||||
|
} else if (c_state == Contact::Components::ConnectionState::State::cloud) {
|
||||||
|
color_current = th.getColor<ThemeCol_Contact::avatar_online_cloud>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// avatar
|
||||||
|
const auto [id, width, height] = contact_tc.get(c);
|
||||||
|
ImGui::Image(
|
||||||
|
id,
|
||||||
|
box,
|
||||||
|
{0, 0},
|
||||||
|
{1, 1},
|
||||||
|
{1, 1, 1, 1},
|
||||||
|
color_current
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renderContactBig(
|
||||||
|
const Theme& th,
|
||||||
|
ContactTextureCache& contact_tc,
|
||||||
|
const Contact3Handle c,
|
||||||
|
int line_height,
|
||||||
|
const bool unread,
|
||||||
|
const bool selectable,
|
||||||
|
const bool selected
|
||||||
|
) {
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
if (line_height < 1) {
|
||||||
|
line_height = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we dont need ### bc there is no named prefix
|
||||||
|
auto label = "##" + std::to_string(entt::to_integral(c.entity()));
|
||||||
|
|
||||||
|
const bool request_incoming = c.all_of<Contact::Components::RequestIncoming>();
|
||||||
|
const bool request_outgoing = c.all_of<Contact::Components::TagRequestOutgoing>();
|
||||||
|
|
||||||
|
ImVec2 orig_curser_pos = ImGui::GetCursorPos();
|
||||||
|
// HACK: fake selected to make it draw a box for us
|
||||||
|
const bool show_selected = request_incoming || request_outgoing || selected;
|
||||||
|
if (request_incoming) {
|
||||||
|
ImGui::PushStyleColor(
|
||||||
|
ImGuiCol_Header,
|
||||||
|
th.getColor<ThemeCol_Contact::request_incoming>()
|
||||||
|
);
|
||||||
|
} else if (request_outgoing) {
|
||||||
|
ImGui::PushStyleColor(
|
||||||
|
ImGuiCol_Header,
|
||||||
|
th.getColor<ThemeCol_Contact::request_outgoing>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
|
||||||
|
|
||||||
|
bool got_selected = false;
|
||||||
|
if (selectable) {
|
||||||
|
got_selected = ImGui::Selectable(label.c_str(), show_selected, ImGuiSelectableFlags_None, {0, line_height*TEXT_BASE_HEIGHT});
|
||||||
|
} else {
|
||||||
|
got_selected = ImGui::InvisibleButton(label.c_str(), {-FLT_MIN, line_height*TEXT_BASE_HEIGHT});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request_incoming || request_outgoing) {
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* cstate = c.try_get<Contact::Components::ConnectionState>();
|
||||||
|
if (ImGui::BeginItemTooltip()) {
|
||||||
|
if (cstate != nullptr) {
|
||||||
|
ImGui::Text("Connection state: %s",
|
||||||
|
(cstate->state == Contact::Components::ConnectionState::disconnected)
|
||||||
|
? "offline"
|
||||||
|
: (cstate->state == Contact::Components::ConnectionState::direct)
|
||||||
|
? "online (direct)"
|
||||||
|
: "online (cloud)"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ImGui::TextUnformatted("Connection state: unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
const auto* slt = c.try_get<Contact::Components::StatusText>();
|
||||||
|
slt != nullptr &&
|
||||||
|
!slt->text.empty()
|
||||||
|
) {
|
||||||
|
ImGui::SeparatorText("Status Text");
|
||||||
|
//ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]);
|
||||||
|
ImGui::TextUnformatted(slt->text.c_str());
|
||||||
|
//ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add a whole bunch more info
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 post_curser_pos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
|
ImVec2 img_curser {
|
||||||
|
orig_curser_pos.x + ImGui::GetStyle().FramePadding.x,
|
||||||
|
orig_curser_pos.y + ImGui::GetStyle().FramePadding.y
|
||||||
|
};
|
||||||
|
|
||||||
|
float img_y {TEXT_BASE_HEIGHT*line_height - ImGui::GetStyle().FramePadding.y*2};
|
||||||
|
|
||||||
|
ImGui::SetCursorPos(img_curser);
|
||||||
|
|
||||||
|
renderAvatar(th, contact_tc, c, {img_y, img_y});
|
||||||
|
|
||||||
|
const float same_line_spacing = ImGui::GetStyle().ItemSpacing.x*0.5f;
|
||||||
|
ImGui::SameLine(0.f, same_line_spacing);
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
{
|
||||||
|
{ // line 1
|
||||||
|
if (line_height == 1 && cstate != nullptr) {
|
||||||
|
// icon pos
|
||||||
|
auto p0 = ImGui::GetCursorScreenPos();
|
||||||
|
p0.y += ImGui::GetStyle().FramePadding.y;
|
||||||
|
ImVec2 p1_o = {img_y, img_y}; // img_y is 1 line_height in this case
|
||||||
|
|
||||||
|
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
|
||||||
|
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
|
||||||
|
drawIconDirect(
|
||||||
|
p0,
|
||||||
|
p1_o,
|
||||||
|
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_direct>()),
|
||||||
|
col_back
|
||||||
|
);
|
||||||
|
} else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon
|
||||||
|
drawIconCloud(
|
||||||
|
p0,
|
||||||
|
p1_o,
|
||||||
|
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_cloud>()),
|
||||||
|
col_back
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ImGui::Dummy(p1_o);
|
||||||
|
ImGui::SameLine(0.f, same_line_spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("%s%s", unread?"* ":"", (c.all_of<Contact::Components::Name>() ? c.get<Contact::Components::Name>().name.c_str() : "<unk>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// line 2
|
||||||
|
if (line_height >= 2) {
|
||||||
|
if (request_incoming) {
|
||||||
|
ImGui::TextUnformatted("Incoming request/invite");
|
||||||
|
} else if (request_outgoing) {
|
||||||
|
ImGui::TextUnformatted("Outgoing request/invite");
|
||||||
|
} else {
|
||||||
|
if (cstate != nullptr) {
|
||||||
|
// icon pos
|
||||||
|
auto p0 = ImGui::GetCursorScreenPos();
|
||||||
|
p0.y += ImGui::GetStyle().FramePadding.y;
|
||||||
|
const float box_hight = TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2;
|
||||||
|
ImVec2 p1_o = {box_hight, box_hight};
|
||||||
|
|
||||||
|
const ImU32 col_back = ImGui::GetColorU32(th.getColor<ThemeCol_Contact::icon_backdrop>());
|
||||||
|
if (cstate->state == Contact::Components::ConnectionState::direct) { // direct icon
|
||||||
|
drawIconDirect(
|
||||||
|
p0,
|
||||||
|
p1_o,
|
||||||
|
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_direct>()),
|
||||||
|
col_back
|
||||||
|
);
|
||||||
|
} else if (cstate->state == Contact::Components::ConnectionState::cloud) { // cloud icon
|
||||||
|
drawIconCloud(
|
||||||
|
p0,
|
||||||
|
p1_o,
|
||||||
|
ImGui::GetColorU32(th.getColor<ThemeCol_Contact::avatar_online_cloud>()),
|
||||||
|
col_back
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ImGui::Dummy(p1_o);
|
||||||
|
ImGui::SameLine(0.f, same_line_spacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
const auto* slt = c.try_get<Contact::Components::StatusText>();
|
||||||
|
slt != nullptr &&
|
||||||
|
!slt->text.empty() &&
|
||||||
|
slt->first_line_length > 0 &&
|
||||||
|
slt->first_line_length <= slt->text.size()
|
||||||
|
) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]);
|
||||||
|
ImGui::TextUnformatted(slt->text.c_str(), slt->text.c_str() + slt->first_line_length);
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
} else {
|
||||||
|
ImGui::TextDisabled(""); // or dummy?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// line 3
|
||||||
|
//if (line_height >= 3) {
|
||||||
|
// constexpr std::string_view test_text{"text"};
|
||||||
|
// ImGui::RenderTextEllipsis(ImGui::GetWindowDrawList(), ImVec2{}, ImVec2{}, 1.f, 1.f, test_text.data(), test_text.data()+test_text.size(), nullptr);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::SetCursorPos(post_curser_pos);
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
return got_selected;
|
||||||
|
}
|
||||||
|
|
43
src/chat_gui/contact_list.hpp
Normal file
43
src/chat_gui/contact_list.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "./texture_cache_defs.hpp"
|
||||||
|
|
||||||
|
#include "./theme.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/contact/contact_model3.hpp>
|
||||||
|
|
||||||
|
enum class ThemeCol_Contact {
|
||||||
|
request_incoming,
|
||||||
|
request_outgoing,
|
||||||
|
|
||||||
|
avatar_online_direct,
|
||||||
|
avatar_online_cloud,
|
||||||
|
avatar_offline,
|
||||||
|
|
||||||
|
icon_backdrop,
|
||||||
|
};
|
||||||
|
|
||||||
|
void renderAvatar(
|
||||||
|
const Theme& th,
|
||||||
|
ContactTextureCache& contact_tc,
|
||||||
|
const Contact3Handle c,
|
||||||
|
ImVec2 box
|
||||||
|
);
|
||||||
|
|
||||||
|
// returns true if clicked, if selectable, will highlight on hover and respect selected
|
||||||
|
// TODO: refine
|
||||||
|
// +------+
|
||||||
|
// | | *Name (Alias?)
|
||||||
|
// |Avatar| Satus Message <-- richpresence interface?
|
||||||
|
// | | user status (online/away/busy)-direct/relayed / offline <-- last text?
|
||||||
|
// +------+
|
||||||
|
bool renderContactBig(
|
||||||
|
const Theme& th,
|
||||||
|
ContactTextureCache& contact_tc,
|
||||||
|
const Contact3Handle c,
|
||||||
|
int line_height = 3,
|
||||||
|
const bool unread = false,
|
||||||
|
const bool selectable = false,
|
||||||
|
const bool selected = false
|
||||||
|
);
|
||||||
|
|
@ -1,9 +1,10 @@
|
|||||||
#include "./send_image_popup.hpp"
|
#include "./send_image_popup.hpp"
|
||||||
|
|
||||||
#include "./image_loader_sdl_bmp.hpp"
|
#include "../image_loader_sdl_bmp.hpp"
|
||||||
#include "./image_loader_stb.hpp"
|
#include "../image_loader_stb.hpp"
|
||||||
#include "./image_loader_webp.hpp"
|
#include "../image_loader_webp.hpp"
|
||||||
#include "./image_loader_qoi.hpp"
|
#include "../image_loader_qoi.hpp"
|
||||||
|
#include "../image_loader_sdl_image.hpp"
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ SendImagePopup::SendImagePopup(TextureUploaderI& tu) : _tu(tu) {
|
|||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSTB>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendImagePopup::reset(void) {
|
void SendImagePopup::reset(void) {
|
@ -5,8 +5,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "./image_loader.hpp"
|
#include "../image_loader.hpp"
|
||||||
#include "./texture_cache.hpp"
|
#include "../texture_cache.hpp"
|
||||||
|
|
||||||
struct SendImagePopup {
|
struct SendImagePopup {
|
||||||
TextureUploaderI& _tu;
|
TextureUploaderI& _tu;
|
12
src/chat_gui/texture_cache_defs.hpp
Normal file
12
src/chat_gui/texture_cache_defs.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
|
#include "../texture_cache.hpp"
|
||||||
|
#include "../tox_avatar_loader.hpp"
|
||||||
|
#include "../message_image_loader.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
using ContactTextureCache = TextureCache<void*, Contact3, ToxAvatarLoader>;
|
||||||
|
using MessageTextureCache = TextureCache<void*, Message3Handle, MessageImageLoader>;
|
||||||
|
|
62
src/chat_gui/theme.cpp
Normal file
62
src/chat_gui/theme.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include "./theme.hpp"
|
||||||
|
|
||||||
|
// HACK: includes everything and sets theme defaults
|
||||||
|
#include "./contact_list.hpp"
|
||||||
|
|
||||||
|
//#include <iostream>
|
||||||
|
|
||||||
|
//enum class TestThemeSet {
|
||||||
|
//Value1,
|
||||||
|
//};
|
||||||
|
|
||||||
|
//// specialization
|
||||||
|
////template<>
|
||||||
|
////std::string typeValueName(TestThemeSet v) {
|
||||||
|
////switch (v) {
|
||||||
|
////case TestThemeSet::Value1: return "Value1";
|
||||||
|
////default: return "unk";
|
||||||
|
////}
|
||||||
|
////}
|
||||||
|
|
||||||
|
Theme::Theme(void) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theme::update(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Theme::load(void) {
|
||||||
|
name = "Default";
|
||||||
|
|
||||||
|
//setColor<TestThemeSet::Value1>(ImVec4{});
|
||||||
|
//std::cout << "test value name: " << getColorName<TestThemeSet::Value1>() << "\n";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Theme::store(void) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Theme getDefaultThemeDark(void) {
|
||||||
|
Theme t;
|
||||||
|
|
||||||
|
t.setColor<ThemeCol_Contact::request_incoming >({0.98f, 0.41f, 0.26f, 0.52f});
|
||||||
|
t.setColor<ThemeCol_Contact::request_outgoing >({0.98f, 0.26f, 0.41f, 0.52f});
|
||||||
|
|
||||||
|
t.setColor<ThemeCol_Contact::avatar_online_direct >({0.3f, 1.0f, 0.0f, 1.0f});
|
||||||
|
t.setColor<ThemeCol_Contact::avatar_online_cloud >({0.0f, 1.0f, 0.8f, 1.0f});
|
||||||
|
t.setColor<ThemeCol_Contact::avatar_offline >({0.4f, 0.4f, 0.4f, 1.0f});
|
||||||
|
|
||||||
|
t.setColor<ThemeCol_Contact::icon_backdrop >({0.0f, 0.0f, 0.0f, 0.4f});
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
Theme getDefaultThemeLight(void) {
|
||||||
|
// HACK: inherit dark and only diff
|
||||||
|
Theme t = getDefaultThemeDark();
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
76
src/chat_gui/theme.hpp
Normal file
76
src/chat_gui/theme.hpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
|
#include <entt/container/dense_map.hpp>
|
||||||
|
#include <entt/core/type_info.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// default is resolving to its value
|
||||||
|
template<typename T>
|
||||||
|
std::string typeValueName(T V) {
|
||||||
|
return std::to_string(static_cast<std::underlying_type_t<T>>(V));
|
||||||
|
}
|
||||||
|
|
||||||
|
// stores theming values and colors not expressed by imgui directly
|
||||||
|
struct Theme {
|
||||||
|
using key_type = entt::id_type;
|
||||||
|
|
||||||
|
entt::dense_map<key_type, ImVec4> colors;
|
||||||
|
entt::dense_map<key_type, std::string> colors_name;
|
||||||
|
|
||||||
|
// TODO: spec out dependencies
|
||||||
|
|
||||||
|
// TODO: what for
|
||||||
|
entt::dense_map<key_type, float> single_values;
|
||||||
|
|
||||||
|
std::string name; // theme name
|
||||||
|
|
||||||
|
Theme(void);
|
||||||
|
|
||||||
|
// call when any color changed, so dependencies can be resolved
|
||||||
|
void update(void);
|
||||||
|
|
||||||
|
template<auto V>
|
||||||
|
void setColor(ImVec4 color) {
|
||||||
|
constexpr auto key = entt::type_hash<entt::tag<static_cast<entt::id_type>(V)>>::value();
|
||||||
|
colors[key] = color;
|
||||||
|
|
||||||
|
if (!colors_name.contains(key)) {
|
||||||
|
std::string key_name = static_cast<std::string>(
|
||||||
|
entt::type_name<decltype(V)>::value()
|
||||||
|
) + ":" + typeValueName(V);
|
||||||
|
colors_name[key] = key_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<auto V>
|
||||||
|
ImVec4 getColor(void) const {
|
||||||
|
constexpr auto key = entt::type_hash<entt::tag<static_cast<entt::id_type>(V)>>::value();
|
||||||
|
const auto it = colors.find(key);
|
||||||
|
if (it != colors.end()) {
|
||||||
|
return it->second;
|
||||||
|
} else {
|
||||||
|
return {}; // TODO: pink as default?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<auto V>
|
||||||
|
std::string_view getColorName(void) const {
|
||||||
|
constexpr auto key = entt::type_hash<entt::tag<static_cast<entt::id_type>(V)>>::value();
|
||||||
|
if (colors_name.contains(key)) {
|
||||||
|
return colors_name.at(key);
|
||||||
|
} else {
|
||||||
|
return "unk";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: actually serialize from config?
|
||||||
|
bool load(void);
|
||||||
|
bool store(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
Theme getDefaultThemeDark(void);
|
||||||
|
Theme getDefaultThemeLight(void);
|
||||||
|
|
@ -1,7 +1,5 @@
|
|||||||
#include "./chat_gui4.hpp"
|
#include "./chat_gui4.hpp"
|
||||||
|
|
||||||
#include "./file_selector.hpp"
|
|
||||||
|
|
||||||
#include <solanaceae/message3/components.hpp>
|
#include <solanaceae/message3/components.hpp>
|
||||||
#include <solanaceae/tox_messages/components.hpp>
|
#include <solanaceae/tox_messages/components.hpp>
|
||||||
#include <solanaceae/contact/components.hpp>
|
#include <solanaceae/contact/components.hpp>
|
||||||
@ -15,6 +13,8 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include "./chat_gui/contact_list.hpp"
|
||||||
|
|
||||||
#include "./media_meta_info_loader.hpp"
|
#include "./media_meta_info_loader.hpp"
|
||||||
#include "./sdl_clipboard_utils.hpp"
|
#include "./sdl_clipboard_utils.hpp"
|
||||||
|
|
||||||
@ -145,8 +145,9 @@ ChatGui4::ChatGui4(
|
|||||||
Contact3Registry& cr,
|
Contact3Registry& cr,
|
||||||
TextureUploaderI& tu,
|
TextureUploaderI& tu,
|
||||||
ContactTextureCache& contact_tc,
|
ContactTextureCache& contact_tc,
|
||||||
MessageTextureCache& msg_tc
|
MessageTextureCache& msg_tc,
|
||||||
) : _conf(conf), _rmm(rmm), _cr(cr), _contact_tc(contact_tc), _msg_tc(msg_tc), _sip(tu) {
|
Theme& theme
|
||||||
|
) : _conf(conf), _rmm(rmm), _cr(cr), _contact_tc(contact_tc), _msg_tc(msg_tc), _theme(theme), _sip(tu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatGui4::~ChatGui4(void) {
|
ChatGui4::~ChatGui4(void) {
|
||||||
@ -197,16 +198,42 @@ float ChatGui4::render(float time_delta) {
|
|||||||
sub_contacts = &_cr.get<Contact::Components::ParentOf>(*_selected_contact).subs;
|
sub_contacts = &_cr.get<Contact::Components::ParentOf>(*_selected_contact).subs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, true)) {
|
const bool highlight_private {!_cr.all_of<Contact::Components::TagPrivate>(*_selected_contact)};
|
||||||
//if (_cr.all_of<Contact::Components::ParentOf>(*_selected_contact)) {
|
|
||||||
if (sub_contacts != nullptr) {
|
if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, ImGuiChildFlags_Border, ImGuiWindowFlags_MenuBar)) {
|
||||||
|
if (ImGui::BeginMenuBar()) {
|
||||||
|
if (ImGui::BeginMenu("debug")) {
|
||||||
|
ImGui::Checkbox("show extra info", &_show_chat_extra_info);
|
||||||
|
ImGui::Checkbox("show avatar transfers", &_show_chat_avatar_tf);
|
||||||
|
|
||||||
|
ImGui::SeparatorText("tox");
|
||||||
|
|
||||||
|
// TODO: cheese it and rename to copy id?
|
||||||
|
if (_cr.all_of<Contact::Components::ToxGroupPersistent>(*_selected_contact)) {
|
||||||
|
if (ImGui::MenuItem("copy ngc chatid")) {
|
||||||
|
const auto& chat_id = _cr.get<Contact::Components::ToxGroupPersistent>(*_selected_contact).chat_id.data;
|
||||||
|
const auto chat_id_str = bin2hex(std::vector<uint8_t>{chat_id.begin(), chat_id.end()});
|
||||||
|
ImGui::SetClipboardText(chat_id_str.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderContactBig(_theme, _contact_tc, {_cr, *_selected_contact}, 3, false, false, false);
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if (sub_contacts != nullptr && !_cr.all_of<Contact::Components::TagPrivate>(*_selected_contact) && _cr.all_of<Contact::Components::TagGroup>(*_selected_contact)) {
|
||||||
if (!sub_contacts->empty()) {
|
if (!sub_contacts->empty()) {
|
||||||
if (ImGui::BeginChild("subcontacts", {150, -100}, true)) {
|
if (ImGui::BeginChild("subcontacts", {TEXT_BASE_WIDTH * 18.f, -100.f}, true)) {
|
||||||
ImGui::Text("subs: %zu", sub_contacts->size());
|
ImGui::Text("subs: %zu", sub_contacts->size());
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
for (const auto& c : *sub_contacts) {
|
for (const auto& c : *sub_contacts) {
|
||||||
// TODO: can a sub be selected? no
|
// TODO: can a sub be selected? no
|
||||||
if (renderSubContactListContact(c, _selected_contact.has_value() && *_selected_contact == c)) {
|
//if (renderSubContactListContact(c, _selected_contact.has_value() && *_selected_contact == c)) {
|
||||||
|
if (renderContactBig(_theme, _contact_tc, {_cr, c}, 1)) {
|
||||||
_text_input_buffer.insert(0, (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>") + ": ");
|
_text_input_buffer.insert(0, (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>") + ": ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,27 +284,11 @@ float ChatGui4::render(float time_delta) {
|
|||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginChild("message_log", {0, -100}, false, ImGuiWindowFlags_MenuBar)) {
|
if (ImGui::BeginChild("message_log", {0, -100}, ImGuiChildFlags_None)) {
|
||||||
if (ImGui::BeginMenuBar()) {
|
// TODO: background image?
|
||||||
if (ImGui::BeginMenu("debug")) {
|
//auto p_min = ImGui::GetCursorScreenPos();
|
||||||
ImGui::Checkbox("show extra info", &_show_chat_extra_info);
|
//auto a_max = ImGui::GetContentRegionAvail();
|
||||||
ImGui::Checkbox("show avatar transfers", &_show_chat_avatar_tf);
|
//ImGui::GetWindowDrawList()->AddImage(0, p_min, {p_min.x+a_max.x, p_min.y+a_max.y});
|
||||||
|
|
||||||
ImGui::SeparatorText("tox");
|
|
||||||
|
|
||||||
// TODO: cheese it and rename to copy id?
|
|
||||||
if (_cr.all_of<Contact::Components::ToxGroupPersistent>(*_selected_contact)) {
|
|
||||||
if (ImGui::MenuItem("copy ngc chatid")) {
|
|
||||||
const auto& chat_id = _cr.get<Contact::Components::ToxGroupPersistent>(*_selected_contact).chat_id.data;
|
|
||||||
const auto chat_id_str = bin2hex(std::vector<uint8_t>{chat_id.begin(), chat_id.end()});
|
|
||||||
ImGui::SetClipboardText(chat_id_str.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
ImGui::EndMenuBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* msg_reg_ptr = _rmm.get(*_selected_contact);
|
auto* msg_reg_ptr = _rmm.get(*_selected_contact);
|
||||||
|
|
||||||
@ -287,7 +298,7 @@ float ChatGui4::render(float time_delta) {
|
|||||||
ImGuiTableFlags_SizingFixedFit
|
ImGuiTableFlags_SizingFixedFit
|
||||||
;
|
;
|
||||||
if (msg_reg_ptr != nullptr && ImGui::BeginTable("chat_table", 5, table_flags)) {
|
if (msg_reg_ptr != nullptr && ImGui::BeginTable("chat_table", 5, table_flags)) {
|
||||||
ImGui::TableSetupColumn("name", 0, TEXT_BASE_WIDTH * 15.f);
|
ImGui::TableSetupColumn("name", 0, TEXT_BASE_WIDTH * 16.f);
|
||||||
ImGui::TableSetupColumn("message", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("message", ImGuiTableColumnFlags_WidthStretch);
|
||||||
ImGui::TableSetupColumn("delivered/read");
|
ImGui::TableSetupColumn("delivered/read");
|
||||||
ImGui::TableSetupColumn("timestamp");
|
ImGui::TableSetupColumn("timestamp");
|
||||||
@ -315,7 +326,7 @@ float ChatGui4::render(float time_delta) {
|
|||||||
msg_reg.view<Components::UnreadFade>().each([&to_remove, time_delta](const Message3 e, Components::UnreadFade& fade) {
|
msg_reg.view<Components::UnreadFade>().each([&to_remove, time_delta](const Message3 e, Components::UnreadFade& fade) {
|
||||||
// TODO: configurable
|
// TODO: configurable
|
||||||
const float fade_duration = 7.5f;
|
const float fade_duration = 7.5f;
|
||||||
fade.fade -= 1.f/fade_duration * std::min<float>(time_delta, 1.f/10.f); // fps but not below 10 for smooth fade
|
fade.fade -= 1.f/fade_duration * std::min<float>(time_delta, 1.f/8.f); // fps but not below 8 for smooth-ish fade
|
||||||
if (fade.fade <= 0.f) {
|
if (fade.fade <= 0.f) {
|
||||||
to_remove.push_back(e);
|
to_remove.push_back(e);
|
||||||
}
|
}
|
||||||
@ -375,6 +386,10 @@ float ChatGui4::render(float time_delta) {
|
|||||||
|
|
||||||
// name
|
// name
|
||||||
if (ImGui::TableNextColumn()) {
|
if (ImGui::TableNextColumn()) {
|
||||||
|
const float img_y {TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2};
|
||||||
|
renderAvatar(_theme, _contact_tc, {_cr, c_from.c}, {img_y, img_y});
|
||||||
|
ImGui::SameLine(0.f, ImGui::GetStyle().ItemSpacing.x*0.5f);
|
||||||
|
|
||||||
if (_cr.all_of<Contact::Components::Name>(c_from.c)) {
|
if (_cr.all_of<Contact::Components::Name>(c_from.c)) {
|
||||||
ImGui::TextUnformatted(_cr.get<Contact::Components::Name>(c_from.c).name.c_str());
|
ImGui::TextUnformatted(_cr.get<Contact::Components::Name>(c_from.c).name.c_str());
|
||||||
} else {
|
} else {
|
||||||
@ -417,7 +432,7 @@ float ChatGui4::render(float time_delta) {
|
|||||||
std::optional<ImVec4> row_bg;
|
std::optional<ImVec4> row_bg;
|
||||||
|
|
||||||
// private group message
|
// private group message
|
||||||
if (_cr.any_of<Contact::Components::TagSelfWeak, Contact::Components::TagSelfStrong>(c_to.c)) {
|
if (highlight_private && _cr.any_of<Contact::Components::TagSelfWeak, Contact::Components::TagSelfStrong>(c_to.c)) {
|
||||||
const ImVec4 priv_msg_hi_col = ImVec4(0.5f, 0.2f, 0.5f, 0.35f);
|
const ImVec4 priv_msg_hi_col = ImVec4(0.5f, 0.2f, 0.5f, 0.35f);
|
||||||
ImU32 row_bg_color = ImGui::GetColorU32(priv_msg_hi_col);
|
ImU32 row_bg_color = ImGui::GetColorU32(priv_msg_hi_col);
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, row_bg_color);
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, row_bg_color);
|
||||||
@ -456,8 +471,11 @@ float ChatGui4::render(float time_delta) {
|
|||||||
if (ImGui::TableNextColumn()) {
|
if (ImGui::TableNextColumn()) {
|
||||||
// TODO: theming for hardcoded values
|
// TODO: theming for hardcoded values
|
||||||
|
|
||||||
if (msg_reg.all_of<Message::Components::Remote::TimestampReceived>(e)) {
|
if (!msg_reg.all_of<Message::Components::ReceivedBy>(e)) {
|
||||||
const auto list = msg_reg.get<Message::Components::Remote::TimestampReceived>(e).ts;
|
// TODO: dedup?
|
||||||
|
ImGui::TextDisabled("_");
|
||||||
|
} else {
|
||||||
|
const auto list = msg_reg.get<Message::Components::ReceivedBy>(e).ts;
|
||||||
// wrongly assumes contacts never get removed from a group
|
// wrongly assumes contacts never get removed from a group
|
||||||
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
|
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
|
||||||
// if partically delivered
|
// if partically delivered
|
||||||
@ -471,6 +489,7 @@ float ChatGui4::render(float time_delta) {
|
|||||||
std::string synced_by_text {"delivery confirmed by:"};
|
std::string synced_by_text {"delivery confirmed by:"};
|
||||||
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
|
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
|
||||||
|
|
||||||
|
size_t other_contacts {0};
|
||||||
for (const auto& [c, syned_ts] : list) {
|
for (const auto& [c, syned_ts] : list) {
|
||||||
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
|
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
|
||||||
//synced_by_text += "\n sself(!)"; // makes no sense
|
//synced_by_text += "\n sself(!)"; // makes no sense
|
||||||
@ -480,23 +499,26 @@ float ChatGui4::render(float time_delta) {
|
|||||||
} else {
|
} else {
|
||||||
synced_by_text += "\n >" + (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>");
|
synced_by_text += "\n >" + (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>");
|
||||||
}
|
}
|
||||||
|
other_contacts += 1;
|
||||||
const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1;
|
const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1;
|
||||||
synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)";
|
synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)";
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Text("%s", synced_by_text.c_str());
|
if (other_contacts > 0) {
|
||||||
|
ImGui::Text("%s", synced_by_text.c_str());
|
||||||
|
} else {
|
||||||
|
ImGui::TextUnformatted("no delivery confirmation");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ImGui::TextDisabled("_");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
// TODO: dedup
|
// TODO: dedup
|
||||||
if (msg_reg.all_of<Message::Components::Remote::TimestampRead>(e)) {
|
if (msg_reg.all_of<Message::Components::ReadBy>(e)) {
|
||||||
const auto list = msg_reg.get<Message::Components::Remote::TimestampRead>(e).ts;
|
const auto list = msg_reg.get<Message::Components::ReadBy>(e).ts;
|
||||||
// wrongly assumes contacts never get removed from a group
|
// wrongly assumes contacts never get removed from a group
|
||||||
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
|
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
|
||||||
// if partially read
|
// if partially read
|
||||||
@ -1045,13 +1067,13 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove?
|
// TODO: remove?
|
||||||
if (reg.all_of<Message::Components::Remote::TimestampReceived>(e)) {
|
if (reg.all_of<Message::Components::ReceivedBy>(e)) {
|
||||||
std::string synced_by_text {"receivedBy:"};
|
std::string synced_by_text {"receivedBy:"};
|
||||||
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
|
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
|
||||||
|
|
||||||
for (const auto& [c, syned_ts] : reg.get<Message::Components::Remote::TimestampReceived>(e).ts) {
|
for (const auto& [c, syned_ts] : reg.get<Message::Components::ReceivedBy>(e).ts) {
|
||||||
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
|
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
|
||||||
synced_by_text += "\n sself(!)"; // makes no sense
|
synced_by_text += "\n sself"; // required (except when synced externally)
|
||||||
} else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) {
|
} else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) {
|
||||||
synced_by_text += "\n wself";
|
synced_by_text += "\n wself";
|
||||||
} else {
|
} else {
|
||||||
@ -1069,7 +1091,18 @@ void ChatGui4::renderContactList(void) {
|
|||||||
if (ImGui::BeginChild("contacts", {TEXT_BASE_WIDTH*35, 0})) {
|
if (ImGui::BeginChild("contacts", {TEXT_BASE_WIDTH*35, 0})) {
|
||||||
//for (const auto& c : _cm.getBigContacts()) {
|
//for (const auto& c : _cm.getBigContacts()) {
|
||||||
for (const auto& c : _cr.view<Contact::Components::TagBig>()) {
|
for (const auto& c : _cr.view<Contact::Components::TagBig>()) {
|
||||||
if (renderContactListContactBig(c, _selected_contact.has_value() && *_selected_contact == c)) {
|
const bool selected = _selected_contact.has_value() && *_selected_contact == c;
|
||||||
|
|
||||||
|
// TODO: is there a better way?
|
||||||
|
// maybe cache mm?
|
||||||
|
bool has_unread = false;
|
||||||
|
if (const auto* mm = _rmm.get(c); mm != nullptr) {
|
||||||
|
if (const auto* unread_storage = mm->storage<Message::Components::TagUnread>(); unread_storage != nullptr && !unread_storage->empty()) {
|
||||||
|
has_unread = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderContactBig(_theme, _contact_tc, {_cr, c}, 2, has_unread, true, selected)) {
|
||||||
_selected_contact = c;
|
_selected_contact = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1077,121 +1110,6 @@ void ChatGui4::renderContactList(void) {
|
|||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatGui4::renderContactListContactBig(const Contact3 c, const bool selected) {
|
|
||||||
// TODO:
|
|
||||||
// - unread message
|
|
||||||
// - avatar img
|
|
||||||
// - connection status
|
|
||||||
// - user status
|
|
||||||
// - status message
|
|
||||||
// - context menu n shit?
|
|
||||||
|
|
||||||
// +------+
|
|
||||||
// | | *Name (Alias?)
|
|
||||||
// |Avatar| Satus Message
|
|
||||||
// | | user status (online/away/busy)-direct/relayed / offline
|
|
||||||
// +------+
|
|
||||||
|
|
||||||
auto label = "###" + std::to_string(entt::to_integral(c));
|
|
||||||
|
|
||||||
const bool request_incoming = _cr.all_of<Contact::Components::RequestIncoming>(c);
|
|
||||||
const bool request_outgoing = _cr.all_of<Contact::Components::TagRequestOutgoing>(c);
|
|
||||||
|
|
||||||
ImVec2 orig_curser_pos = ImGui::GetCursorPos();
|
|
||||||
// HACK: fake selected to make it draw a box for us
|
|
||||||
const bool show_selected = request_incoming || request_outgoing || selected;
|
|
||||||
if (request_incoming) {
|
|
||||||
// TODO: theming
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Header, {0.98f, 0.41f, 0.26f, 0.52f});
|
|
||||||
} else if (request_outgoing) {
|
|
||||||
// TODO: theming
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Header, {0.98f, 0.26f, 0.41f, 0.52f});
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool got_selected = ImGui::Selectable(label.c_str(), show_selected, 0, {0,3*TEXT_BASE_HEIGHT});
|
|
||||||
|
|
||||||
if (request_incoming || request_outgoing) {
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
}
|
|
||||||
ImVec2 post_curser_pos = ImGui::GetCursorPos();
|
|
||||||
|
|
||||||
ImVec2 img_curser {
|
|
||||||
orig_curser_pos.x + ImGui::GetStyle().FramePadding.x,
|
|
||||||
orig_curser_pos.y + ImGui::GetStyle().FramePadding.y
|
|
||||||
};
|
|
||||||
|
|
||||||
float img_y {
|
|
||||||
//(post_curser_pos.y - orig_curser_pos.y) - ImGui::GetStyle().FramePadding.y*2
|
|
||||||
TEXT_BASE_HEIGHT*3 - ImGui::GetStyle().FramePadding.y*2
|
|
||||||
};
|
|
||||||
|
|
||||||
ImGui::SetCursorPos(img_curser);
|
|
||||||
const ImVec4 color_online_direct{0.3, 1, 0, 1};
|
|
||||||
const ImVec4 color_online_cloud{0, 1, 0.8, 1};
|
|
||||||
const ImVec4 color_offline{0.4, 0.4, 0.4, 1};
|
|
||||||
|
|
||||||
ImVec4 color_current = color_offline;
|
|
||||||
if (_cr.all_of<Contact::Components::ConnectionState>(c)) {
|
|
||||||
const auto c_state = _cr.get<Contact::Components::ConnectionState>(c).state;
|
|
||||||
if (c_state == Contact::Components::ConnectionState::State::direct) {
|
|
||||||
color_current = color_online_direct;
|
|
||||||
} else if (c_state == Contact::Components::ConnectionState::State::cloud) {
|
|
||||||
color_current = color_online_cloud;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// avatar
|
|
||||||
const auto [id, width, height] = _contact_tc.get(c);
|
|
||||||
ImGui::Image(
|
|
||||||
id,
|
|
||||||
ImVec2{img_y, img_y},
|
|
||||||
{0, 0},
|
|
||||||
{1, 1},
|
|
||||||
{1, 1, 1, 1},
|
|
||||||
color_current
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: move this out of chat gui
|
|
||||||
any_unread = false;
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
{
|
|
||||||
// TODO: is there a better way?
|
|
||||||
// maybe cache mm?
|
|
||||||
bool has_unread = false;
|
|
||||||
if (const auto* mm = _rmm.get(c); mm != nullptr) {
|
|
||||||
if (const auto* unread_storage = mm->storage<Message::Components::TagUnread>(); unread_storage != nullptr && !unread_storage->empty()) {
|
|
||||||
#if 0
|
|
||||||
assert(unread_storage.size() == 0);
|
|
||||||
assert(unread_storage.cbegin() == unread_storage.cend());
|
|
||||||
std::cout << "UNREAD ";
|
|
||||||
for (const auto e : mm->view<Message::Components::TagUnread>()) {
|
|
||||||
std::cout << entt::to_integral(e) << " ";
|
|
||||||
}
|
|
||||||
std::cout << "\n";
|
|
||||||
#endif
|
|
||||||
has_unread = true;
|
|
||||||
any_unread = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("%s%s", has_unread?"* ":"", (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name.c_str() : "<unk>"));
|
|
||||||
if (request_incoming) {
|
|
||||||
ImGui::TextUnformatted("Incoming request/invite");
|
|
||||||
} else if (request_outgoing) {
|
|
||||||
ImGui::TextUnformatted("Outgoing request/invite");
|
|
||||||
}
|
|
||||||
//ImGui::Text("status message...");
|
|
||||||
//ImGui::TextDisabled("hi");
|
|
||||||
//ImGui::RenderTextEllipsis
|
|
||||||
}
|
|
||||||
ImGui::EndGroup();
|
|
||||||
|
|
||||||
ImGui::SetCursorPos(post_curser_pos);
|
|
||||||
return got_selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ChatGui4::renderContactListContactSmall(const Contact3 c, const bool selected) const {
|
bool ChatGui4::renderContactListContactSmall(const Contact3 c, const bool selected) const {
|
||||||
std::string label;
|
std::string label;
|
||||||
|
|
||||||
@ -1202,6 +1120,7 @@ bool ChatGui4::renderContactListContactSmall(const Contact3 c, const bool select
|
|||||||
return ImGui::Selectable(label.c_str(), selected);
|
return ImGui::Selectable(label.c_str(), selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
bool ChatGui4::renderSubContactListContact(const Contact3 c, const bool selected) const {
|
bool ChatGui4::renderSubContactListContact(const Contact3 c, const bool selected) const {
|
||||||
std::string label;
|
std::string label;
|
||||||
|
|
||||||
@ -1224,6 +1143,7 @@ bool ChatGui4::renderSubContactListContact(const Contact3 c, const bool selected
|
|||||||
|
|
||||||
return ImGui::Selectable(label.c_str(), selected);
|
return ImGui::Selectable(label.c_str(), selected);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ChatGui4::pasteFile(const char* mime_type) {
|
void ChatGui4::pasteFile(const char* mime_type) {
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
#include <solanaceae/message3/registry_message_model.hpp>
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
#include <solanaceae/util/config_model.hpp>
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
|
||||||
|
#include "./chat_gui/theme.hpp"
|
||||||
|
|
||||||
#include "./texture_uploader.hpp"
|
#include "./texture_uploader.hpp"
|
||||||
#include "./texture_cache.hpp"
|
#include "./texture_cache.hpp"
|
||||||
#include "./tox_avatar_loader.hpp"
|
#include "./tox_avatar_loader.hpp"
|
||||||
#include "./message_image_loader.hpp"
|
#include "./message_image_loader.hpp"
|
||||||
#include "./file_selector.hpp"
|
#include "./chat_gui/file_selector.hpp"
|
||||||
#include "./send_image_popup.hpp"
|
#include "./chat_gui/send_image_popup.hpp"
|
||||||
|
|
||||||
#include <entt/container/dense_map.hpp>
|
#include <entt/container/dense_map.hpp>
|
||||||
|
|
||||||
@ -29,6 +31,8 @@ class ChatGui4 {
|
|||||||
ContactTextureCache& _contact_tc;
|
ContactTextureCache& _contact_tc;
|
||||||
MessageTextureCache& _msg_tc;
|
MessageTextureCache& _msg_tc;
|
||||||
|
|
||||||
|
Theme& _theme;
|
||||||
|
|
||||||
FileSelector _fss;
|
FileSelector _fss;
|
||||||
SendImagePopup _sip;
|
SendImagePopup _sip;
|
||||||
|
|
||||||
@ -57,7 +61,8 @@ class ChatGui4 {
|
|||||||
Contact3Registry& cr,
|
Contact3Registry& cr,
|
||||||
TextureUploaderI& tu,
|
TextureUploaderI& tu,
|
||||||
ContactTextureCache& contact_tc,
|
ContactTextureCache& contact_tc,
|
||||||
MessageTextureCache& msg_tc
|
MessageTextureCache& msg_tc,
|
||||||
|
Theme& theme
|
||||||
);
|
);
|
||||||
~ChatGui4(void);
|
~ChatGui4(void);
|
||||||
|
|
||||||
@ -65,8 +70,6 @@ class ChatGui4 {
|
|||||||
float render(float time_delta);
|
float render(float time_delta);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool any_unread {false};
|
|
||||||
|
|
||||||
void sendFilePath(const char* file_path);
|
void sendFilePath(const char* file_path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -75,9 +78,8 @@ class ChatGui4 {
|
|||||||
void renderMessageExtra(Message3Registry& reg, const Message3 e);
|
void renderMessageExtra(Message3Registry& reg, const Message3 e);
|
||||||
|
|
||||||
void renderContactList(void);
|
void renderContactList(void);
|
||||||
bool renderContactListContactBig(const Contact3 c, const bool selected);
|
|
||||||
bool renderContactListContactSmall(const Contact3 c, const bool selected) const;
|
bool renderContactListContactSmall(const Contact3 c, const bool selected) const;
|
||||||
bool renderSubContactListContact(const Contact3 c, const bool selected) const;
|
//bool renderSubContactListContact(const Contact3 c, const bool selected) const;
|
||||||
|
|
||||||
void pasteFile(const char* mime_type);
|
void pasteFile(const char* mime_type);
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <imgui/backends/imgui_impl_sdlrenderer3.h>
|
#include <imgui/backends/imgui_impl_sdlrenderer3.h>
|
||||||
|
|
||||||
#include "./theme.hpp"
|
#include "./theme.hpp"
|
||||||
|
#include "./chat_gui/theme.hpp"
|
||||||
|
|
||||||
#include "./start_screen.hpp"
|
#include "./start_screen.hpp"
|
||||||
|
|
||||||
@ -58,11 +59,14 @@ int main(int argc, char** argv) {
|
|||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
|
||||||
|
Theme theme;
|
||||||
if (SDL_GetSystemTheme() == SDL_SYSTEM_THEME_LIGHT) {
|
if (SDL_GetSystemTheme() == SDL_SYSTEM_THEME_LIGHT) {
|
||||||
ImGui::StyleColorsLight();
|
ImGui::StyleColorsLight();
|
||||||
|
theme = getDefaultThemeLight();
|
||||||
} else {
|
} else {
|
||||||
//ImGui::StyleColorsDark();
|
//ImGui::StyleColorsDark();
|
||||||
setThemeGreen();
|
setThemeGreen();
|
||||||
|
theme = getDefaultThemeDark();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -85,7 +89,7 @@ int main(int argc, char** argv) {
|
|||||||
ImGui_ImplSDL3_InitForSDLRenderer(window.get(), renderer.get());
|
ImGui_ImplSDL3_InitForSDLRenderer(window.get(), renderer.get());
|
||||||
ImGui_ImplSDLRenderer3_Init(renderer.get());
|
ImGui_ImplSDLRenderer3_Init(renderer.get());
|
||||||
|
|
||||||
std::unique_ptr<Screen> screen = std::make_unique<StartScreen>(renderer.get());
|
std::unique_ptr<Screen> screen = std::make_unique<StartScreen>(renderer.get(), theme);
|
||||||
|
|
||||||
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::vector<std::string> plugins) :
|
MainScreen::MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) :
|
||||||
renderer(renderer_),
|
renderer(renderer_),
|
||||||
rmm(cr),
|
rmm(cr),
|
||||||
msnj{cr, {}, {}},
|
msnj{cr, {}, {}},
|
||||||
@ -24,6 +24,7 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::stri
|
|||||||
tmm(rmm, cr, tcm, tc, tc),
|
tmm(rmm, cr, tcm, tc, tc),
|
||||||
ttm(rmm, cr, tcm, tc, tc),
|
ttm(rmm, cr, tcm, tc, tc),
|
||||||
tffom(cr, rmm, tcm, tc, tc),
|
tffom(cr, rmm, tcm, tc, tc),
|
||||||
|
theme(theme_),
|
||||||
mmil(rmm),
|
mmil(rmm),
|
||||||
tam(rmm, cr, conf),
|
tam(rmm, cr, conf),
|
||||||
sdlrtu(renderer_),
|
sdlrtu(renderer_),
|
||||||
@ -31,7 +32,7 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::stri
|
|||||||
contact_tc(tal, sdlrtu),
|
contact_tc(tal, sdlrtu),
|
||||||
mil(),
|
mil(),
|
||||||
msg_tc(mil, sdlrtu),
|
msg_tc(mil, sdlrtu),
|
||||||
cg(conf, rmm, cr, sdlrtu, contact_tc, msg_tc),
|
cg(conf, rmm, cr, sdlrtu, contact_tc, msg_tc, theme),
|
||||||
sw(conf),
|
sw(conf),
|
||||||
tuiu(tc, conf),
|
tuiu(tc, conf),
|
||||||
tdch(tpi)
|
tdch(tpi)
|
||||||
@ -44,9 +45,10 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::stri
|
|||||||
conf.set("tox", "save_file_path", save_path);
|
conf.set("tox", "save_file_path", save_path);
|
||||||
|
|
||||||
{ // name stuff
|
{ // name stuff
|
||||||
|
// a new profile will not have this set
|
||||||
auto name = tc.toxSelfGetName();
|
auto name = tc.toxSelfGetName();
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
name = "tomato";
|
name = new_username;
|
||||||
}
|
}
|
||||||
conf.set("tox", "name", name);
|
conf.set("tox", "name", name);
|
||||||
tc.setSelfName(name); // TODO: this is ugly
|
tc.setSelfName(name); // TODO: this is ugly
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "./message_image_loader.hpp"
|
#include "./message_image_loader.hpp"
|
||||||
|
|
||||||
#include "./chat_gui4.hpp"
|
#include "./chat_gui4.hpp"
|
||||||
#include "./settings_window.hpp"
|
#include "./chat_gui/settings_window.hpp"
|
||||||
#include "./tox_ui_utils.hpp"
|
#include "./tox_ui_utils.hpp"
|
||||||
#include "./tox_dht_cap_histo.hpp"
|
#include "./tox_dht_cap_histo.hpp"
|
||||||
#include "./tox_friend_faux_offline_messaging.hpp"
|
#include "./tox_friend_faux_offline_messaging.hpp"
|
||||||
@ -62,6 +62,8 @@ struct MainScreen final : public Screen {
|
|||||||
ToxTransferManager ttm;
|
ToxTransferManager ttm;
|
||||||
ToxFriendFauxOfflineMessaging tffom;
|
ToxFriendFauxOfflineMessaging tffom;
|
||||||
|
|
||||||
|
Theme& theme;
|
||||||
|
|
||||||
MediaMetaInfoLoader mmil;
|
MediaMetaInfoLoader mmil;
|
||||||
ToxAvatarManager tam;
|
ToxAvatarManager tam;
|
||||||
|
|
||||||
@ -89,7 +91,7 @@ struct MainScreen final : public Screen {
|
|||||||
uint64_t _window_hidden_ts {0};
|
uint64_t _window_hidden_ts {0};
|
||||||
float _time_since_event {0.f};
|
float _time_since_event {0.f};
|
||||||
|
|
||||||
MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::vector<std::string> plugins);
|
MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins);
|
||||||
~MainScreen(void);
|
~MainScreen(void);
|
||||||
|
|
||||||
bool handleEvent(SDL_Event& e) override;
|
bool handleEvent(SDL_Event& e) override;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include "./image_loader_webp.hpp"
|
#include "./image_loader_webp.hpp"
|
||||||
#include "./image_loader_sdl_bmp.hpp"
|
#include "./image_loader_sdl_bmp.hpp"
|
||||||
#include "./image_loader_qoi.hpp"
|
#include "./image_loader_qoi.hpp"
|
||||||
#include "./image_loader_stb.hpp"
|
|
||||||
#include "./image_loader_sdl_image.hpp"
|
#include "./image_loader_sdl_image.hpp"
|
||||||
|
|
||||||
#include <solanaceae/message3/components.hpp>
|
#include <solanaceae/message3/components.hpp>
|
||||||
@ -81,7 +80,6 @@ MediaMetaInfoLoader::MediaMetaInfoLoader(RegistryMessageModel& rmm) : _rmm(rmm)
|
|||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSTB>());
|
|
||||||
|
|
||||||
_rmm.subscribe(this, RegistryMessageModel_Event::message_construct);
|
_rmm.subscribe(this, RegistryMessageModel_Event::message_construct);
|
||||||
_rmm.subscribe(this, RegistryMessageModel_Event::message_updated);
|
_rmm.subscribe(this, RegistryMessageModel_Event::message_updated);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "./image_loader_sdl_bmp.hpp"
|
#include "./image_loader_sdl_bmp.hpp"
|
||||||
#include "./image_loader_qoi.hpp"
|
#include "./image_loader_qoi.hpp"
|
||||||
#include "./image_loader_stb.hpp"
|
|
||||||
#include "./image_loader_webp.hpp"
|
#include "./image_loader_webp.hpp"
|
||||||
#include "./image_loader_sdl_image.hpp"
|
#include "./image_loader_sdl_image.hpp"
|
||||||
#include "./media_meta_info_loader.hpp"
|
#include "./media_meta_info_loader.hpp"
|
||||||
@ -24,7 +23,6 @@ MessageImageLoader::MessageImageLoader(void) {
|
|||||||
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSTB>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) {
|
std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) {
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
#include <imgui/misc/cpp/imgui_stdlib.h>
|
#include <imgui/misc/cpp/imgui_stdlib.h>
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
StartScreen::StartScreen(SDL_Renderer* renderer) : _renderer(renderer) {
|
StartScreen::StartScreen(SDL_Renderer* renderer, Theme& theme) : _renderer(renderer), _theme(theme) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen* StartScreen::render(float, bool&) {
|
Screen* StartScreen::render(float, bool&) {
|
||||||
@ -33,13 +34,13 @@ Screen* StartScreen::render(float, bool&) {
|
|||||||
_fss.requestFile(
|
_fss.requestFile(
|
||||||
[](const auto& path) -> bool { return std::filesystem::is_regular_file(path); },
|
[](const auto& path) -> bool { return std::filesystem::is_regular_file(path); },
|
||||||
[this](const auto& path) {
|
[this](const auto& path) {
|
||||||
tox_profile_path = path.string();
|
_tox_profile_path = path.string();
|
||||||
},
|
},
|
||||||
[](){}
|
[](){}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::TextUnformatted(tox_profile_path.c_str());
|
ImGui::TextUnformatted(_tox_profile_path.c_str());
|
||||||
|
|
||||||
ImGui::TextUnformatted("password:");
|
ImGui::TextUnformatted("password:");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
@ -56,8 +57,22 @@ Screen* StartScreen::render(float, bool&) {
|
|||||||
if (ImGui::BeginTabItem("create profile")) {
|
if (ImGui::BeginTabItem("create profile")) {
|
||||||
_new_save = true;
|
_new_save = true;
|
||||||
|
|
||||||
ImGui::TextUnformatted("TODO: profile path");
|
ImGui::TextUnformatted("username:");
|
||||||
ImGui::TextUnformatted("TODO: profile name");
|
ImGui::SameLine();
|
||||||
|
if (ImGui::InputText("##user_name", &_user_name)) {
|
||||||
|
std::string tmp_copy = _user_name;
|
||||||
|
for (auto& c : tmp_copy) {
|
||||||
|
if (!std::isalnum(static_cast<unsigned char>(c)) && c != '-' && c != '.') {
|
||||||
|
c = '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp_copy.empty()) {
|
||||||
|
tmp_copy = "unnamed-tomato";
|
||||||
|
}
|
||||||
|
|
||||||
|
_tox_profile_path = tmp_copy + ".tox";
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::TextUnformatted("password:");
|
ImGui::TextUnformatted("password:");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
@ -69,6 +84,8 @@ Screen* StartScreen::render(float, bool&) {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Checkbox("show password", &_show_password);
|
ImGui::Checkbox("show password", &_show_password);
|
||||||
|
|
||||||
|
ImGui::TextUnformatted("TODO: profile path (current path for now)");
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("plugins")) {
|
if (ImGui::BeginTabItem("plugins")) {
|
||||||
@ -81,7 +98,6 @@ Screen* StartScreen::render(float, bool&) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::TextUnformatted(it->c_str());
|
ImGui::TextUnformatted(it->c_str());
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
@ -105,7 +121,7 @@ Screen* StartScreen::render(float, bool&) {
|
|||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (!_new_save && !std::filesystem::is_regular_file(tox_profile_path)) {
|
if (!_new_save && !std::filesystem::is_regular_file(_tox_profile_path)) {
|
||||||
// load but file missing
|
// load but file missing
|
||||||
|
|
||||||
ImGui::BeginDisabled();
|
ImGui::BeginDisabled();
|
||||||
@ -115,7 +131,7 @@ Screen* StartScreen::render(float, bool&) {
|
|||||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||||
ImGui::SetTooltip("file does not exist");
|
ImGui::SetTooltip("file does not exist");
|
||||||
}
|
}
|
||||||
} else if (_new_save && std::filesystem::exists(tox_profile_path)) {
|
} else if (_new_save && std::filesystem::exists(_tox_profile_path)) {
|
||||||
// new but file exists
|
// new but file exists
|
||||||
|
|
||||||
ImGui::BeginDisabled();
|
ImGui::BeginDisabled();
|
||||||
@ -127,7 +143,7 @@ Screen* StartScreen::render(float, bool&) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ImGui::Button("load", {60, 25})) {
|
if (ImGui::Button("load", {60, 25})) {
|
||||||
auto new_screen = std::make_unique<MainScreen>(_renderer, tox_profile_path, _password, queued_plugin_paths);
|
auto new_screen = std::make_unique<MainScreen>(_renderer, _theme, _tox_profile_path, _password, _user_name, queued_plugin_paths);
|
||||||
return new_screen.release();
|
return new_screen.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#include "./screen.hpp"
|
#include "./screen.hpp"
|
||||||
|
|
||||||
#include "./file_selector.hpp"
|
#include "./chat_gui/theme.hpp"
|
||||||
|
#include "./chat_gui/file_selector.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -14,18 +15,20 @@ extern "C" {
|
|||||||
|
|
||||||
struct StartScreen final : public Screen {
|
struct StartScreen final : public Screen {
|
||||||
SDL_Renderer* _renderer;
|
SDL_Renderer* _renderer;
|
||||||
|
Theme& _theme;
|
||||||
FileSelector _fss;
|
FileSelector _fss;
|
||||||
|
|
||||||
bool _new_save {false};
|
bool _new_save {false};
|
||||||
|
std::string _user_name {"unnamed-tomato"};
|
||||||
|
|
||||||
bool _show_password {false};
|
bool _show_password {false};
|
||||||
std::string _password;
|
std::string _password;
|
||||||
|
|
||||||
std::string tox_profile_path {"tomato.tox"};
|
std::string _tox_profile_path {"unnamed-tomato.tox"};
|
||||||
std::vector<std::string> queued_plugin_paths;
|
std::vector<std::string> queued_plugin_paths;
|
||||||
|
|
||||||
StartScreen(void) = delete;
|
StartScreen(void) = delete;
|
||||||
StartScreen(SDL_Renderer* renderer);
|
StartScreen(SDL_Renderer* renderer, Theme& theme);
|
||||||
~StartScreen(void) = default;
|
~StartScreen(void) = default;
|
||||||
|
|
||||||
// return nullptr if not next
|
// return nullptr if not next
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "./image_loader_sdl_bmp.hpp"
|
#include "./image_loader_sdl_bmp.hpp"
|
||||||
#include "./image_loader_qoi.hpp"
|
#include "./image_loader_qoi.hpp"
|
||||||
#include "./image_loader_stb.hpp"
|
|
||||||
#include "./image_loader_webp.hpp"
|
#include "./image_loader_webp.hpp"
|
||||||
#include "./image_loader_sdl_image.hpp"
|
#include "./image_loader_sdl_image.hpp"
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) {
|
|||||||
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLImage>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSTB>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static float getHue_6bytes(const uint8_t* data) {
|
static float getHue_6bytes(const uint8_t* data) {
|
||||||
@ -189,7 +187,8 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
|||||||
if (!_cr.any_of<
|
if (!_cr.any_of<
|
||||||
Contact::Components::ToxFriendPersistent,
|
Contact::Components::ToxFriendPersistent,
|
||||||
Contact::Components::ToxGroupPersistent,
|
Contact::Components::ToxGroupPersistent,
|
||||||
Contact::Components::ToxGroupPeerPersistent
|
Contact::Components::ToxGroupPeerPersistent,
|
||||||
|
Contact::Components::ID
|
||||||
>(c)) {
|
>(c)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@ -201,6 +200,12 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
|||||||
pixels = generateToxIdenticon(_cr.get<Contact::Components::ToxGroupPersistent>(c).chat_id);
|
pixels = generateToxIdenticon(_cr.get<Contact::Components::ToxGroupPersistent>(c).chat_id);
|
||||||
} else if (_cr.all_of<Contact::Components::ToxGroupPeerPersistent>(c)) {
|
} else if (_cr.all_of<Contact::Components::ToxGroupPeerPersistent>(c)) {
|
||||||
pixels = generateToxIdenticon(_cr.get<Contact::Components::ToxGroupPeerPersistent>(c).peer_key);
|
pixels = generateToxIdenticon(_cr.get<Contact::Components::ToxGroupPeerPersistent>(c).peer_key);
|
||||||
|
} else if (_cr.all_of<Contact::Components::ID>(c)) {
|
||||||
|
// TODO: should we really use toxidenticons for other protocols?
|
||||||
|
// (this is required for self)
|
||||||
|
auto id_copy = _cr.get<Contact::Components::ID>(c).data;
|
||||||
|
id_copy.resize(32);
|
||||||
|
pixels = generateToxIdenticon(id_copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureEntry new_entry;
|
TextureEntry new_entry;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// meh, change this
|
// meh, change this
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <toxencryptsave/toxencryptsave.h>
|
#include <tox/toxencryptsave.h>
|
||||||
|
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
|
||||||
|
@ -107,6 +107,12 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM
|
|||||||
|
|
||||||
const uint64_t ts_now = Message::getTimeMS();
|
const uint64_t ts_now = Message::getTimeMS();
|
||||||
|
|
||||||
|
if (!_cr.all_of<Contact::Components::Self>(c)) {
|
||||||
|
return dfmc_Ret::NO_MSG; // error
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto self_c = _cr.get<Contact::Components::Self>(c).self;
|
||||||
|
|
||||||
// filter for unconfirmed messages
|
// filter for unconfirmed messages
|
||||||
|
|
||||||
// we assume sorted
|
// we assume sorted
|
||||||
@ -127,9 +133,8 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM
|
|||||||
continue; // skip
|
continue; // skip
|
||||||
}
|
}
|
||||||
|
|
||||||
// exclude
|
if (!mr->any_of<
|
||||||
if (mr->any_of<
|
Message::Components::ReceivedBy
|
||||||
Message::Components::Remote::TimestampReceived // this acts like a tag, which is wrong in groups
|
|
||||||
>(msg)
|
>(msg)
|
||||||
) {
|
) {
|
||||||
continue; // skip
|
continue; // skip
|
||||||
@ -139,6 +144,16 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM
|
|||||||
continue; // not outbound (in private)
|
continue; // not outbound (in private)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& ts_received = mr->get<Message::Components::ReceivedBy>(msg).ts;
|
||||||
|
// not target
|
||||||
|
if (ts_received.contains(c)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// needs to contain self
|
||||||
|
if (!ts_received.contains(self_c)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
valid_unsent = true;
|
valid_unsent = true;
|
||||||
|
|
||||||
uint64_t msg_ts = msg_view.get<Message::Components::Timestamp>(msg).ts;
|
uint64_t msg_ts = msg_view.get<Message::Components::Timestamp>(msg).ts;
|
||||||
|
Reference in New Issue
Block a user