adding TheCard preview
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+4120
-71
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+105
-15
@@ -4139,14 +4139,15 @@ TheCard.exportVCard = function (card) {
|
||||
}
|
||||
if (Array.isArray(card.comm)) {
|
||||
card.comm.forEach(comm => {
|
||||
const types = comm.des.join(',').toUpperCase();
|
||||
if (comm.proto === 'tel') {
|
||||
vcard += `TEL;TYPE=${comm.des.toUpperCase()}:${comm.value}\r\n`;
|
||||
vcard += `TEL;TYPE=${types}:${comm.value}\r\n`;
|
||||
} else if (comm.proto === 'email') {
|
||||
vcard += `EMAIL;TYPE=${comm.des.toUpperCase()}:${comm.value}\r\n`;
|
||||
vcard += `EMAIL;TYPE=${types}:${comm.value}\r\n`;
|
||||
} else if (comm.proto === 'tinode') {
|
||||
vcard += `IMPP;TYPE=${comm.des.toUpperCase()};tinode:${comm.value}\r\n`;
|
||||
vcard += `IMPP;TYPE=${types};tinode:${comm.value}\r\n`;
|
||||
} else if (comm.proto === 'http') {
|
||||
vcard += `URL;TYPE=${comm.des.toUpperCase()}:${comm.value}\r\n`;
|
||||
vcard += `URL;TYPE=${types}:${comm.value}\r\n`;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -4157,8 +4158,25 @@ TheCard.importVCard = function (vcardStr) {
|
||||
if (!vcardStr || typeof vcardStr !== 'string') {
|
||||
return null;
|
||||
}
|
||||
const lines = vcardStr.split(/\r\n|\n/);
|
||||
const rawLines = vcardStr.split(/\r\n|\n/);
|
||||
const lines = [];
|
||||
let currentLine = '';
|
||||
for (let i = 0; i < rawLines.length; i++) {
|
||||
const line = rawLines[i];
|
||||
if (line.startsWith(' ') || line.startsWith('\t')) {
|
||||
currentLine += line.substring(1);
|
||||
} else {
|
||||
if (currentLine) {
|
||||
lines.push(currentLine);
|
||||
}
|
||||
currentLine = line;
|
||||
}
|
||||
}
|
||||
if (currentLine) {
|
||||
lines.push(currentLine);
|
||||
}
|
||||
let card = {};
|
||||
const commMap = new Map();
|
||||
lines.forEach(line => {
|
||||
const [keyPart, ...valueParts] = line.split(':');
|
||||
if (!keyPart || valueParts.length === 0) {
|
||||
@@ -4219,21 +4237,83 @@ TheCard.importVCard = function (vcardStr) {
|
||||
};
|
||||
}
|
||||
} else if (key === 'TEL') {
|
||||
const des = keyPart.split(';').find(param => param.trim().toUpperCase().startsWith('TYPE='))?.split('=')[1].trim().toLowerCase() || 'voice';
|
||||
card = TheCard.addPhone(card, value, des);
|
||||
const typeParams = keyPart.split(';').filter(param => param.trim().toUpperCase().startsWith('TYPE='));
|
||||
const types = typeParams.flatMap(param => {
|
||||
const equalIndex = param.indexOf('=');
|
||||
const valuesPart = param.substring(equalIndex + 1);
|
||||
return valuesPart.split(',').map(t => {
|
||||
const cleaned = t.trim().toLowerCase();
|
||||
return cleaned.startsWith('type=') ? cleaned.substring(5) : cleaned;
|
||||
});
|
||||
}).filter(t => t !== 'internet');
|
||||
const mapKey = `tel|${value}`;
|
||||
if (!commMap.has(mapKey)) {
|
||||
commMap.set(mapKey, new Set());
|
||||
}
|
||||
types.forEach(t => commMap.get(mapKey).add(t));
|
||||
} else if (key === 'EMAIL') {
|
||||
const des = keyPart.split(';').find(param => param.trim().toUpperCase().startsWith('TYPE='))?.split('=')[1].trim().toLowerCase() || 'home';
|
||||
card = TheCard.addEmail(card, value, des);
|
||||
const typeParams = keyPart.split(';').filter(param => param.trim().toUpperCase().startsWith('TYPE='));
|
||||
const types = typeParams.flatMap(param => {
|
||||
const equalIndex = param.indexOf('=');
|
||||
const valuesPart = param.substring(equalIndex + 1);
|
||||
return valuesPart.split(',').map(t => {
|
||||
const cleaned = t.trim().toLowerCase();
|
||||
return cleaned.startsWith('type=') ? cleaned.substring(5) : cleaned;
|
||||
});
|
||||
}).filter(t => t !== 'internet');
|
||||
const mapKey = `email|${value}`;
|
||||
if (!commMap.has(mapKey)) {
|
||||
commMap.set(mapKey, new Set());
|
||||
}
|
||||
types.forEach(t => commMap.get(mapKey).add(t));
|
||||
} else if (key === 'IMPP') {
|
||||
const des = keyPart.split(';').find(param => param.trim().toUpperCase().startsWith('TYPE='))?.split('=')[1].trim().toLowerCase() || 'home';
|
||||
const typeParams = keyPart.split(';').filter(param => param.trim().toUpperCase().startsWith('TYPE='));
|
||||
const types = typeParams.flatMap(param => {
|
||||
const equalIndex = param.indexOf('=');
|
||||
const valuesPart = param.substring(equalIndex + 1);
|
||||
return valuesPart.split(',').map(t => {
|
||||
const cleaned = t.trim().toLowerCase();
|
||||
return cleaned.startsWith('type=') ? cleaned.substring(5) : cleaned;
|
||||
});
|
||||
}).filter(t => t !== 'internet');
|
||||
const tinodeID = value.replace(/^tinode:/, '');
|
||||
card = TheCard.addTinodeID(card, tinodeID, des);
|
||||
const mapKey = `tinode|${tinodeID}`;
|
||||
if (!commMap.has(mapKey)) {
|
||||
commMap.set(mapKey, new Set());
|
||||
}
|
||||
types.forEach(t => commMap.get(mapKey).add(t));
|
||||
} else if (key === 'URL') {
|
||||
const typeParams = keyPart.split(';').filter(param => param.trim().toUpperCase().startsWith('TYPE='));
|
||||
const types = typeParams.flatMap(param => {
|
||||
const equalIndex = param.indexOf('=');
|
||||
const valuesPart = param.substring(equalIndex + 1);
|
||||
return valuesPart.split(',').map(t => {
|
||||
const cleaned = t.trim().toLowerCase();
|
||||
return cleaned.startsWith('type=') ? cleaned.substring(5) : cleaned;
|
||||
});
|
||||
}).filter(t => t !== 'internet');
|
||||
const mapKey = `http|${value}`;
|
||||
if (!commMap.has(mapKey)) {
|
||||
commMap.set(mapKey, new Set());
|
||||
}
|
||||
types.forEach(t => commMap.get(mapKey).add(t));
|
||||
}
|
||||
});
|
||||
if (commMap.size > 0) {
|
||||
card.comm = [];
|
||||
commMap.forEach((types, key) => {
|
||||
const [proto, value] = key.split('|', 2);
|
||||
card.comm.push({
|
||||
proto: proto,
|
||||
des: Array.from(types),
|
||||
value: value
|
||||
});
|
||||
});
|
||||
}
|
||||
return card;
|
||||
};
|
||||
TheCard.isFileSupported = function (type, name) {
|
||||
return type == 'text/vcard' || (name || '').endsWith('.vcf') || (name || '').endsWith('.vcard');
|
||||
return type == 'text/vcard' || (name || '').endsWith('.vcf') || (name || '').endsWith('.vcr') || (name || '').endsWith('.vcard');
|
||||
};
|
||||
function theCard(fn, imageUrl, imageMimeType, note) {
|
||||
let card = null;
|
||||
@@ -4275,11 +4355,14 @@ function addOrSetComm(card, proto, value, type, setOnly) {
|
||||
card = card || {};
|
||||
card.comm = card.comm || [];
|
||||
if (setOnly) {
|
||||
card.comm = card.comm.filter(c => !(c.proto == proto && c.des == type));
|
||||
card.comm = card.comm.filter(c => {
|
||||
if (c.proto != proto) return true;
|
||||
return !c.des.includes(type);
|
||||
});
|
||||
}
|
||||
card.comm.push({
|
||||
proto: proto,
|
||||
des: type,
|
||||
des: [type],
|
||||
value: value
|
||||
});
|
||||
}
|
||||
@@ -4287,7 +4370,14 @@ function addOrSetComm(card, proto, value, type, setOnly) {
|
||||
}
|
||||
function clearComm(card, proto, value, type) {
|
||||
if (card && Array.isArray(card.comm)) {
|
||||
card.comm = card.comm.filter(c => !(c.proto == proto && (!type || c.des == type) && (!value || c.value == value)));
|
||||
card.comm = card.comm.filter(c => {
|
||||
if (c.proto != proto) return true;
|
||||
if (value && c.value != value) return true;
|
||||
if (type) {
|
||||
return !c.des.includes(type);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2687
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user