# aardio 范例: mail.tm 临时邮箱



```aardio
import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="mail.tm 临时邮箱";right=759;bottom=550;bgcolor=0xFFFFFF)
winform.add(
btnRefresh={cls="plus";text='\uF021';left=700;top=18;right=740;bottom=52;bgcolor=0xB8A217;color=0xFFFFFF;font=LOGFONT(h=-16;name='FontAwesome');z=4};
btnRegister={cls="plus";text="注册邮箱";left=20;top=18;right=140;bottom=52;bgcolor=0xD47800;color=0xFFFFFF;font=LOGFONT(h=-14);iconStyle={align="left";font=LOGFONT(h=-14;name='FontAwesome');padding={left=12}};iconText='\uF0E0';textPadding={left=35};z=1};
editContent={cls="richedit";left=20;top=413;right=740;bottom=530;edge=1;multiline=1;readonly=1;vscroll=1;z=8};
editEmail={cls="edit";left=150;top=20;right=681;bottom=50;edge=1;readonly=1;z=2};
editToken={cls="edit";left=150;top=56;right=600;bottom=86;edge=1;readonly=1;z=9};
listview={cls="listview";left=20;top=157;right=740;bottom=362;edge=1;fullRow=1;z=6};
staticContent={cls="static";text="邮件内容：";left=20;top=375;right=100;bottom=395;font=LOGFONT(h=-14);transparent=1;z=7};
staticList={cls="static";text="邮件列表：";left=20;top=107;right=100;bottom=127;font=LOGFONT(h=-14);transparent=1;z=5};
staticStatus={cls="static";text="状态：未注册";left=639;top=70;right=740;bottom=90;align="right";color=0x808080;transparent=1;z=3};
staticToken={cls="static";text="令牌:";left=49;top=62;right=140;bottom=88;align="right";transparent=1;z=10}
)
/*}}*/

// 注册并监听邮箱
winform.btnRegister.oncommand = function(){ 
	winform.btnRegister.disabledText = ['\uF254','\uF251','\uF252','\uF253','\uF250']
	
	thread.invoke(
		function(winform, mailState){
			// 调用 mail.tm 接口注册临时邮箱
			import web.rest.jsonClient;
			
			var http = web.rest.jsonClient();
			var mailApi = http.api("https://api.mail.tm/");
			
			// 获取可用域名
			var domainList, err = mailApi.domains.get();
			if(!domainList) return winform.msgboxErr(err); 
			
			var domain = domainList["hydra:member"][1].domain;
			var email = "aardio_" + time.stamp(true/*返回字符串*/,true/*秒*/) + "@" + domain;
			var password = "PWD_"+string.random(15);
		
			// 注册账号
			var account, err = mailApi.accounts.post(
				address = email;
				password = password;
			);
			if(!account)return winform.msgboxErr(err||"注册失败，可能是注册太频繁了！");

			// 获取 token
			var tokenData, err = mailApi.token.post(
				address = email;
				password = password;
			);
			if(!tokenData) return winform.msgboxErr(err);
			
			// 设置 token
			http.setAuthToken(tokenData.token);
			
			winform.editToken.text = tokenData.token;
			winform.editEmail.text = email + ":" + password;

			winform.btnRegister.disabledText =  "已注册"; 
			
			winform.staticStatus.text = "监听中...";
			winform.staticStatus.color = 0x28A745;
			
			// 使用 mercure 协议监听 mail.tm 新邮件（实际上就是 SSE 流）
			var eventSource = http.api("https://mercure.mail.tm/.well-known/mercure");

			// 参数 2 指定 SSE 回调函数就会自动切换到 SSE 模式
			var ok,err = eventSource.get(
				{ topic = "/accounts/" + account.id}
				, function(sseMessage){
					var data = sseMessage.data;
					
					//data 可能是数值（新邮件数）或对象（邮件信息）
					if(data[["@context"]]=="/contexts/Message"){
						var mail = data;
						
						winform.listview.addItem([
							mail.from.address,
							mail.subject || mail.intro,
							time.iso8601(mail.createdAt).format("%Y/%m/%d %H:%M:%S"), 
							mail.id
						]);
						
						/*
						http 对象已进入流模式，
						如果要在这里调用 https://api.mail.tm/messages/{id}/get 
						则需要创建新的 web.rest.jsonClient
						*/
					}
				}
			);
			
		}, winform, mailState
	)
}

// 手动刷新
winform.btnRefresh.oncommand = function(){
 
	winform.btnRefresh.disabledText = ['\uF254','\uF251','\uF252','\uF253','\uF250']
	winform.listview.clear(); 
	
	thread.invoke(
		function(winform){
			
			// 调用 mail.tm 接口获取邮件列表
			
			import web.rest.jsonClient;
			var http = web.rest.jsonClient();
			http.setAuthToken(winform.editToken.text);
			
			var mailApi = http.api("https://api.mail.tm/");
			var messages, err = mailApi.messages.get();
			
			if(messages){
				
				var list = messages["hydra:member"];
				for(i=1; #list){
					var mail = list[i]; 
					winform.listview.addItem([
						mail.from.address,
						mail.subject || mail.intro,
						time.iso8601(mail.createdAt).format("%Y/%m/%d %H:%M:%S"),
						mail.id
					]);
				}
				winform.staticStatus.text = "邮件: " + #list;
			}
			
			winform.btnRefresh.disabledText = null;
		}, winform
	)
}

// 查看邮件详情
winform.listview.onSelChanged = function(selected,item,subItem,nmListView){ 
	if(!item) return;
	
	var msgId = winform.listview.getItemText(item,4);
	winform.editContent.text = "正在加载...";
	
	thread.invoke(
		function(winform,msgId){
			// 调用 mail.tm 接口获取邮件详情
			
			import web.rest.jsonClient;
			
			var http = web.rest.jsonClient();
			http.setAuthToken(winform.editToken.text);
			
			var mailApi = http.api("https://api.mail.tm/");
			var detail, err = mailApi.messages[msgId].get();
			
			if(detail){   
				// detail.text 是邮件的文本格式（字符串），detail.html 则是数组
				winform.editContent.text = detail.text  || "(无内容)";
			} 
			
		}, winform,msgId
	)
}

winform.listview.columns = [
	["发件人", 180],
	["主题", -1],
	["时间", 150],
	["ID",0]
]

winform.btnRegister.skin({
	background={default=0xFF0078D4;hover=0xFF1084D8;active=0xFF005A9E;disabled=0xFFCCCCCC};
	color={default=0xFFFFFFFF}
})

winform.btnRefresh.skin({
	background={default=0xFF17A2B8;hover=0xFF1AB3CB;active=0xFF117A8B;disabled=0xFFCCCCCC};
	color={default=0xFFFFFFFF}
})

winform.show();
win.loopMessage();
```

