Skip to content

Commit aee06dd

Browse files
committed
refactor: split view into tabs
1 parent 6b36e56 commit aee06dd

File tree

12 files changed

+326
-145
lines changed

12 files changed

+326
-145
lines changed

platform/bukkit/src/test/java/net/silthus/schat/bukkit/BukkitTests.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ protected void assertLastMessageIs(PlayerMock player, String message) {
8585
assertTrimmedEquals(getLastMessage(player::nextMessage), message);
8686
}
8787

88+
protected void assertLastMessageContains(PlayerMock player, String text) {
89+
assertTrimmedContains(getLastMessage(player::nextMessage), text);
90+
}
91+
8892
@Nullable
8993
private String getLastMessage(Supplier<String> nextMessageSupplier) {
9094
String nextMessage;
@@ -96,8 +100,21 @@ private String getLastMessage(Supplier<String> nextMessageSupplier) {
96100
}
97101

98102
private void assertTrimmedEquals(String lastMessage, String message) {
99-
if (lastMessage == null && message == null) return;
100-
assertThat(lastMessage).isNotNull();
103+
if (isEmpty(lastMessage, message))
104+
return;
101105
assertThat(lastMessage.trim()).isEqualTo(message.trim());
102106
}
107+
108+
private void assertTrimmedContains(String lastMessage, String text) {
109+
if (isEmpty(lastMessage, text))
110+
return;
111+
assertThat(lastMessage.trim()).contains(text.trim());
112+
}
113+
114+
private boolean isEmpty(String lastMessage, String message) {
115+
if (lastMessage == null && message == null)
116+
return true;
117+
assertThat(lastMessage).isNotNull();
118+
return false;
119+
}
103120
}

platform/bukkit/src/test/java/net/silthus/schat/bukkit/adapter/BukkitChatterFactoryTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void setUp() {
9292

9393
@Test
9494
void then_player_receives_message() {
95-
assertLastMessageIs(player, "Hey");
95+
assertLastMessageContains(player, "Hey");
9696
}
9797
}
9898
}

platform/src/main/resources/schat_en.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ schat.chat.private.you=You
3131
schat.suggest.command.join-channel=Join a channel with {0}
3232
schat.hover.join-channel=Click to join the channel: {0}.
3333

34+
schat.view.no-channels=You are in no channels.

platform/src/test/java/net/silthus/schat/platform/config/ConfigTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
import static net.silthus.schat.message.Message.message;
4545
import static net.silthus.schat.platform.config.ConfigKeys.CHANNELS;
4646
import static net.silthus.schat.platform.config.TestConfigurationAdapter.testConfigAdapter;
47-
import static net.silthus.schat.ui.views.TabbedChannelsView.CHANNEL_FORMAT;
48-
import static net.silthus.schat.ui.views.TabbedChannelsView.MESSAGE_FORMAT;
47+
import static net.silthus.schat.ui.views.tabbed.TabbedChannelsView.CHANNEL_FORMAT;
48+
import static net.silthus.schat.ui.views.tabbed.TabbedChannelsView.MESSAGE_FORMAT;
4949
import static org.assertj.core.api.Assertions.assertThat;
5050

