aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore19
-rw-r--r--ChangeLog (renamed from CHANGES.md)4
-rw-r--r--Makefile102
-rw-r--r--README.md20
-rw-r--r--contrib/distribute_version.sh4
-rw-r--r--contrib/get_version.sh18
-rw-r--r--meson.build52
-rw-r--r--src/.gitignore14
-rw-r--r--src/application.c58
-rw-r--r--src/application.h3
-rw-r--r--src/chat.c22
-rw-r--r--src/chat.h3
-rw-r--r--src/meson.build28
-rw-r--r--src/ui/account_create_dialog.c4
-rw-r--r--src/ui/accounts.h3
-rw-r--r--src/ui/chat_open_dialog.c4
-rw-r--r--src/ui/chats.c22
-rw-r--r--src/ui/chats.h3
-rw-r--r--src/ui/lobby_create_dialog.h3
-rw-r--r--src/ui/lobby_enter_dialog.c4
-rw-r--r--src/ui/members.h3
-rw-r--r--src/ui/meson.build33
-rw-r--r--src/ui/messages.c177
-rw-r--r--src/ui/messages.h5
-rw-r--r--src/util.c18
-rw-r--r--src/util.h13
26 files changed, 410 insertions, 229 deletions
diff --git a/.gitignore b/.gitignore
index 363d75a..8f8cabf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,26 @@
1.version
2
3aclocal.m4
4autom4te.cache/
5build-aux/
6
7config.log
8config.status
9configure
10configure~
11
12libtool
13m4/
14
15Makefile.in
16Makefile
17
1# IDE specific files: 18# IDE specific files:
2.cproject 19.cproject
3.project 20.project
4.settings/ 21.settings/
22.cache/
23.vscode/
5 24
6# Binary files: 25# Binary files:
7*.o 26*.o
diff --git a/CHANGES.md b/ChangeLog
index d800b24..ef9fb5e 100644
--- a/CHANGES.md
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1## Version 0.1.1
2* Replaces build system finally with Meson increasing platform support
3* Fixes issues regarding changes in header usage from GNUnet 0.19.0
4
1## Version 0.1.0 5## Version 0.1.0
2* It is possible to create direct chats and group chats via lobbies, shared keys or invitations 6* It is possible to create direct chats and group chats via lobbies, shared keys or invitations
3* Members of a chats can be observed 7* Members of a chats can be observed
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 66bb7e2..0000000
--- a/Makefile
+++ /dev/null
@@ -1,102 +0,0 @@
1
2VERSION = 0.1.0
3TARGET_NAME = messenger-cli
4
5SOURCE_DIR = src/
6INSTALL_DIR ?= /usr/local/
7
8PACKAGE = $(TARGET_NAME)
9BINARY = $(TARGET_NAME)
10SOURCES = messenger_cli.c\
11 application.c\
12 chat.c\
13 util.c\
14 ui/account_create_dialog.c\
15 ui/accounts.c\
16 ui/chat_open_dialog.c\
17 ui/chats.c\
18 ui/lobby_create_dialog.c\
19 ui/lobby_enter_dialog.c\
20 ui/members.c\
21 ui/messages.c
22HEADERS = application.h\
23 chat.h\
24 util.h\
25 ui/account_create_dialog.h\
26 ui/accounts.h\
27 ui/chat.h\
28 ui/chat_open_dialog.h\
29 ui/chats.h\
30 ui/list_input.h\
31 ui/lobby_create_dialog.h\
32 ui/lobby_enter_dialog.h\
33 ui/members.h\
34 ui/messages.h\
35 ui/text_input.h
36
37LIBRARIES = gnunetchat gnunetutil ncurses
38
39DIST_FILES = Makefile\
40 AUTHORS\
41 CHANGES.md\
42 COPYING\
43 README.md
44
45GNU_CC ?= gcc
46GNU_LD ?= gcc
47GNU_RM ?= rm
48GNU_CP ?= cp
49GNU_TAR ?= tar
50
51CFLAGS += -pedantic -Wall -Wextra -ggdb3 -Wno-overlength-strings
52LDFLAGS +=
53
54DEBUGFLAGS = -O0 -D _DEBUG
55RELEASEFLAGS = -O2 -D NDEBUG
56
57DIST_DIR = $(PACKAGE)-$(VERSION)/
58DIST_TAR = $(PACKAGE)-$(VERSION).tar.gz
59
60SOURCE_FILES = $(addprefix $(SOURCE_DIR), $(SOURCES))
61OBJECT_FILES = $(SOURCE_FILES:%.c=%.o)
62HEADER_FILES = $(addprefix $(SOURCE_DIR), $(HEADERS))
63LIBRARY_FLAGS = $(addprefix -l, $(LIBRARIES))
64
65all: $(BINARY)
66
67debug: CFLAGS += $(DEBUGFLAGS)
68debug: $(BINARY)
69
70release: CFLAGS += $(RELEASEFLAGS)
71release: $(BINARY)
72
73%.o: %.c
74 $(GNU_CC) $(CFLAGS) -c $< -o $@
75
76$(BINARY): $(OBJECT_FILES)
77 $(GNU_LD) $(LDFLAGS) $^ -o $@ $(LIBRARY_FLAGS)
78
79.PHONY: install
80
81install:
82 install -m 755 $(BINARY) $(addprefix $(INSTALL_DIR), bin/)
83
84.PHONY: uninstall
85
86uninstall:
87 $(GNU_RM) -f $(addsuffix $(BINARY), $(addprefix $(INSTALL_DIR), bin/))
88
89.PHONY: dist
90
91dist: clean
92 mkdir $(DIST_DIR)
93 $(GNU_CP) -r $(SOURCE_DIR) $(DIST_DIR)
94 $(foreach DIST_FILE,$(DIST_FILES),$(GNU_CP) $(DIST_FILE) $(addprefix $(DIST_DIR), $(DIST_FILE));)
95 $(GNU_TAR) -czf $(DIST_TAR) $(DIST_DIR)
96 $(GNU_RM) -r $(DIST_DIR)
97
98.PHONY: clean
99
100clean:
101 $(GNU_RM) -f $(BINARY)
102 $(GNU_RM) -f $(OBJECT_FILES)
diff --git a/README.md b/README.md
index 37d95e4..4a5bf35 100644
--- a/README.md
+++ b/README.md
@@ -24,13 +24,21 @@ The following dependencies are required and need to be installed to build the ap
24 - [libgnunetchat](https://git.gnunet.org/libgnunetchat.git/): For chatting via GNUnet messenger 24 - [libgnunetchat](https://git.gnunet.org/libgnunetchat.git/): For chatting via GNUnet messenger
25 - [ncurses](https://www.gnu.org/software/ncurses/): For the general UI visualization 25 - [ncurses](https://www.gnu.org/software/ncurses/): For the general UI visualization
26 26
27Then you can simply use the provided Makefile as follows: 27Then you can simply use [Meson](https://mesonbuild.com/) as follows:
28```
29meson build # Configure the build files for your system
30ninja -C build # Build the application using those build files
31ninja -C build install # Install the application
32```
33
34Here is a list of some useful build commands using Meson and [Ninja](https://ninja-build.org/):
35
36 - `meson compile -C build` to just compile everything with configured parameters
37 - `rm -r build` to cleanup build files in case you want to recompile
38 - `meson install -C build` to install the compiled files (you might need sudo permissions to install)
39 - `meson dist -C build` to create a tar file for distribution
28 40
29 - `make` to just compile everything with default parameters 41If you want to change the installation location, use the `--prefix=` parameter in the initial meson command. Also you can enable optimized release builds by adding `--buildtype=release` as parameter.
30 - `make clean` to cleanup build files in case you want to recompile
31 - `make debug` to compile everything with debug parameters
32 - `make release` to compile everything with build optimizations enabled
33 - `make install` to install the compiled files (you might need sudo permissions to install)
34 42
35## Contribution 43## Contribution
36 44
diff --git a/contrib/distribute_version.sh b/contrib/distribute_version.sh
new file mode 100644
index 0000000..110d311
--- /dev/null
+++ b/contrib/distribute_version.sh
@@ -0,0 +1,4 @@
1#!/bin/sh
2VERSION=$1
3cd "${MESON_DIST_ROOT}"
4echo $VERSION > .version \ No newline at end of file
diff --git a/contrib/get_version.sh b/contrib/get_version.sh
new file mode 100644
index 0000000..2a41ed4
--- /dev/null
+++ b/contrib/get_version.sh
@@ -0,0 +1,18 @@
1#!/bin/sh
2# Gets the version number from git, or from the contents of .version
3VERSION=
4if test -f ".version"
5then
6 VERSION=$(cat .version)
7fi
8if test -d "./.git"
9then
10 VERSION=$(git describe --tags)
11 VERSION=${VERSION#v}
12 echo $VERSION > .version
13fi
14if test "x$VERSION" = "x"
15then
16 VERSION="unknown"
17fi
18echo "$VERSION"
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..d46f2f9
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,52 @@
1#
2# This file is part of GNUnet.
3# Copyright (C) 2023--2024 GNUnet e.V.
4#
5# GNUnet is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Affero General Public License as published
7# by the Free Software Foundation, either version 3 of the License,
8# or (at your option) any later version.
9#
10# GNUnet is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17#
18# SPDX-License-Identifier: AGPL3.0-or-later
19#
20
21project(
22 'messenger-cli',
23 'c',
24 license: 'AGPL3.0-or-later',
25 version: run_command('contrib/get_version.sh').stdout().strip(),
26)
27
28meson.add_dist_script('contrib/distribute_version.sh', meson.project_version())
29
30src_directory = include_directories('src')
31
32messenger_cli_deps = [
33 dependency('gnunetchat'),
34 dependency('gnunetutil'),
35 dependency('ncurses'),
36]
37
38messenger_cli_args = [
39 '-DMESSENGER_CLI_BINARY="@0@"'.format(meson.project_name()),
40 '-DMESSENGER_CLI_VERSION="@0@"'.format(meson.project_version()),
41]
42
43subdir('src')
44
45messenger_cli_exec = executable(
46 'messenger-cli',
47 messenger_cli_sources,
48 c_args: messenger_cli_args,
49 install: true,
50 dependencies: messenger_cli_deps,
51 include_directories: src_directory,
52)
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..937a67b
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1,14 @@
1.deps/
2.libs/
3
4Makefile.in
5Makefile
6
7stamp-h1
8
9messenger_cli_config.h
10messenger_cli_config.h.in
11messenger_cli_config.h.in~
12
13*.o
14*.a
diff --git a/src/application.c b/src/application.c
index d8314df..1b2bdbd 100644
--- a/src/application.c
+++ b/src/application.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2024 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -24,6 +24,20 @@
24 24
25#include "application.h" 25#include "application.h"
26 26
27#include "util.h"
28
29#ifndef MESSENGER_CLI_BINARY
30#define MESSENGER_CLI_BINARY "messenger_cli"
31#endif
32
33#ifndef MESSENGER_CLI_VERSION
34#define MESSENGER_CLI_VERSION "unknown"
35#endif
36
37#ifndef MESSENGER_CLI_DESC
38#define MESSENGER_CLI_DESC "A CLI for the Messenger service of GNUnet."
39#endif
40
27void 41void
28application_clear(MESSENGER_Application *app) 42application_clear(MESSENGER_Application *app)
29{ 43{
@@ -35,14 +49,34 @@ application_clear(MESSENGER_Application *app)
35 49
36void 50void
37application_init(MESSENGER_Application *app, 51application_init(MESSENGER_Application *app,
38 int argc, 52 int argc,
39 char **argv) 53 char **argv)
40{ 54{
55 const struct GNUNET_GETOPT_CommandLineOption options [] = {
56 GNUNET_GETOPT_option_version(MESSENGER_CLI_VERSION),
57 GNUNET_GETOPT_option_help(MESSENGER_CLI_DESC),
58 GNUNET_GETOPT_OPTION_END
59 };
60
41 memset(app, 0, sizeof(*app)); 61 memset(app, 0, sizeof(*app));
42 62
43 app->argc = argc; 63 app->argc = argc;
44 app->argv = argv; 64 app->argv = argv;
45 65
66 const int parsing = GNUNET_GETOPT_run(
67 MESSENGER_CLI_BINARY,
68 options,
69 app->argc,
70 app->argv
71 );
72
73 if (parsing <= 0)
74 {
75 app->window = NULL;
76 app->status = GNUNET_SYSERR == parsing? GNUNET_SYSERR : GNUNET_OK;
77 return;
78 }
79
46 app->window = initscr(); 80 app->window = initscr();
47 81
48 if (!(app->window)) 82 if (!(app->window))
@@ -90,18 +124,18 @@ run (void *cls,
90void 124void
91application_run(MESSENGER_Application *app) 125application_run(MESSENGER_Application *app)
92{ 126{
93 struct GNUNET_GETOPT_CommandLineOption options[] = { 127 const struct GNUNET_GETOPT_CommandLineOption options [] = {
94 GNUNET_GETOPT_OPTION_END 128 GNUNET_GETOPT_OPTION_END
95 }; 129 };
96 130
97 app->status = GNUNET_PROGRAM_run( 131 app->status = GNUNET_PROGRAM_run(
98 app->argc, 132 1,
99 app->argv, 133 app->argv,
100 "messenger_cli", 134 MESSENGER_CLI_BINARY,
101 gettext_noop("A CLI for the Messenger service of GNUnet."), 135 gettext_noop(MESSENGER_CLI_DESC),
102 options, 136 options,
103 &run, 137 &run,
104 app 138 app
105 ); 139 );
106 140
107 members_clear(&(app->current.members)); 141 members_clear(&(app->current.members));
diff --git a/src/application.h b/src/application.h
index ea248e0..2ed9ea4 100644
--- a/src/application.h
+++ b/src/application.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -29,7 +29,6 @@
29#include <curses.h> 29#include <curses.h>
30 30
31#include "chat.h" 31#include "chat.h"
32#include "util.h"
33 32
34#include "ui/accounts.h" 33#include "ui/accounts.h"
35#include "ui/chat.h" 34#include "ui/chat.h"
diff --git a/src/chat.c b/src/chat.c
index a0073d9..792f8eb 100644
--- a/src/chat.c
+++ b/src/chat.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2024 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -26,6 +26,16 @@
26 26
27#include "application.h" 27#include "application.h"
28#include "util.h" 28#include "util.h"
29#include <curses.h>
30#include <gnunet/gnunet_chat_lib.h>
31
32#ifndef MESSENGER_CLI_BINARY
33#define MESSENGER_CLI_BINARY "messenger_cli"
34#endif
35
36#ifndef MESSENGER_CLI_VERSION
37#define MESSENGER_CLI_VERSION "unknown"
38#endif
29 39
30static void 40static void
31_chat_refresh(MESSENGER_Application *app) 41_chat_refresh(MESSENGER_Application *app)
@@ -45,6 +55,14 @@ _chat_refresh(MESSENGER_Application *app)
45 wmove(app->ui.logo, 0, 0); 55 wmove(app->ui.logo, 0, 0);
46 56
47 util_print_logo(app->ui.logo); 57 util_print_logo(app->ui.logo);
58
59 int x = getcurx(app->ui.logo);
60 int y = getcury(app->ui.logo);
61
62 util_print_info(app->ui.logo, MESSENGER_CLI_VERSION);
63
64 wmove(app->ui.logo, --y, x);
65 util_print_info(app->ui.logo, MESSENGER_CLI_BINARY);
48} 66}
49 67
50static bool 68static bool
@@ -357,6 +375,8 @@ chat_process_message(UNUSED MESSENGER_Chat *chat,
357 &(current->messages), 375 &(current->messages),
358 GNUNET_CHAT_message_get_target(message) 376 GNUNET_CHAT_message_get_target(message)
359 ); 377 );
378 else if (GNUNET_YES == GNUNET_CHAT_message_is_deleted(message))
379 messages_remove(&(current->messages), message);
360 else if ((GNUNET_CHAT_KIND_JOIN != kind) || (new_member)) 380 else if ((GNUNET_CHAT_KIND_JOIN != kind) || (new_member))
361 messages_add(&(current->messages), message); 381 messages_add(&(current->messages), message);
362} 382}
diff --git a/src/chat.h b/src/chat.h
index 7eb103f..00c01f1 100644
--- a/src/chat.h
+++ b/src/chat.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -25,7 +25,6 @@
25#ifndef CHAT_H_ 25#ifndef CHAT_H_
26#define CHAT_H_ 26#define CHAT_H_
27 27
28#include <gnunet/platform.h>
29#include <gnunet/gnunet_chat_lib.h> 28#include <gnunet/gnunet_chat_lib.h>
30#include <gnunet/gnunet_util_lib.h> 29#include <gnunet/gnunet_util_lib.h>
31 30
diff --git a/src/meson.build b/src/meson.build
new file mode 100644
index 0000000..1d98bea
--- /dev/null
+++ b/src/meson.build
@@ -0,0 +1,28 @@
1#
2# This file is part of GNUnet.
3# Copyright (C) 2023 GNUnet e.V.
4#
5# GNUnet is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Affero General Public License as published
7# by the Free Software Foundation, either version 3 of the License,
8# or (at your option) any later version.
9#
10# GNUnet is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17#
18# SPDX-License-Identifier: AGPL3.0-or-later
19#
20
21subdir('ui')
22
23messenger_cli_sources = files([
24 'application.c', 'application.h',
25 'chat.c', 'chat.h',
26 'util.c', 'util.h',
27 'messenger_cli.c',
28]) + messenger_cli_ui_sources
diff --git a/src/ui/account_create_dialog.c b/src/ui/account_create_dialog.c
index 1ef6568..6845a1d 100644
--- a/src/ui/account_create_dialog.c
+++ b/src/ui/account_create_dialog.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -24,13 +24,11 @@
24 24
25#include "account_create_dialog.h" 25#include "account_create_dialog.h"
26 26
27#include <gnunet/platform.h>
28#include <gnunet/gnunet_chat_lib.h> 27#include <gnunet/gnunet_chat_lib.h>
29#include <gnunet/gnunet_util_lib.h> 28#include <gnunet/gnunet_util_lib.h>
30 29
31#include "text_input.h" 30#include "text_input.h"
32#include "../application.h" 31#include "../application.h"
33#include "../util.h"
34 32
35void 33void
36account_create_dialog_event(UI_ACCOUNT_CREATE_DIALOG_Handle *create_dialog, 34account_create_dialog_event(UI_ACCOUNT_CREATE_DIALOG_Handle *create_dialog,
diff --git a/src/ui/accounts.h b/src/ui/accounts.h
index 2566e78..392f476 100644
--- a/src/ui/accounts.h
+++ b/src/ui/accounts.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -28,7 +28,6 @@
28#include <stdlib.h> 28#include <stdlib.h>
29#include <curses.h> 29#include <curses.h>
30 30
31#include <gnunet/platform.h>
32#include <gnunet/gnunet_chat_lib.h> 31#include <gnunet/gnunet_chat_lib.h>
33#include <gnunet/gnunet_util_lib.h> 32#include <gnunet/gnunet_util_lib.h>
34 33
diff --git a/src/ui/chat_open_dialog.c b/src/ui/chat_open_dialog.c
index cd98401..1ea5863 100644
--- a/src/ui/chat_open_dialog.c
+++ b/src/ui/chat_open_dialog.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -24,13 +24,11 @@
24 24
25#include "chat_open_dialog.h" 25#include "chat_open_dialog.h"
26 26
27#include <gnunet/platform.h>
28#include <gnunet/gnunet_chat_lib.h> 27#include <gnunet/gnunet_chat_lib.h>
29#include <gnunet/gnunet_util_lib.h> 28#include <gnunet/gnunet_util_lib.h>
30 29
31#include "text_input.h" 30#include "text_input.h"
32#include "../application.h" 31#include "../application.h"
33#include "../util.h"
34 32
35void 33void
36chat_open_dialog_event(UI_CHAT_OPEN_DIALOG_Handle *open_dialog, 34chat_open_dialog_event(UI_CHAT_OPEN_DIALOG_Handle *open_dialog,
diff --git a/src/ui/chats.c b/src/ui/chats.c
index 55e08df..5889dd4 100644
--- a/src/ui/chats.c
+++ b/src/ui/chats.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2024 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -27,8 +27,10 @@
27#include "list_input.h" 27#include "list_input.h"
28#include "../application.h" 28#include "../application.h"
29#include "../util.h" 29#include "../util.h"
30#include <gnunet/gnunet_chat_lib.h>
31#include <gnunet/gnunet_common.h>
30 32
31static int 33static enum GNUNET_GenericReturnValue
32_chats_iterate_group(void *cls, 34_chats_iterate_group(void *cls,
33 UNUSED struct GNUNET_CHAT_Handle *handle, 35 UNUSED struct GNUNET_CHAT_Handle *handle,
34 struct GNUNET_CHAT_Group *group) 36 struct GNUNET_CHAT_Group *group)
@@ -38,17 +40,21 @@ _chats_iterate_group(void *cls,
38 return GNUNET_YES; 40 return GNUNET_YES;
39} 41}
40 42
41static int 43static enum GNUNET_GenericReturnValue
42_chats_iterate_contact(void *cls, 44_chats_iterate_contact(void *cls,
43 UNUSED struct GNUNET_CHAT_Handle *handle, 45 UNUSED struct GNUNET_CHAT_Handle *handle,
44 struct GNUNET_CHAT_Contact *contact) 46 struct GNUNET_CHAT_Contact *contact)
45{ 47{
46 UI_CHATS_Handle *chats = cls; 48 UI_CHATS_Handle *chats = cls;
49
50 if (GNUNET_YES == GNUNET_CHAT_contact_is_owned(contact))
51 return GNUNET_YES;
52
47 list_input_select(chats, 1, GNUNET_CHAT_contact_get_context(contact)); 53 list_input_select(chats, 1, GNUNET_CHAT_contact_get_context(contact));
48 return GNUNET_YES; 54 return GNUNET_YES;
49} 55}
50 56
51static int 57static enum GNUNET_GenericReturnValue
52_chats_iterate_messages(void *cls, 58_chats_iterate_messages(void *cls,
53 struct GNUNET_CHAT_Context *context, 59 struct GNUNET_CHAT_Context *context,
54 const struct GNUNET_CHAT_Message *message) 60 const struct GNUNET_CHAT_Message *message)
@@ -165,7 +171,7 @@ _chats_print_entry(UI_CHATS_Handle *chats,
165 return GNUNET_YES; 171 return GNUNET_YES;
166} 172}
167 173
168int 174enum GNUNET_GenericReturnValue
169_chats_iterate_print_group(void *cls, 175_chats_iterate_print_group(void *cls,
170 UNUSED struct GNUNET_CHAT_Handle *handle, 176 UNUSED struct GNUNET_CHAT_Handle *handle,
171 struct GNUNET_CHAT_Group *group) 177 struct GNUNET_CHAT_Group *group)
@@ -175,12 +181,16 @@ _chats_iterate_print_group(void *cls,
175 return _chats_print_entry(chats, 'x', 'G', name); 181 return _chats_print_entry(chats, 'x', 'G', name);
176} 182}
177 183
178int 184enum GNUNET_GenericReturnValue
179_chats_iterate_print_contact(void *cls, 185_chats_iterate_print_contact(void *cls,
180 UNUSED struct GNUNET_CHAT_Handle *handle, 186 UNUSED struct GNUNET_CHAT_Handle *handle,
181 struct GNUNET_CHAT_Contact *contact) 187 struct GNUNET_CHAT_Contact *contact)
182{ 188{
183 UI_CHATS_Handle *chats = cls; 189 UI_CHATS_Handle *chats = cls;
190
191 if (GNUNET_YES == GNUNET_CHAT_contact_is_owned(contact))
192 return GNUNET_YES;
193
184 const char *name = GNUNET_CHAT_contact_get_name(contact); 194 const char *name = GNUNET_CHAT_contact_get_name(contact);
185 return _chats_print_entry(chats, 'x', 'C', name); 195 return _chats_print_entry(chats, 'x', 'C', name);
186} 196}
diff --git a/src/ui/chats.h b/src/ui/chats.h
index 7ab64d5..eb0ba99 100644
--- a/src/ui/chats.h
+++ b/src/ui/chats.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -28,7 +28,6 @@
28#include <stdlib.h> 28#include <stdlib.h>
29#include <curses.h> 29#include <curses.h>
30 30
31#include <gnunet/platform.h>
32#include <gnunet/gnunet_chat_lib.h> 31#include <gnunet/gnunet_chat_lib.h>
33#include <gnunet/gnunet_util_lib.h> 32#include <gnunet/gnunet_util_lib.h>
34 33
diff --git a/src/ui/lobby_create_dialog.h b/src/ui/lobby_create_dialog.h
index 42d06fc..4ec5501 100644
--- a/src/ui/lobby_create_dialog.h
+++ b/src/ui/lobby_create_dialog.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -28,7 +28,6 @@
28#include <stdlib.h> 28#include <stdlib.h>
29#include <curses.h> 29#include <curses.h>
30 30
31#include <gnunet/platform.h>
32#include <gnunet/gnunet_chat_lib.h> 31#include <gnunet/gnunet_chat_lib.h>
33#include <gnunet/gnunet_util_lib.h> 32#include <gnunet/gnunet_util_lib.h>
34 33
diff --git a/src/ui/lobby_enter_dialog.c b/src/ui/lobby_enter_dialog.c
index 0ae9018..a3ef356 100644
--- a/src/ui/lobby_enter_dialog.c
+++ b/src/ui/lobby_enter_dialog.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -24,13 +24,11 @@
24 24
25#include "lobby_enter_dialog.h" 25#include "lobby_enter_dialog.h"
26 26
27#include <gnunet/platform.h>
28#include <gnunet/gnunet_chat_lib.h> 27#include <gnunet/gnunet_chat_lib.h>
29#include <gnunet/gnunet_util_lib.h> 28#include <gnunet/gnunet_util_lib.h>
30 29
31#include "text_input.h" 30#include "text_input.h"
32#include "../application.h" 31#include "../application.h"
33#include "../util.h"
34 32
35void 33void
36lobby_enter_dialog_event(UI_LOBBY_ENTER_DIALOG_Handle *enter_dialog, 34lobby_enter_dialog_event(UI_LOBBY_ENTER_DIALOG_Handle *enter_dialog,
diff --git a/src/ui/members.h b/src/ui/members.h
index 7769e74..9ff3078 100644
--- a/src/ui/members.h
+++ b/src/ui/members.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -29,7 +29,6 @@
29#include <stdlib.h> 29#include <stdlib.h>
30#include <curses.h> 30#include <curses.h>
31 31
32#include <gnunet/platform.h>
33#include <gnunet/gnunet_chat_lib.h> 32#include <gnunet/gnunet_chat_lib.h>
34#include <gnunet/gnunet_util_lib.h> 33#include <gnunet/gnunet_util_lib.h>
35 34
diff --git a/src/ui/meson.build b/src/ui/meson.build
new file mode 100644
index 0000000..a57c670
--- /dev/null
+++ b/src/ui/meson.build
@@ -0,0 +1,33 @@
1#
2# This file is part of GNUnet.
3# Copyright (C) 2023 GNUnet e.V.
4#
5# GNUnet is free software: you can redistribute it and/or modify it
6# under the terms of the GNU Affero General Public License as published
7# by the Free Software Foundation, either version 3 of the License,
8# or (at your option) any later version.
9#
10# GNUnet is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17#
18# SPDX-License-Identifier: AGPL3.0-or-later
19#
20
21messenger_cli_ui_sources = files([
22 'account_create_dialog.c', 'account_create_dialog.h',
23 'accounts.c', 'accounts.h',
24 'chat_open_dialog.c', 'chat_open_dialog.h',
25 'chat.h',
26 'chats.c', 'chats.h',
27 'list_input.h',
28 'lobby_create_dialog.c', 'lobby_create_dialog.h',
29 'lobby_enter_dialog.c', 'lobby_enter_dialog.h',
30 'members.c', 'members.h',
31 'messages.c', 'messages.h',
32 'text_input.h',
33])
diff --git a/src/ui/messages.c b/src/ui/messages.c
index 8bfd934..1dea885 100644
--- a/src/ui/messages.c
+++ b/src/ui/messages.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2024 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -28,10 +28,12 @@
28#include "text_input.h" 28#include "text_input.h"
29#include "../application.h" 29#include "../application.h"
30#include "../util.h" 30#include "../util.h"
31#include <gnunet/gnunet_chat_lib.h>
32#include <gnunet/gnunet_common.h>
31 33
32struct tm* 34struct tm*
33_messages_new_day(time_t* current_time, 35_messages_new_day(time_t* current_time,
34 const time_t* timestamp) 36 const time_t* timestamp)
35{ 37{
36 struct tm* ts = localtime(timestamp); 38 struct tm* ts = localtime(timestamp);
37 39
@@ -57,21 +59,21 @@ _messages_handle_message(UI_MESSAGES_Handle *messages)
57 case GNUNET_CHAT_KIND_INVITATION: 59 case GNUNET_CHAT_KIND_INVITATION:
58 { 60 {
59 struct GNUNET_CHAT_Invitation *invitation = ( 61 struct GNUNET_CHAT_Invitation *invitation = (
60 GNUNET_CHAT_message_get_invitation(messages->selected) 62 GNUNET_CHAT_message_get_invitation(messages->selected)
61 ); 63 );
62 64
63 if (invitation) 65 if (invitation)
64 GNUNET_CHAT_invitation_accept(invitation); 66 GNUNET_CHAT_invitation_accept(invitation);
65 break; 67 break;
66 } 68 }
67 case GNUNET_CHAT_KIND_FILE: 69 case GNUNET_CHAT_KIND_FILE:
68 { 70 {
69 struct GNUNET_CHAT_File *file = GNUNET_CHAT_message_get_file( 71 struct GNUNET_CHAT_File *file = GNUNET_CHAT_message_get_file(
70 messages->selected 72 messages->selected
71 ); 73 );
72 74
73 if ((file) && (GNUNET_YES != GNUNET_CHAT_file_is_downloading(file))) 75 if ((file) && (GNUNET_YES != GNUNET_CHAT_file_is_downloading(file)))
74 GNUNET_CHAT_file_start_download(file, NULL, NULL); 76 GNUNET_CHAT_file_start_download(file, NULL, NULL);
75 break; 77 break;
76 default: 78 default:
77 break; 79 break;
@@ -81,8 +83,8 @@ _messages_handle_message(UI_MESSAGES_Handle *messages)
81 83
82void 84void
83messages_event(UI_MESSAGES_Handle *messages, 85messages_event(UI_MESSAGES_Handle *messages,
84 MESSENGER_Application *app, 86 MESSENGER_Application *app,
85 int key) 87 int key)
86{ 88{
87 list_input_reset(messages); 89 list_input_reset(messages);
88 messages->line_time = 0; 90 messages->line_time = 0;
@@ -91,8 +93,8 @@ messages_event(UI_MESSAGES_Handle *messages,
91 while (element) 93 while (element)
92 { 94 {
93 struct tm *ts = _messages_new_day( 95 struct tm *ts = _messages_new_day(
94 &(messages->line_time), 96 &(messages->line_time),
95 &(element->timestamp) 97 &(element->timestamp)
96 ); 98 );
97 99
98 list_input_select(messages, ts? 2 : 1, element->message); 100 list_input_select(messages, ts? 2 : 1, element->message);
@@ -113,44 +115,44 @@ messages_event(UI_MESSAGES_Handle *messages,
113 case '\n': 115 case '\n':
114 case KEY_ENTER: 116 case KEY_ENTER:
115 if (messages->selected) 117 if (messages->selected)
116 _messages_handle_message(messages); 118 _messages_handle_message(messages);
117 else if (messages->text_len > 0) 119 else if (messages->text_len > 0)
118 { 120 {
119 if (0 != strncmp(messages->text, 121 if (0 != strncmp(messages->text,
120 UI_MESSAGES_FILE_PREFIX, 122 UI_MESSAGES_FILE_PREFIX,
121 UI_MESSAGES_FILE_PREFIX_LEN)) 123 UI_MESSAGES_FILE_PREFIX_LEN))
122 goto write_text; 124 goto write_text;
123 125
124 const char* filename = messages->text + 5; 126 const char* filename = messages->text + 5;
125 127
126 if (0 != access(filename, R_OK | F_OK)) 128 if (0 != access(filename, R_OK | F_OK))
127 break; 129 break;
128 130
129 GNUNET_CHAT_context_send_file( 131 GNUNET_CHAT_context_send_file(
130 app->chat.context, 132 app->chat.context,
131 filename, 133 filename,
132 NULL, 134 NULL,
133 NULL 135 NULL
134 ); 136 );
135 137
136 goto drop_text; 138 goto drop_text;
137 139
138 write_text: 140 write_text:
139 GNUNET_CHAT_context_send_text( 141 GNUNET_CHAT_context_send_text(
140 app->chat.context, 142 app->chat.context,
141 messages->text 143 messages->text
142 ); 144 );
143 145
144 drop_text: 146 drop_text:
145 messages->text_len = 0; 147 messages->text_len = 0;
146 } 148 }
147 break; 149 break;
148 case KEY_BACKSPACE: 150 case KEY_BACKSPACE:
149 if (messages->selected) 151 if (messages->selected)
150 GNUNET_CHAT_message_delete( 152 GNUNET_CHAT_message_delete(
151 messages->selected, 153 messages->selected,
152 GNUNET_TIME_relative_get_zero_() 154 GNUNET_TIME_relative_get_zero_()
153 ); 155 );
154 break; 156 break;
155 default: 157 default:
156 break; 158 break;
@@ -164,14 +166,30 @@ messages_event(UI_MESSAGES_Handle *messages,
164 166
165void 167void
166_messages_iterate_print(UI_MESSAGES_Handle *messages, 168_messages_iterate_print(UI_MESSAGES_Handle *messages,
167 const time_t* timestamp, 169 const time_t* timestamp,
168 const struct GNUNET_CHAT_Message *message) 170 const struct GNUNET_CHAT_Message *message)
169{ 171{
172 static const char *you = "you";
173
170 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); 174 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message);
171 175
172 struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message); 176 struct GNUNET_CHAT_Contact *sender = GNUNET_CHAT_message_get_sender(message);
177 struct GNUNET_CHAT_Contact *recipient = GNUNET_CHAT_message_get_recipient(message);
178
179 enum GNUNET_GenericReturnValue sent = GNUNET_CHAT_message_is_sent(message);
180 const char *msg_s = GNUNET_YES == sent? "" : "s";
181
182 enum GNUNET_GenericReturnValue recv = recipient?
183 GNUNET_CHAT_contact_is_owned(recipient) : GNUNET_NO;
184
185 const char *name = GNUNET_YES == sent? you : (
186 sender? GNUNET_CHAT_contact_get_name(sender) : NULL
187 );
188
189 const char *rcp = GNUNET_YES == recv? you : (
190 recipient? GNUNET_CHAT_contact_get_name(recipient) : you
191 );
173 192
174 const char *name = sender? GNUNET_CHAT_contact_get_name(sender) : NULL;
175 const char *text = GNUNET_CHAT_message_get_text(message); 193 const char *text = GNUNET_CHAT_message_get_text(message);
176 194
177 const struct GNUNET_CHAT_File *file = GNUNET_CHAT_message_get_file(message); 195 const struct GNUNET_CHAT_File *file = GNUNET_CHAT_message_get_file(message);
@@ -209,31 +227,35 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages,
209 switch (kind) { 227 switch (kind) {
210 case GNUNET_CHAT_KIND_JOIN: 228 case GNUNET_CHAT_KIND_JOIN:
211 wprintw( 229 wprintw(
212 messages->window, 230 messages->window,
213 "%s joins the room.", 231 "%s join%s the room.",
214 name 232 name,
233 msg_s
215 ); 234 );
216 break; 235 break;
217 case GNUNET_CHAT_KIND_LEAVE: 236 case GNUNET_CHAT_KIND_LEAVE:
218 wprintw( 237 wprintw(
219 messages->window, 238 messages->window,
220 "%s leaves the room.", 239 "%s leave%s the room.",
221 name 240 name,
241 msg_s
222 ); 242 );
223 break; 243 break;
224 case GNUNET_CHAT_KIND_INVITATION: 244 case GNUNET_CHAT_KIND_INVITATION:
225 wprintw( 245 wprintw(
226 messages->window, 246 messages->window,
227 "%s invites you to a room.", 247 "%s invite%s %s to a room.",
228 name 248 name,
249 msg_s,
250 rcp
229 ); 251 );
230 break; 252 break;
231 case GNUNET_CHAT_KIND_TEXT: 253 case GNUNET_CHAT_KIND_TEXT:
232 wprintw( 254 wprintw(
233 messages->window, 255 messages->window,
234 "%s: %s", 256 "%s: %s",
235 name, 257 name,
236 text 258 text
237 ); 259 );
238 break; 260 break;
239 case GNUNET_CHAT_KIND_FILE: { 261 case GNUNET_CHAT_KIND_FILE: {
@@ -243,22 +265,23 @@ _messages_iterate_print(UI_MESSAGES_Handle *messages,
243 const uint64_t filesize = GNUNET_CHAT_file_get_size(file); 265 const uint64_t filesize = GNUNET_CHAT_file_get_size(file);
244 266
245 wprintw( 267 wprintw(
246 messages->window, 268 messages->window,
247 "%s shares the file '%s' (%lu / %lu) with you.", 269 "%s share%s the file '%s' (%lu / %lu).",
248 name, 270 name,
249 filename, 271 msg_s,
250 localsize, 272 filename,
251 filesize 273 localsize,
274 filesize
252 ); 275 );
253 break; 276 break;
254 } 277 }
255 default: 278 default:
256 wprintw( 279 wprintw(
257 messages->window, 280 messages->window,
258 "[%d] %s: %s", 281 "[%d] %s: %s",
259 (int) kind, 282 (int) kind,
260 name, 283 name,
261 text 284 text
262 ); 285 );
263 break; 286 break;
264 } 287 }
@@ -295,9 +318,9 @@ messages_print(UI_MESSAGES_Handle *messages)
295 whline(messages->window, '-', width); 318 whline(messages->window, '-', width);
296 319
297 const bool is_file_text = (0 == strncmp( 320 const bool is_file_text = (0 == strncmp(
298 messages->text, 321 messages->text,
299 UI_MESSAGES_FILE_PREFIX, 322 UI_MESSAGES_FILE_PREFIX,
300 UI_MESSAGES_FILE_PREFIX_LEN 323 UI_MESSAGES_FILE_PREFIX_LEN
301 )); 324 ));
302 325
303 const int attrs_select = A_BOLD | (is_file_text? A_ITALIC : A_NORMAL); 326 const int attrs_select = A_BOLD | (is_file_text? A_ITALIC : A_NORMAL);
@@ -327,9 +350,9 @@ messages_clear(UI_MESSAGES_Handle *messages)
327 element = messages->head; 350 element = messages->head;
328 351
329 GNUNET_CONTAINER_DLL_remove( 352 GNUNET_CONTAINER_DLL_remove(
330 messages->head, 353 messages->head,
331 messages->tail, 354 messages->tail,
332 element 355 element
333 ); 356 );
334 357
335 GNUNET_free(element); 358 GNUNET_free(element);
@@ -338,8 +361,8 @@ messages_clear(UI_MESSAGES_Handle *messages)
338 361
339static int 362static int
340_message_compare_timestamps(UNUSED void *cls, 363_message_compare_timestamps(UNUSED void *cls,
341 UI_MESSAGES_List *list0, 364 UI_MESSAGES_List *list0,
342 UI_MESSAGES_List *list1) 365 UI_MESSAGES_List *list1)
343{ 366{
344 if ((!list0) || (!list1)) 367 if ((!list0) || (!list1))
345 return 0; 368 return 0;
@@ -354,13 +377,13 @@ _message_compare_timestamps(UNUSED void *cls,
354 377
355void 378void
356messages_add(UI_MESSAGES_Handle *messages, 379messages_add(UI_MESSAGES_Handle *messages,
357 const struct GNUNET_CHAT_Message *message) 380 const struct GNUNET_CHAT_Message *message)
358{ 381{
359 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); 382 enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message);
360 383
361 switch (kind) { 384 switch (kind) {
385 case GNUNET_CHAT_KIND_UPDATE:
362 case GNUNET_CHAT_KIND_CONTACT: 386 case GNUNET_CHAT_KIND_CONTACT:
363 case GNUNET_CHAT_KIND_WHISPER:
364 case GNUNET_CHAT_KIND_DELETION: 387 case GNUNET_CHAT_KIND_DELETION:
365 return; 388 return;
366 default: 389 default:
@@ -385,11 +408,11 @@ messages_add(UI_MESSAGES_Handle *messages,
385 list_input_select(messages, 1, NULL); 408 list_input_select(messages, 1, NULL);
386 409
387 const struct GNUNET_TIME_Absolute abs_time = ( 410 const struct GNUNET_TIME_Absolute abs_time = (
388 GNUNET_CHAT_message_get_timestamp(message) 411 GNUNET_CHAT_message_get_timestamp(message)
389 ); 412 );
390 413
391 const struct GNUNET_TIME_Timestamp timestamp = ( 414 const struct GNUNET_TIME_Timestamp timestamp = (
392 GNUNET_TIME_absolute_to_timestamp(abs_time) 415 GNUNET_TIME_absolute_to_timestamp(abs_time)
393 ); 416 );
394 417
395 element = GNUNET_new(UI_MESSAGES_List); 418 element = GNUNET_new(UI_MESSAGES_List);
@@ -413,7 +436,7 @@ messages_add(UI_MESSAGES_Handle *messages,
413 436
414void 437void
415messages_remove(UI_MESSAGES_Handle *messages, 438messages_remove(UI_MESSAGES_Handle *messages,
416 const struct GNUNET_CHAT_Message *message) 439 const struct GNUNET_CHAT_Message *message)
417{ 440{
418 UI_MESSAGES_List *element = messages->head; 441 UI_MESSAGES_List *element = messages->head;
419 while (element) 442 while (element)
@@ -426,8 +449,8 @@ messages_remove(UI_MESSAGES_Handle *messages,
426 449
427 if (element) 450 if (element)
428 GNUNET_CONTAINER_DLL_remove( 451 GNUNET_CONTAINER_DLL_remove(
429 messages->head, 452 messages->head,
430 messages->tail, 453 messages->tail,
431 element 454 element
432 ); 455 );
433} 456}
diff --git a/src/ui/messages.h b/src/ui/messages.h
index 3d509db..bcb2336 100644
--- a/src/ui/messages.h
+++ b/src/ui/messages.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2023 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -26,9 +26,10 @@
26#define UI_MESSAGES_H_ 26#define UI_MESSAGES_H_
27 27
28#include <stdlib.h> 28#include <stdlib.h>
29#include <time.h>
30#include <unistd.h>
29#include <curses.h> 31#include <curses.h>
30 32
31#include <gnunet/platform.h>
32#include <gnunet/gnunet_chat_lib.h> 33#include <gnunet/gnunet_chat_lib.h>
33#include <gnunet/gnunet_util_lib.h> 34#include <gnunet/gnunet_util_lib.h>
34 35
diff --git a/src/util.c b/src/util.c
index 6647fef..89155c8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2024 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include "util.h" 25#include "util.h"
26#include <string.h>
26 27
27void 28void
28util_print_logo(WINDOW *window) 29util_print_logo(WINDOW *window)
@@ -41,3 +42,18 @@ util_print_logo(WINDOW *window)
41 wmove(window, y++, x); wprintw(window, " oooo "); 42 wmove(window, y++, x); wprintw(window, " oooo ");
42 wmove(window, y++, x); wprintw(window, " "); 43 wmove(window, y++, x); wprintw(window, " ");
43} 44}
45
46void
47util_print_info(WINDOW *window,
48 const char *info)
49{
50 const int x = getmaxx(window) - strlen(info) - 1;
51 const int y = getcury(window);
52
53 if ((x + (y - 2) / 2 < UTIL_LOGO_COLS - 7) ||
54 ((y < 4) && (x < UTIL_LOGO_COLS)))
55 return;
56
57 wmove(window, y, x);
58 wprintw(window, "%s", info);
59}
diff --git a/src/util.h b/src/util.h
index ba4c735..d1126a9 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V. 3 Copyright (C) 2022--2024 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -43,4 +43,15 @@
43void 43void
44util_print_logo(WINDOW *window); 44util_print_logo(WINDOW *window);
45 45
46/**
47 * Print information on the right side of
48 * the application besides the main logo.
49 *
50 * @param[in,out] window Window view
51 * @param[in] info Information
52 */
53void
54util_print_info(WINDOW *window,
55 const char *info);
56
46#endif /* UTIL_H_ */ 57#endif /* UTIL_H_ */