working on address card editor
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
href = '#',
|
||||
onclick = evt => { evt.preventDefault(); startEdit(); return false },
|
||||
onSet = newVal => {return true;},
|
||||
title = t('long_click_to_edit'),
|
||||
type = 'div',
|
||||
value = $bindable(null)
|
||||
} = $props();
|
||||
@@ -103,5 +104,5 @@
|
||||
{#if editable && editing}
|
||||
<input bind:value={editValue} onkeyup={typed} autofocus />
|
||||
{:else}
|
||||
<svelte:element this={type} href={href} onclick={ignore} {onmousedown} {onmouseup} {ontouchstart} {ontouchend} {oncontextmenu} class={{editable}} title={t('long_click_to_edit')} >{value}</svelte:element>
|
||||
<svelte:element this={type} href={href} onclick={ignore} {onmousedown} {onmouseup} {ontouchstart} {ontouchend} {oncontextmenu} class={{editable}} {title} >{value}</svelte:element>
|
||||
{/if}
|
||||
|
||||
@@ -1,31 +1,46 @@
|
||||
<script>
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
import { addr } from '../../vcard.js';
|
||||
import { t } from '../../translations.svelte';
|
||||
|
||||
let { code } = $props();
|
||||
let { code, patch = (from, to) => true } = $props();
|
||||
|
||||
let address = $derived(addr(code));
|
||||
let home = $derived(code.toLowerCase().includes('type=home'));
|
||||
let work = $derived(code.toLowerCase().includes('type=work'));
|
||||
|
||||
function onSet(oldVal,newVal){
|
||||
const newCode = code.replace(oldVal,newVal);
|
||||
return patch(code,newCode);
|
||||
}
|
||||
|
||||
function toggleHome(){
|
||||
toggleType('HOME');
|
||||
}
|
||||
|
||||
function toggleType(key){
|
||||
key = key.toUpperCase();
|
||||
if (code.toUpperCase().includes(';TYPE='+key)) {
|
||||
const regex = new RegExp(';TYPE='+key, "ig");
|
||||
patch(code,code.replace(regex,''));
|
||||
} else patch(code,code.replace('ADR','ADR;TYPE='+key));
|
||||
}
|
||||
|
||||
function toggleWork(){
|
||||
toggleType('WORK');
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="address">
|
||||
{#if address.box}
|
||||
<span class="post_box">{address.box}</span>
|
||||
{/if}
|
||||
{#if address.ext}
|
||||
<span class="extended">{address.ext}</span>
|
||||
{/if}
|
||||
{#if address.street}
|
||||
<span class="street">{address.street}</span>
|
||||
{/if}
|
||||
{#if address.code}
|
||||
<span class="code">{address.code}</span>
|
||||
{/if}
|
||||
{#if address.loc}
|
||||
<span class="locality">{address.loc}</span>
|
||||
{/if}
|
||||
{#if address.region}
|
||||
<span class="region">{address.region}</span>
|
||||
{/if}
|
||||
{#if address.country}
|
||||
<span class="country">{address.country}</span>
|
||||
{/if}
|
||||
<div>
|
||||
<span class="symbol {home?'':'inactive'}" onclick={toggleHome}></span>
|
||||
<span class="symbol {work?'':'inactive'}" onclick={toggleWork} ></span>
|
||||
</div>
|
||||
<LineEditor type="span" editable={true} value={address.box} onSet={newVal => onSet(address.box,newVal)} title={t('post_box')} />
|
||||
<LineEditor type="span" editable={true} value={address.ext} onSet={newVal => onSet(address.ext,newVal)} title={t('extended_address')} />
|
||||
<LineEditor type="span" editable={true} value={address.street} onSet={newVal => onSet(address.street,newVal)} title={t('street')} />
|
||||
<LineEditor type="span" editable={true} value={address.code} onSet={newVal => onSet(address.code,newVal)} title={t('post_code')} />
|
||||
<LineEditor type="span" editable={true} value={address.loc} onSet={newVal => onSet(address.loc,newVal)} title={t('locality')} />
|
||||
<LineEditor type="span" editable={true} value={address.region} onSet={newVal => onSet(address.region,newVal)} title={t('region')} />
|
||||
<LineEditor type="span" editable={true} value={address.country} onSet={newVal => onSet(address.country,newVal)} title={t('country')} />
|
||||
</div>
|
||||
@@ -15,12 +15,12 @@
|
||||
|
||||
let addresses = $derived(contact.vcard.match(/^ADR.*:.+$/gm));
|
||||
let code = $state(false);
|
||||
let fns = $derived(contact.vcard.match(/^FN.*:.+$/gm));
|
||||
let emails = $derived(contact.vcard.match(/^EMAIL.*:.+$/gm));
|
||||
let extra_fields = $derived(contact.vcard.match(/^X-.*:.+/gm));
|
||||
let fns = $derived(contact.vcard.match(/^FN.*:.+$/gm));
|
||||
let orgs = $derived(contact.vcard.match(/^ORG.*:.+$/gm));
|
||||
|
||||
async function patch(from,to){
|
||||
console.log(`patch(${contact.id}: ${from} → ${to})`);
|
||||
if (from == to) return;
|
||||
const url = api(`contact/${contact.id}`);
|
||||
const res = await fetch(url,{
|
||||
@@ -64,7 +64,9 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Org vcard={contact.vcard} />
|
||||
{#each orgs as code}
|
||||
<Org {code} {patch} />
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -75,21 +77,21 @@
|
||||
<tr>
|
||||
<td>
|
||||
{#each addresses as code}
|
||||
<Address {code} />
|
||||
<Address {code} {patch} />
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{#each emails as code}
|
||||
<Email {code} />
|
||||
<Email {code} {patch} />
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{#each extra_fields as code}
|
||||
<ExtraField {code} />
|
||||
<ExtraField {code} {patch} />
|
||||
{/each}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,9 +1,37 @@
|
||||
<script>
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
import { email } from '../../vcard.js';
|
||||
|
||||
let { code } = $props();
|
||||
let { code, patch = (from, to) => true } = $props();
|
||||
|
||||
let adr = $derived(email(code));
|
||||
let home = $derived(code.toLowerCase().includes('type=home'));
|
||||
let work = $derived(code.toLowerCase().includes('type=work'));
|
||||
let value = $derived(email(code));
|
||||
|
||||
function onSet(newVal){
|
||||
const newCode = code.replace(value,newVal);
|
||||
return patch(code,newCode);
|
||||
}
|
||||
|
||||
function toggleHome(){
|
||||
toggleType('HOME');
|
||||
}
|
||||
|
||||
function toggleType(key){
|
||||
key = key.toUpperCase();
|
||||
if (code.toUpperCase().includes(';TYPE='+key)) {
|
||||
const regex = new RegExp(';TYPE='+key, "ig");
|
||||
patch(code,code.replace(regex,''));
|
||||
} else patch(code,code.replace('EMAIL','EMAIL;TYPE='+key));
|
||||
}
|
||||
|
||||
function toggleWork(){
|
||||
toggleType('WORK');
|
||||
}
|
||||
</script>
|
||||
|
||||
<span class="email">{adr}</span>
|
||||
{#if value}
|
||||
<span class="symbol {home?'':'inactive'}" onclick={toggleHome}></span>
|
||||
<span class="symbol {work?'':'inactive'}" onclick={toggleWork} ></span>
|
||||
<LineEditor type="span" editable={true} {value} {onSet} /><br/>
|
||||
{/if}
|
||||
@@ -1,14 +1,25 @@
|
||||
<script>
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
import MultiLineEditor from '../../Components/MultilineEditor.svelte';
|
||||
import { extra } from '../../vcard.js';
|
||||
import { t } from '../../translations.svelte';
|
||||
|
||||
let { code } = $props();
|
||||
let { code, patch = (from, to) => true } = $props();
|
||||
|
||||
let field = $derived(extra(code));
|
||||
|
||||
function onSet(newVal){
|
||||
const newCode = code.replace(field.value,newVal.replaceAll('\n','\\n'));
|
||||
return patch(code,newCode);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if field}
|
||||
<span class={field.name}>
|
||||
{field.value}
|
||||
</span>
|
||||
<div class={field.name}>
|
||||
{#if field.value.includes('\\n')}
|
||||
<MultiLineEditor type="div" editable={true} value={field.value.replaceAll('\\n','\n')} {onSet} title={t(field.name)+' – '+t('long_click_to_edit')} />
|
||||
{:else}
|
||||
<LineEditor type="div" editable={true} value={field.value} {onSet} title={t(field.name)+' – '+t('long_click_to_edit')} />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -1,18 +1,18 @@
|
||||
<script>
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
import { fn } from '../../vcard.js';
|
||||
import { t } from '../../translations.svelte';
|
||||
import { t } from '../../translations.svelte';
|
||||
|
||||
let { code, patch = (from, to) => true } = $props();
|
||||
|
||||
let name = $derived(fn(code));
|
||||
let value = $derived(fn(code));
|
||||
|
||||
function onSet(newVal){
|
||||
const newCode = code.replace(name,newVal);
|
||||
const newCode = code.replace(value,newVal);
|
||||
return patch(code,newCode);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if name}
|
||||
<LineEditor type="span" editable={true} value={name} {onSet} />
|
||||
{#if value}
|
||||
<LineEditor type="span" editable={true} {value} {onSet} title={t('formatted_name')}/>
|
||||
{/if}
|
||||
@@ -18,7 +18,6 @@
|
||||
yikes();
|
||||
var data = await res.json();
|
||||
contacts = Object.values(data).sort(byName);
|
||||
console.log(contacts);
|
||||
} else {
|
||||
error(res);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<script>
|
||||
import LineEditor from '../../Components/LineEditor.svelte';
|
||||
import { org } from '../../vcard.js';
|
||||
import { t } from '../../translations.svelte';
|
||||
import { t } from '../../translations.svelte';
|
||||
|
||||
let { vcard } = $props();
|
||||
let { code, patch = (from, to) => true } = $props();
|
||||
|
||||
let o = $derived(org(vcard));
|
||||
let value = $derived(org(code));
|
||||
|
||||
function onSet(newVal){
|
||||
const newCode = code.replace(value,newVal);
|
||||
return patch(code,newCode);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if o}
|
||||
<span class="organization">{o}</span>
|
||||
{#if value}
|
||||
<LineEditor type="span" editable={true} {value} {onSet} title={t('organization')}/>
|
||||
{/if}
|
||||
@@ -28,7 +28,7 @@ export function email(vcard){
|
||||
}
|
||||
|
||||
export function extra(code){
|
||||
const match = code.match(/^X-(.+):(.+)/)
|
||||
const match = code.match(/^X-([^:]+):(.+)/)
|
||||
return match ? {name:match[1],value:match[2]} : null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user