5151
class ConfigTests {

ui/src/main/java/net/silthus/schat/ui/util/ViewHelper.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
* This file is part of sChat, licensed under the MIT License.
3+
* Copyright (C) Silthus <https://www.github.com/silthus>
4+
* Copyright (C) sChat team and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
125
package net.silthus.schat.ui.util;
226

327
import net.kyori.adventure.text.Component;

ui/src/main/java/net/silthus/schat/ui/views/Views.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import lombok.NonNull;
2828
import net.silthus.schat.chatter.Chatter;
2929
import net.silthus.schat.ui.view.View;
30+
import net.silthus.schat.ui.views.tabbed.TabbedChannelsView;
3031

3132
public final class Views {
3233

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* This file is part of sChat, licensed under the MIT License.
3+
* Copyright (C) Silthus <https://www.github.com/silthus>
4+
* Copyright (C) sChat team and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.silthus.schat.ui.views.tabbed;
26+
27+
import java.util.Collection;
28+
import java.util.List;
29+
import lombok.Data;
30+
import lombok.experimental.Accessors;
31+
import net.kyori.adventure.text.Component;
32+
import net.kyori.adventure.text.TextComponent;
33+
import net.silthus.schat.message.Message;
34+
import net.silthus.schat.ui.format.Format;
35+
import net.silthus.schat.ui.view.View;
36+
import org.jetbrains.annotations.NotNull;
37+
38+
import static net.kyori.adventure.text.Component.join;
39+
import static net.kyori.adventure.text.Component.newline;
40+
import static net.kyori.adventure.text.Component.text;
41+
import static net.kyori.adventure.text.JoinConfiguration.newlines;
42+
import static net.silthus.schat.util.Iterators.lastN;
43+
44+
@Data
45+
@Accessors(fluent = true)
46+
public abstract class AbstractTab implements Tab {
47+
private final TabbedChannelsView view;
48+
private Format messageFormat;
49+
50+
protected AbstractTab(TabbedChannelsView view, Format messageFormat) {
51+
this.view = view;
52+
this.messageFormat = messageFormat;
53+
}
54+
55+
@Override
56+
public Component renderContent() {
57+
return renderBlankLines()
58+
.append(join(newlines(), renderMessages()));
59+
}
60+
61+
protected abstract boolean isMessageDisplayed(Message message);
62+
63+
protected List<Component> renderMessages() {
64+
return messages().stream()
65+
.map(message -> messageFormat().format(view, message))
66+
.toList();
67+
}
68+
69+
protected @NotNull Collection<Message> messages() {
70+
return view.viewModel().messages().stream()
71+
.filter(this::isMessageDisplayed)
72+
.collect(lastN(100));
73+
}
74+
75+
protected final Component renderBlankLines() {
76+
final int blankLineAmount = Math.max(0, view.get(View.VIEW_HEIGHT) - messages().size());
77+
return renderBlankLines(blankLineAmount);
78+
}
79+
80+
protected final Component renderBlankLines(int amount) {
81+
final TextComponent.Builder builder = text();
82+
for (int i = 0; i < amount; i++) {
83+
builder.append(newline());
84+
}
85+
return builder.build();
86+
}
87+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* This file is part of sChat, licensed under the MIT License.
3+
* Copyright (C) Silthus <https://www.github.com/silthus>
4+
* Copyright (C) sChat team and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.silthus.schat.ui.views.tabbed;
26+
27+
import lombok.Getter;
28+
import lombok.Setter;
29+
import lombok.experimental.Accessors;
30+
import net.kyori.adventure.text.Component;
31+
import net.silthus.schat.channel.Channel;
32+
import net.silthus.schat.message.Message;
33+
import net.silthus.schat.ui.format.Format;
34+
import net.silthus.schat.ui.model.ChatterViewModel;
35+
36+
@Getter
37+
@Setter
38+
@Accessors(fluent = true)
39+
public class ChannelTab extends AbstractTab {
40+
private final Channel channel;
41+
42+
private Format activeFormat;
43+
private Format inactiveFormat;
44+
45+
protected ChannelTab(TabbedChannelsView view, Channel channel, Format messageFormat, Format activeFormat, Format inactiveFormat) {
46+
super(view, messageFormat);
47+
this.channel = channel;
48+
49+
this.activeFormat = activeFormat;
50+
this.inactiveFormat = inactiveFormat;
51+
}
52+
53+
@Override
54+
public Component renderName() {
55+
if (isActive())
56+
return activeFormat().format(view(), channel());
57+
else
58+
return inactiveFormat().format(view(), channel());
59+
}
60+
61+
@Override
62+
public boolean isActive() {
63+
return view().viewModel().isActiveChannel(channel());
64+
}
65+
66+
@Override
67+
protected boolean isMessageDisplayed(Message message) {
68+
final ChatterViewModel viewModel = view().viewModel();
69+
if (viewModel.noActiveChannel() && viewModel.isSystemMessage(message))
70+
return true;
71+
if (viewModel.isPrivateChannel())
72+
return viewModel.isSentToActiveChannel(message) && !viewModel.isSystemMessage(message);
73+
return viewModel.isSystemMessage(message) || viewModel.isSentToActiveChannel(message);
74+
}
75+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* This file is part of sChat, licensed under the MIT License.
3+
* Copyright (C) Silthus <https://www.github.com/silthus>
4+
* Copyright (C) sChat team and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.silthus.schat.ui.views.tabbed;
26+
27+
import net.kyori.adventure.text.Component;
28+
import net.silthus.schat.message.Message;
29+
import net.silthus.schat.ui.format.Format;
30+
31+
import static net.kyori.adventure.text.Component.translatable;
32+
import static net.kyori.adventure.text.format.NamedTextColor.RED;
33+
34+
public class NoChannelsTab extends AbstractTab {
35+
36+
protected NoChannelsTab(TabbedChannelsView view, Format messageFormat) {
37+
super(view, messageFormat);
38+
}
39+
40+
@Override
41+
protected boolean isMessageDisplayed(Message message) {
42+
return message.type() == Message.Type.SYSTEM;
43+
}
44+
45+
@Override
46+
public Component renderName() {
47+
return translatable("schat.view.no-channels").color(RED);
48+
}
49+
50+
@Override
51+
public boolean isActive() {
52+
return true;
53+
}
54+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This file is part of sChat, licensed under the MIT License.
3+
* Copyright (C) Silthus <https://www.github.com/silthus>
4+
* Copyright (C) sChat team and contributors
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.silthus.schat.ui.views.tabbed;
26+
27+
import net.kyori.adventure.text.Component;
28+
29+
public interface Tab {
30+
31+
Component renderName();
32+
33+
Component renderContent();
34+
35+
boolean isActive();
36+
}

0 commit comments

Comments
 (0)