From ddf81f15ddc0a179c6776eb749e981e616aa887c Mon Sep 17 00:00:00 2001 From: twisti-dev <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 3 Jun 2026 19:33:51 +0200 Subject: [PATCH 1/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(pagination):?= =?UTF-8?q?=20trigger=20pagination=20state=20update=20on=20view=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - call pagination.switchTo with currentPage to refresh dynamic elements --- .../framework/view/pagination/AbstractPaginatedSurfView.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt index 60f4977e6..bb7860f5d 100644 --- a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt @@ -217,6 +217,9 @@ abstract class AbstractPaginatedSurfView(header: String) : AbstractSurfView(head final override fun onViewUpdate(update: Context) { + val pagination = paginationState.get(update) + pagination.switchTo(pagination.currentPage()) // trigger pagination state update to refresh dynamic elements + onPaginatedUpdate(update) } From 01b1f41ffe362ca76f26eff73e60a7fc5f76d0cd Mon Sep 17 00:00:00 2001 From: twisti-dev <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 3 Jun 2026 19:56:17 +0200 Subject: [PATCH 2/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(pagination):?= =?UTF-8?q?=20update=20pagination=20state=20handling=20for=20static=20view?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change pagination state update logic to handle static views differently - use player scheduler for updating pagination glyphs in static mode --- .../pagination/AbstractPaginatedSurfView.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt index bb7860f5d..b726025c0 100644 --- a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt @@ -1,8 +1,5 @@ package dev.slne.surf.api.paper.inventory.framework.view.pagination -import com.github.shynixn.mccoroutine.folia.entityDispatcher -import com.github.shynixn.mccoroutine.folia.launch -import com.github.shynixn.mccoroutine.folia.ticks import dev.slne.surf.api.core.util.prepend import dev.slne.surf.api.paper.inventory.framework.view.AbstractSurfView import dev.slne.surf.api.paper.inventory.framework.view.container.dsl.ViewContainerModificationContext @@ -10,7 +7,6 @@ import dev.slne.surf.api.paper.inventory.framework.view.container.dsl.addChild import dev.slne.surf.api.paper.inventory.framework.view.container.dsl.blockCell import dev.slne.surf.api.paper.inventory.framework.view.container.dsl.removeChildrenOfType import dev.slne.surf.api.paper.inventory.framework.view.settings.PaginatedViewSettings -import kotlinx.coroutines.delay import me.devnatan.inventoryframework.ViewConfigBuilder import me.devnatan.inventoryframework.component.BukkitItemComponentBuilder import me.devnatan.inventoryframework.component.Pagination @@ -190,7 +186,13 @@ abstract class AbstractPaginatedSurfView(header: String) : AbstractSurfView(head val pagination = paginationState.get(render) ?: return val paginationButtonRow = settings.paginationButtonRow - render.watchState(pagination.id, InitialPaginationStateWatcher()) + if (pagination.isStatic) { + render.player.scheduler.run(JavaPlugin.getProvidingPlugin(javaClass), { + updatePaginationGlyph(render) + }, null) + } else { + render.watchState(pagination.id, InitialPaginationStateWatcher()) + } render.slot(PaginationButton.LEFT.clickSlot(paginationButtonRow)) .withItem(ItemStack.empty()) @@ -247,11 +249,9 @@ abstract class AbstractPaginatedSurfView(header: String) : AbstractSurfView(head if (!initialHandled.compareAndSet(false, true)) return if (host !is Context) return - val plugin = JavaPlugin.getProvidingPlugin(javaClass) - plugin.launch(plugin.entityDispatcher(host.player)) { - delay(1.ticks) + host.player.scheduler.run(JavaPlugin.getProvidingPlugin(javaClass), { updatePaginationGlyph(host) - } + }, null) } } From a0516e08b5c6954dcd8312a703577340d95b66f9 Mon Sep 17 00:00:00 2001 From: twisti-dev <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 3 Jun 2026 20:26:51 +0200 Subject: [PATCH 3/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(view):=20impl?= =?UTF-8?q?ement=20view=20navigation=20history=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add ViewNavigationHistory to track navigation state - update onOpen and onClose methods to manage history - refactor handleOutsideClick to utilize navigation history --- .../framework/view/AbstractSurfView.kt | 47 ++++++++++--------- .../framework/view/ViewNavigationHistory.kt | 41 ++++++++++++++++ 2 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/ViewNavigationHistory.kt diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/AbstractSurfView.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/AbstractSurfView.kt index 0723be608..8a40c5718 100644 --- a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/AbstractSurfView.kt +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/AbstractSurfView.kt @@ -9,12 +9,10 @@ import dev.slne.surf.api.paper.inventory.framework.view.container.dsl.addChild import dev.slne.surf.api.paper.inventory.framework.view.container.dsl.backHint import dev.slne.surf.api.paper.inventory.framework.view.settings.SimpleViewSettings import dev.slne.surf.api.paper.inventory.framework.view.settings.SurfViewSettings -import dev.slne.surf.api.paper.inventory.framework.viewFrame import me.devnatan.inventoryframework.View import me.devnatan.inventoryframework.ViewConfigBuilder import me.devnatan.inventoryframework.ViewType import me.devnatan.inventoryframework.context.* -import org.bukkit.plugin.java.JavaPlugin /** * Abstract base class for all Surf inventory views built on top of the inventory framework. @@ -145,7 +143,7 @@ abstract class AbstractSurfView( ViewContainerTitleComponent( title = defaultHeader, font = settings.font, - charSpacing = ViewContainerTitleComponent.Companion.CHAR_SPACING, + charSpacing = ViewContainerTitleComponent.CHAR_SPACING, textAlignment = settings.headerTextAlignment ) ) @@ -183,10 +181,22 @@ abstract class AbstractSurfView( } final override fun onOpen(open: OpenContext) { + recordHistory(open) applyContainerDefaults(open) onViewOpen(open) } + private fun recordHistory(open: OpenContext) { + val player = open.player + val entry = ViewNavigationHistory.NavEntry(javaClass, open.initialData) + + when { + ViewNavigationHistory.consumeBackNavigation(player) -> Unit + open.viewer.isSwitching -> ViewNavigationHistory.pushForward(player, entry) + else -> ViewNavigationHistory.reset(player, entry) + } + } + final override fun onFirstRender(render: RenderContext) { onViewRender(render) } @@ -201,6 +211,10 @@ abstract class AbstractSurfView( } final override fun onClose(close: CloseContext) { + val player = close.player + if (!close.viewer.isSwitching && !ViewNavigationHistory.isPending(player.uniqueId)) { + ViewNavigationHistory.clear(player) + } onViewClose(close) } @@ -209,27 +223,16 @@ abstract class AbstractSurfView( } private fun handleOutsideClick(click: SlotClickContext) { - val viewer = click.viewer - val previousContext = viewer.previousContext + val player = click.player + val target = ViewNavigationHistory.popToPrevious(player) - if (previousContext == null) { + if (target == null) { + ViewNavigationHistory.clear(player) click.closeForPlayer() - } else { - val previousView = previousContext.root - if (previousView !is View) { - click.closeForPlayer() - return - } - - val player = click.player - val previousState = viewer.previousContext.initialData - - viewer.previousContext = null - click.closeForPlayer() - - player.scheduler.run(JavaPlugin.getProvidingPlugin(javaClass), { - viewFrame.open(previousView.javaClass, player, previousState) - }, null) + return } + + ViewNavigationHistory.markBackNavigation(player) + click.openForPlayer(target.viewClass, target.data) } } \ No newline at end of file diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/ViewNavigationHistory.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/ViewNavigationHistory.kt new file mode 100644 index 000000000..0d93a0f9d --- /dev/null +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/ViewNavigationHistory.kt @@ -0,0 +1,41 @@ +package dev.slne.surf.api.paper.inventory.framework.view + +import me.devnatan.inventoryframework.View +import org.bukkit.entity.Player +import java.util.UUID +import java.util.concurrent.ConcurrentHashMap +import kotlin.collections.ArrayDeque + +internal object ViewNavigationHistory { + private val paths = ConcurrentHashMap>() + private val backNav = ConcurrentHashMap.newKeySet() + + private fun deque(player: Player) = paths.computeIfAbsent(player.uniqueId) { ArrayDeque() } + + fun reset(player: Player, entry: NavEntry) { + val deque = deque(player) + deque.clear() + deque.addLast(entry) + } + + fun pushForward(player: Player, entry: NavEntry) = deque(player).addLast(entry) + + fun markBackNavigation(player: Player) = backNav.add(player.uniqueId) + + fun consumeBackNavigation(player: Player) = backNav.remove(player.uniqueId) + + fun popToPrevious(player: Player): NavEntry? { + val deque = paths[player.uniqueId] ?: return null + deque.removeLastOrNull() + return deque.lastOrNull() + } + + fun isPending(uuid: UUID): Boolean = backNav.contains(uuid) + + fun clear(player: Player) { + paths.remove(player.uniqueId) + backNav.remove(player.uniqueId) + } + + internal data class NavEntry(val viewClass: Class, val data: Any?) +} \ No newline at end of file From adb9c4138be43865c5bd11b78b275fc9c1cb5e8c Mon Sep 17 00:00:00 2001 From: twisti-dev <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 3 Jun 2026 20:27:51 +0200 Subject: [PATCH 4/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(pagination):?= =?UTF-8?q?=20update=20pagination=20state=20handling=20to=20use=20currentP?= =?UTF-8?q?ageIndex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change pagination state update method from currentPage() to currentPageIndex() - ensure dynamic elements refresh correctly on view updates --- .../framework/view/pagination/AbstractPaginatedSurfView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt index b726025c0..f2827eba5 100644 --- a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt @@ -220,7 +220,7 @@ abstract class AbstractPaginatedSurfView(header: String) : AbstractSurfView(head final override fun onViewUpdate(update: Context) { val pagination = paginationState.get(update) - pagination.switchTo(pagination.currentPage()) // trigger pagination state update to refresh dynamic elements + pagination.switchTo(pagination.currentPageIndex()) // trigger pagination state update to refresh dynamic elements onPaginatedUpdate(update) } From b8f4ab98a1aeab23828fbc967b7dee5ff5882792 Mon Sep 17 00:00:00 2001 From: twisti-dev <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 3 Jun 2026 20:28:09 +0200 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=94=A7=20chore:=20update=20version=20?= =?UTF-8?q?to=203.17.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e4934ece5..ead2e85bf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled javaVersion=25 mcVersion=26.1.2 group=dev.slne.surf.api -version=3.17.1 +version=3.17.2 relocationPrefix=dev.slne.surf.api.libs snapshot=false From 3e17798fd42279fbc6208449a7ca1290c38230e4 Mon Sep 17 00:00:00 2001 From: twisti-dev <76837088+twisti-dev@users.noreply.github.com> Date: Wed, 3 Jun 2026 22:36:22 +0200 Subject: [PATCH 6/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(pagination):?= =?UTF-8?q?=20add=20null=20check=20before=20switching=20pagination=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ensure pagination object is not null before calling switchTo on currentPageIndex --- .../framework/view/pagination/AbstractPaginatedSurfView.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt index f2827eba5..767e6fe54 100644 --- a/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt +++ b/surf-api-paper/surf-api-paper/src/main/kotlin/dev/slne/surf/api/paper/inventory/framework/view/pagination/AbstractPaginatedSurfView.kt @@ -220,7 +220,9 @@ abstract class AbstractPaginatedSurfView(header: String) : AbstractSurfView(head final override fun onViewUpdate(update: Context) { val pagination = paginationState.get(update) - pagination.switchTo(pagination.currentPageIndex()) // trigger pagination state update to refresh dynamic elements + if (pagination != null) { + pagination.switchTo(pagination.currentPageIndex()) // trigger pagination state update to refresh dynamic elements + } onPaginatedUpdate(update) }