working on event handlers for mobile devices

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2025-11-28 20:38:45 +01:00
parent 59f864d16f
commit 600b0f2cf4
3 changed files with 66 additions and 26 deletions

View File

@@ -41,7 +41,7 @@ subprojects {
testImplementation(platform("org.junit:junit-bom:5.10.0")) testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter") testImplementation("org.junit.jupiter:junit-jupiter")
implementation("de.srsoftware:configuration.api:1.0.2") implementation("de.srsoftware:configuration.api:1.0.2")
implementation("de.srsoftware:tools.jdbc:2.0.2") implementation("de.srsoftware:tools.jdbc:2.0.3")
implementation("de.srsoftware:tools.http:6.0.5") implementation("de.srsoftware:tools.http:6.0.5")
implementation("de.srsoftware:tools.mime:1.1.3") implementation("de.srsoftware:tools.mime:1.1.3")
implementation("de.srsoftware:tools.logging:1.3.2") implementation("de.srsoftware:tools.logging:1.3.2")

View File

@@ -16,17 +16,15 @@
let router = useTinyRouter(); let router = useTinyRouter();
let sorted = $derived(tasks ? Object.values(tasks).filter(noNoIndex).sort(byName) : null); let sorted = $derived(tasks ? Object.values(tasks).filter(noNoIndex).sort(byName) : null);
let start = 0;
let x = 0;
let y = 0;
function byName(a,b){ function byName(a,b){
return a.name.localeCompare(b.name); return a.name.localeCompare(b.name);
} }
function close(e,task){
e.stopPropagation();
e.preventDefault();
update(task,60);
}
function goTag(e,newTag){ function goTag(e,newTag){
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@@ -39,9 +37,8 @@
const url = api(`task/tagged/${tag}`); const url = api(`task/tagged/${tag}`);
const res = await get(url); const res = await get(url);
if (res.ok){ if (res.ok){
tasks = await res.json();
console.log(Object.values(tasks).map(t => t.name));
yikes(); yikes();
tasks = await res.json();
input.focus(); input.focus();
} else error(res); } else error(res);
} }
@@ -50,6 +47,12 @@
return !task.no_index; return !task.no_index;
} }
function ignore(evt){
evt.preventDefault();
evt.stopPropagation();
return false;
}
function extend(e,task){ function extend(e,task){
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@@ -57,10 +60,47 @@
return false; return false;
} }
function open(e,task){
e.stopPropagation(); function getTask(evt){
e.preventDefault(); var link = evt.target;
update(task,20); var id = link.getAttribute('task_id');
return tasks[id];
}
function onclick(evt) {
let task = getTask(evt);
if (task.status <= 20) { // open
update(task,60);
} else update(task,20);
return ignore(evt);
}
function oncontextmenu(evt) {
highlight = getTask(evt);
return ignore(evt);
}
function ontouchstart(evt){
start = evt.timeStamp;
x = evt.touches[0].clientX;
y = evt.touches[0].clientY;
return ignore(evt);
}
function ontouchend(evt){
let d = Math.abs(x - evt.changedTouches[0].clientX) + Math.abs(y - evt.changedTouches[0].clientY);
measured(evt, evt.timeStamp - start, d);
return ignore(evt);
}
function measured(evt,duration,d){
if (d > 100) return;
if (duration < 500){
onclick(evt);
} else {
oncontextmenu(evt);
}
} }
async function update(task,newState){ async function update(task,newState){
@@ -87,7 +127,7 @@
{#if sorted} {#if sorted}
{#each sorted as task} {#each sorted as task}
{#if task.status == 20 && (!filter || task.name.toLowerCase().includes(search))} {#if task.status == 20 && (!filter || task.name.toLowerCase().includes(search))}
<a href={`/task/${task.id}/view`} title={task.description.source} onclick={e => close(e,task)} oncontextmenu={e => extend(e,task)} > <a href={`/task/${task.id}/view`} title={task.description.source} task_id={task.id} {onclick} {oncontextmenu} {ontouchstart} {ontouchend} >
{task.name} {task.name}
</a> </a>
{#if highlight == task} {#if highlight == task}
@@ -103,7 +143,7 @@
{#if sorted} {#if sorted}
{#each sorted as task} {#each sorted as task}
{#if task.status > 20 && (!filter || task.name.toLowerCase().includes(search))} {#if task.status > 20 && (!filter || task.name.toLowerCase().includes(search))}
<a href={`/task/${task.id}/view`} title={task.description.source} onclick={e => open(e,task)} oncontextmenu={e => extend(e,task)} > <a href={`/task/${task.id}/view`} title={task.description.source} task_id={task.id} {onclick} {oncontextmenu} {ontouchstart} {ontouchend} >
{task.name} {task.name}
</a> </a>
{#if highlight == task} {#if highlight == task}

View File

@@ -204,10 +204,10 @@ CREATE TABLE IF NOT EXISTS {0} (
public String delete(long userId, String module, long entityId, String tag) { public String delete(long userId, String module, long entityId, String tag) {
try { try {
Query.delete().from(TABLE_TAGS) Query.delete().from(TABLE_TAGS)
.where(TAG,equal(tag)).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,equal(userId)) .where(TAG,iEqual(tag)).where(MODULE,iEqual(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,equal(userId))
.execute(db); .execute(db);
Query.delete().from(TABLE_TAGS) Query.delete().from(TABLE_TAGS)
.where(TAG,equal(tag)).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,isNull()) .where(TAG,iEqual(tag)).where(MODULE,iEqual(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,isNull())
.execute(db); .execute(db);
return tag; return tag;
} catch (SQLException e){ } catch (SQLException e){
@@ -219,7 +219,7 @@ CREATE TABLE IF NOT EXISTS {0} (
public void deleteEntity(String module, long entityId) { public void deleteEntity(String module, long entityId) {
try { try {
Query.delete().from(TABLE_TAGS) Query.delete().from(TABLE_TAGS)
.where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)) .where(MODULE,iEqual(module)).where(ENTITY_ID,equal(entityId))
.execute(db); .execute(db);
} catch (SQLException e){ } catch (SQLException e){
throw new UmbrellaException("Failed to save tags ({0} {1})",module,entityId); throw new UmbrellaException("Failed to save tags ({0} {1})",module,entityId);
@@ -229,7 +229,7 @@ CREATE TABLE IF NOT EXISTS {0} (
@Override @Override
public Map<String, List<Long>> getUses(String tag, long userId) { public Map<String, List<Long>> getUses(String tag, long userId) {
try { try {
var rs = select(ALL).from(TABLE_TAGS).where(TAG,equal(tag)).where(USER_ID,equal(userId)).exec(db); var rs = select(ALL).from(TABLE_TAGS).where(TAG,iEqual(tag)).where(USER_ID,equal(userId)).exec(db);
var result = new HashMap<String,List<Long>>(); var result = new HashMap<String,List<Long>>();
while (rs.next()){ while (rs.next()){
var module = rs.getString(MODULE); var module = rs.getString(MODULE);
@@ -237,7 +237,7 @@ CREATE TABLE IF NOT EXISTS {0} (
result.computeIfAbsent(module, k -> new ArrayList<>()).add(entityId); result.computeIfAbsent(module, k -> new ArrayList<>()).add(entityId);
} }
rs.close(); rs.close();
rs = select(ALL).from(TABLE_TAGS).where(TAG,equal(tag)).where(USER_ID,isNull()).exec(db); rs = select(ALL).from(TABLE_TAGS).where(TAG,iEqual(tag)).where(USER_ID,isNull()).exec(db);
while (rs.next()){ while (rs.next()){
var module = rs.getString(MODULE); var module = rs.getString(MODULE);
var entityId = rs.getLong(ENTITY_ID); var entityId = rs.getLong(ENTITY_ID);
@@ -256,12 +256,12 @@ CREATE TABLE IF NOT EXISTS {0} (
var tags = new HashSet<String>(); var tags = new HashSet<String>();
// load tags assigned to user // load tags assigned to user
var rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,equal(userId)).exec(db); var rs = select(TAG).from(TABLE_TAGS).where(MODULE,iEqual(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,equal(userId)).exec(db);
while (rs.next()) tags.add(rs.getString(1)); while (rs.next()) tags.add(rs.getString(1));
rs.close(); rs.close();
// load tags assigned to no user // load tags assigned to no user
rs = select(TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,isNull()).exec(db); rs = select(TAG).from(TABLE_TAGS).where(MODULE,iEqual(module)).where(ENTITY_ID,equal(entityId)).where(USER_ID,isNull()).exec(db);
while (rs.next()) tags.add(rs.getString(1)); while (rs.next()) tags.add(rs.getString(1));
rs.close(); rs.close();
return tags; return tags;
@@ -294,12 +294,12 @@ CREATE TABLE IF NOT EXISTS {0} (
var tags = new HashMap<Long,HashSet<String>>(); var tags = new HashMap<Long,HashSet<String>>();
// load tags assigned to user // load tags assigned to user
var rs = select(ENTITY_ID,TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,in(entityIds.toArray())).where(USER_ID,equal(userId)).exec(db); var rs = select(ENTITY_ID,TAG).from(TABLE_TAGS).where(MODULE,iEqual(module)).where(ENTITY_ID,in(entityIds.toArray())).where(USER_ID,equal(userId)).exec(db);
while (rs.next()) tags.computeIfAbsent(rs.getLong(ENTITY_ID), k -> new HashSet<>()).add(rs.getString(TAG)); while (rs.next()) tags.computeIfAbsent(rs.getLong(ENTITY_ID), k -> new HashSet<>()).add(rs.getString(TAG));
rs.close(); rs.close();
// load tags assigned to no user // load tags assigned to no user
rs = select(ENTITY_ID,TAG).from(TABLE_TAGS).where(MODULE,equal(module)).where(ENTITY_ID,in(entityIds.toArray())).where(USER_ID,isNull()).exec(db); rs = select(ENTITY_ID,TAG).from(TABLE_TAGS).where(MODULE,iEqual(module)).where(ENTITY_ID,in(entityIds.toArray())).where(USER_ID,isNull()).exec(db);
while (rs.next()) tags.computeIfAbsent(rs.getLong(ENTITY_ID), k -> new HashSet<>()).add(rs.getString(TAG)); while (rs.next()) tags.computeIfAbsent(rs.getLong(ENTITY_ID), k -> new HashSet<>()).add(rs.getString(TAG));
rs.close(); rs.close();
return tags; return tags;
@@ -328,7 +328,7 @@ CREATE TABLE IF NOT EXISTS {0} (
@Override @Override
public void updateId(String module, Object oldId, Object newId) { public void updateId(String module, Object oldId, Object newId) {
try { try {
update(TABLE_TAGS).set(ENTITY_ID).where(MODULE,equal(module)).where(ENTITY_ID,equal(oldId)).prepare(db).apply(newId).close(); update(TABLE_TAGS).set(ENTITY_ID).where(MODULE,iEqual(module)).where(ENTITY_ID,equal(oldId)).prepare(db).apply(newId).close();
LOG.log(DEBUG,"Updated tag @ {0}.{1} → {0}.{2}",module,oldId,newId); LOG.log(DEBUG,"Updated tag @ {0}.{1} → {0}.{2}",module,oldId,newId);
} catch (SQLException e) { } catch (SQLException e) {
throw databaseException("Failed to update {0}.{1} → {0}.{2}",module,oldId,newId); throw databaseException("Failed to update {0}.{1} → {0}.{2}",module,oldId,newId);