From a91d5e80ca1d7086fdf0c7d801ea32bd061b9c89 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 12 Jan 2009 12:32:43 +0000 Subject: [PATCH] Merge new summary view branches changes into trunk --- webcit/auth.c | 10 +- webcit/context_loop.c | 2 +- webcit/iconbar.c | 431 +-------- webcit/messages.c | 99 +- webcit/msg_renderers.c | 35 +- webcit/roomops.c | 167 +++- webcit/static/dragdrop.js | 3 +- webcit/static/iconbaricns.css | 4 +- webcit/static/summaryview.js | 478 ++++++++++ webcit/static/t/box_preferences.html | 12 + webcit/static/t/head.html | 14 +- webcit/static/t/iconbar.html | 13 +- webcit/static/t/load_attachments.html | 2 + webcit/static/t/login.html | 15 +- webcit/static/t/mailsummary_json.html | 5 + webcit/static/t/mailsummary_json_section.html | 3 + webcit/static/t/msg_listview.html | 63 +- webcit/static/t/richedit.html | 4 +- webcit/static/t/roombanner.html | 10 +- webcit/static/t/section_attach_select.html | 2 +- webcit/static/t/section_mailsummary.html | 10 +- webcit/static/t/subject_aiderestart.html | 1 + webcit/static/t/subject_floorconfig.html | 1 + webcit/static/t/subject_inet_aliases.html | 1 + webcit/static/t/subject_pushmail.html | 1 + webcit/static/t/subject_tuning.html | 1 + webcit/static/t/summary_header.html | 11 +- webcit/static/wclib.js | 860 +++++++----------- webcit/static/webcit.css | 246 +++-- webcit/subst.c | 3 + webcit/subst.h | 3 +- webcit/webcit.c | 13 +- webcit/webcit.h | 26 +- 33 files changed, 1395 insertions(+), 1154 deletions(-) create mode 100644 webcit/static/summaryview.js create mode 100644 webcit/static/t/mailsummary_json.html create mode 100644 webcit/static/t/mailsummary_json_section.html create mode 100644 webcit/static/t/subject_aiderestart.html create mode 100644 webcit/static/t/subject_floorconfig.html create mode 100644 webcit/static/t/subject_inet_aliases.html create mode 100644 webcit/static/t/subject_pushmail.html create mode 100644 webcit/static/t/subject_tuning.html diff --git a/webcit/auth.c b/webcit/auth.c index 77dc5c475..5208addb0 100644 --- a/webcit/auth.c +++ b/webcit/auth.c @@ -187,8 +187,6 @@ void become_logged_in(const StrBuf *user, const StrBuf *pass, StrBuf *serv_respo extract_token(WC->cs_inet_email, &buf[4], 3, '|', sizeof WC->cs_inet_email); } - get_pref_long("current_iconbar", &WC->current_iconbar, current_iconbar_menu); - get_preference("floordiv_expanded", &FloorDiv); WC->floordiv_expanded = FloorDiv; } @@ -554,10 +552,6 @@ void do_welcome(void) */ void end_webcit_session(void) { - if (WC->logged_in) { - set_pref_long("current_iconbar", WC->current_iconbar, 0); - } - serv_puts("QUIT"); WC->killthis = 1; /* close() of citadel socket will be done by do_housekeeping() */ @@ -904,6 +898,9 @@ int ConditionalRoomAide(StrBuf *Target, WCTemplputParams *TP) return (WC->is_room_aide == 0); } +int ConditionalIsLoggedIn(StrBuf *Target, WCTemplputParams *TP) { + return (WC->logged_in == 0); +} int ConditionalRoomAcessDelete(StrBuf *Target, WCTemplputParams *TP) { wcsession *WCC = WC; @@ -936,6 +933,7 @@ InitModule_AUTH RegisterConditional(HKEY("COND:AIDE"), 2, ConditionalAide, CTX_NONE); RegisterConditional(HKEY("COND:ROOMAIDE"), 2, ConditionalRoomAide, CTX_NONE); RegisterConditional(HKEY("COND:ACCESS:DELETE"), 2, ConditionalRoomAcessDelete, CTX_NONE); + RegisterConditional(HKEY("COND:LOGGEDIN"), 2, ConditionalIsLoggedIn, CTX_NONE); return ; } diff --git a/webcit/context_loop.c b/webcit/context_loop.c index e0a816e1d..58ecdb6d9 100644 --- a/webcit/context_loop.c +++ b/webcit/context_loop.c @@ -35,7 +35,7 @@ void DestroySession(wcsession **sessions_to_kill) DeleteHash(&((*sessions_to_kill)->attachments)); free_march_list((*sessions_to_kill)); DeleteHash(&((*sessions_to_kill)->hash_prefs)); - DeleteHash(&((*sessions_to_kill)->IconBarSetttings)); + DeleteHash(&((*sessions_to_kill)->IconBarSettings)); DeleteHash(&((*sessions_to_kill)->ServCfg)); FreeStrBuf(&((*sessions_to_kill)->UrlFragment1)); FreeStrBuf(&((*sessions_to_kill)->UrlFragment2)); diff --git a/webcit/iconbar.c b/webcit/iconbar.c index ee216df1d..41e7e73e5 100644 --- a/webcit/iconbar.c +++ b/webcit/iconbar.c @@ -12,22 +12,6 @@ #define IB_PICONLY 1 /**< just a picture */ #define IB_TEXTONLY 2 /**< just text */ - -void do_iconbar(void); -void do_iconbar_roomlist(void); - -/* - * Render the left side iconbar - */ -void do_selected_iconbar(void) { - if (WC->current_iconbar == current_iconbar_roomlist) { - do_iconbar_roomlist(); - } - else { - do_iconbar(); - } -} - void DontDeleteThis(void *Data){} #define IconbarIsEnabled(a, b) IconbarIsENABLED(a, sizeof(a) - 1, b) @@ -35,7 +19,7 @@ void DontDeleteThis(void *Data){} long IconbarIsENABLED(const char *key, size_t keylen, long defval) { void *Data; - if (GetHash(WC->IconBarSetttings, key, keylen, + if (GetHash(WC->IconBarSettings, key, keylen, &Data)) return (long) Data; else @@ -51,6 +35,40 @@ inline const char *PrintInt(void *Prefstr) } #endif +/** Produces a stylesheet which hides any iconbar icons the user does not want */ +void doUserIconStylesheet(void) { + HashPos *pos; + void *Data; + long value; + const char *key; + long HKLen; + + LoadIconSettings(); + output_custom_content_header("text/css"); + hprintf("Cache-Control: private\r\n"); + + begin_burst(); + pos = GetNewHashPos(WC->IconBarSettings, 0); + while(GetNextHashPos(WC->IconBarSettings, pos, &HKLen, &key, &Data)) { + value = (long) Data; + if (value == 0 + && strncasecmp("ib_displayas",key,12) + && strncasecmp("ib_logoff", key, 9)) { + // Don't shoot me for this + wprintf("#%s { display: none !important; }\r\n",key); + } else if (!strncasecmp("ib_users",key, 8) && value != 2) { + wprintf("#online_users { display: none; !important } \r\n"); + } + } + end_burst(); +} + +int ConditionalIsActiveStylesheet(StrBuf *Target, WCTemplputParams *TP) { + long testFor = TP->Tokens->Params[3]->lvalue; + int ib_displayas = IconbarIsEnabled("ib_displayas",IB_PICTEXT); + return (testFor == ib_displayas); +} + void LoadIconSettings(void) { wcsession *WCC = WC; @@ -62,9 +80,8 @@ void LoadIconSettings(void) buf = NewStrBuf();; key = NewStrBuf(); - WCC->current_iconbar = current_iconbar_menu; - if (WCC->IconBarSetttings == NULL) - WCC->IconBarSetttings = NewHash(1, NULL); + if (WCC->IconBarSettings == NULL) + WCC->IconBarSettings = NewHash(1, NULL); /** * The initialized values of these variables also happen to * specify the default values for users who haven't customized @@ -78,7 +95,7 @@ void LoadIconSettings(void) StrBufExtract_token(buf, iconbar, i, ','); StrBufExtract_token(key, buf, 0, '='); val = StrBufExtract_long(buf, 1, '='); - Put(WCC->IconBarSetttings, + Put(WCC->IconBarSettings, ChrPtr(key), StrLength(key), (void*)val, DontDeleteThis); } @@ -92,363 +109,6 @@ void LoadIconSettings(void) FreeStrBuf(&buf); } - -/** - * \brief draw the icon bar??? - */ -void do_iconbar(void) { - int ib_displayas = IB_PICTEXT; /**< pictures and text, pictures, text */ - - LoadIconSettings(); - ib_displayas = IconbarIsEnabled("ib_displayas", IB_PICTEXT); - -/** Site logo */ - if (IconbarIsEnabled("ib_logo", 0)) { - if (ib_displayas != IB_TEXTONLY) { - wprintf("
\" \" " - "
\n" - ); - } - wprintf("\n"); - } - -/** 'Powered by Citadel' logo */ - if (IconbarIsEnabled("ib_citadel", 1) && (ib_displayas != IB_TEXTONLY)) wprintf( - "
" - " " - "\"%s\" " - "
\n", - _("Find out more about Citadel"), - _("CITADEL") - ); - - wprintf("\n"); - - if (IconbarIsEnabled("ib_users", 0) == 2) { - StrBufAppendPrintf(WC->trailing_javascript, - "new Ajax.PeriodicalUpdater('wholist', 'do_template?template=wholist_section', " - "{ method: 'get', frequency: 30 } ); \n" - ); - } -} - - -/** - * \brief roomtree view of the iconbar - * If the user has toggled the icon bar over to a room list, here's where - * we generate its innerHTML... - */ -void do_iconbar_roomlist(void) { - int ib_displayas; - - WC->current_iconbar = current_iconbar_roomlist; - - /** - * The initialized values of these variables also happen to - * specify the default values for users who haven't customized - * their iconbars. These should probably be set in a master - * configuration somewhere. - */ - - LoadIconSettings(); - - ib_displayas = IconbarIsEnabled("ib_displayas", IB_PICTEXT); /* pictures and text, pictures, text */ - -/** Site logo */ - if (IconbarIsEnabled("ib_logo", 0)) { - if (ib_displayas != IB_TEXTONLY) { - wprintf("
\" \" " - "
\n" - ); - } - } - -/** 'Powered by Citadel' logo */ - if (IconbarIsEnabled("ib_citadel", 1) && (ib_displayas != IB_TEXTONLY)) wprintf( - "
" - " " - "\"%s\" " - "
\n", - _("Find out more about Citadel"), - _("CITADEL") - ); - - wprintf("\n"); - - /** embed the room list */ - list_all_rooms_by_floor("iconbar"); - - wprintf("\n"); -} - - /** * \brief display a customized version of the iconbar */ @@ -784,6 +444,7 @@ void commit_iconbar(void) { set_preference("iconbar", iconbar, 1); output_headers(1, 1, 2, 0, 0, 0); + /* TODO: TEMPLATE */ wprintf("
\n"); wprintf("

"); wprintf(_("Customize the icon bar")); @@ -795,7 +456,7 @@ void commit_iconbar(void) { "" " "); wprintf(_("Your icon bar has been updated. Please select any of its " - "choices to continue.")); + "choices to continue.
You may need to force refresh (SHIFT-F5) in order for changes to take effect")); wprintf("\n"); wDumpContent(2); #ifdef DBG_ICONBAR_HASH @@ -809,11 +470,7 @@ void tmplput_iconbar(StrBuf *Target, WCTemplputParams *TP) wcsession *WCC = WC; if ((WCC != NULL) && (WCC->logged_in)) { - wprintf("
"); - do_selected_iconbar(); - /** check for instant messages (these display in a new window) */ - page_popup(); - wprintf("
"); + DoTemplate(HKEY("iconbar"), NULL, &NoCtx); } } @@ -821,10 +478,10 @@ void InitModule_ICONBAR (void) { - WebcitAddUrlHandler(HKEY("iconbar_ajax_menu"), do_iconbar, AJAX); - WebcitAddUrlHandler(HKEY("iconbar_ajax_rooms"), do_iconbar_roomlist, AJAX); + WebcitAddUrlHandler(HKEY("user_iconbar"), doUserIconStylesheet, 0); + WebcitAddUrlHandler(HKEY("commit_iconbar"), commit_iconbar, 0); + RegisterConditional(HKEY("COND:ICONBAR:ACTIVE"), 3, ConditionalIsActiveStylesheet, CTX_NONE); WebcitAddUrlHandler(HKEY("display_customize_iconbar"), display_customize_iconbar, 0); - WebcitAddUrlHandler(HKEY("commit_iconbar"), commit_iconbar, 0); RegisterNamespace("ICONBAR", 0, 0, tmplput_iconbar, 0); } diff --git a/webcit/messages.c b/webcit/messages.c index 3e8d1d054..652083d5a 100644 --- a/webcit/messages.c +++ b/webcit/messages.c @@ -402,8 +402,7 @@ int load_msg_ptrs(char *servcmd, int with_headers) int skipit; if (WCC->summ != NULL) { - if (WCC->summ != NULL) - DeleteHash(&WCC->summ); + DeleteHash(&WCC->summ); } WCC->summ = NewHash(1, Flathash); maxload = 10000; @@ -699,17 +698,26 @@ void readloop(long oper) } break; case VIEW_MAILBOX: + if (!WCC->is_ajax) { + new_summary_view(); + return; + } else { defaultsortorder = 2; sortit = 1; load_seen = 1; - care_for_empty_list = 1; + care_for_empty_list = 0; with_headers = 1; - if (WCC->is_mobile) maxmsgs = 20; + /* Generally using maxmsgs|startmsg is not required + in mailbox view, but we have a 'safemode' for clients + (*cough* Exploder) that simply can't handle too many */ + if (havebstr("maxmsgs")) maxmsgs = ibstr("maxmsgs"); else maxmsgs = 9999999; + if (havebstr("startmsg")) startmsg = lbstr("startmsg"); snprintf(cmd, sizeof(cmd), "MSGS %s|%s||1", (oper == do_search) ? "SEARCH" : "ALL", (oper == do_search) ? bstr("query") : "" ); + } break; case VIEW_BBS: default: @@ -730,8 +738,11 @@ void readloop(long oper) } } + if (!WCC->is_ajax) { output_headers(1, 1, 1, 0, 0, 0); - + } else if (WCC->wc_view == VIEW_MAILBOX) { + jsonMessageListHdr(); + } nummsgs = load_msg_ptrs(cmd, with_headers); if (nummsgs == 0) { if (care_for_empty_list) { @@ -747,9 +758,9 @@ void readloop(long oper) wprintf(_("No messages here.")); } wprintf("

\n"); + goto DONE; } - goto DONE; } if (sortit) { @@ -780,9 +791,6 @@ void readloop(long oper) * If we're to print s.th. above the message list... */ switch (WCC->wc_view) { - case VIEW_MAILBOX: - do_template("summary_header", NULL); - break; case VIEW_BBS: BBViewToolBar = NewStrBuf(); MessageDropdown = NewStrBuf(); @@ -804,7 +812,18 @@ void readloop(long oper) FlushStrBuf(BBViewToolBar); break; } - + WCC->startmsg = startmsg; + WCC->maxmsgs = maxmsgs; + WCC->num_displayed = 0; + + /* Put some helpful data in vars for mailsummary_json */ + svputlong("READLOOP:TOTALMSGS", nummsgs); + svputlong("READLOOP:STARTMSG", startmsg); + svputlong("WCVIEW", WCC->wc_view); + /* + * iterate over each message. if we need to load an attachment, do it here. + */ + if (WCC->wc_view == VIEW_MAILBOX) goto NO_MSG_LOOP; /* * iterate over each message. if we need to load an attachment, do it here. */ @@ -835,14 +854,6 @@ void readloop(long oper) sizeof(addrbook[num_ab-1].ab_name)); addrbook[num_ab-1].ab_msgnum = Msg->msgnum; break; - case VIEW_MAILBOX: /* here we just need the abstract, so render it now. */ - memset(&SubTP, 0, sizeof(WCTemplputParams)); - SubTP.ContextType = CTX_MAILSUM; - SubTP.Context = Msg; - DoTemplate(HKEY("section_mailsummary"), NULL, &SubTP); - - num_displayed++; - break; case VIEW_BBS: /* Tag the mails we want to show in bbview... */ default: if (displayed_msgs == NULL) { @@ -857,19 +868,19 @@ void readloop(long oper) num_displayed++; } } - } + } i++; } DeleteHashPos(&at); - + NO_MSG_LOOP: /* * Done iterating the message list. now tasks we want to do after. */ switch (WCC->wc_view) { - case VIEW_MAILBOX: - do_template("summary_trailer", NULL); - break; + case VIEW_MAILBOX: + DoTemplate(HKEY("mailsummary_json"),NULL, &SubTP); + break; case VIEW_BBS: if (displayed_msgs != NULL) { /** if we do a split bbview in the future, begin messages div here */ @@ -916,10 +927,15 @@ DONE: break; } /** Note: wDumpContent() will output one additional tag. */ + if (WCC->wc_view != VIEW_MAILBOX) { + // We ought to move this out into template wprintf("\n"); /** end of 'content' div */ wDumpContent(1); - - /** free the summary */ + } else { + end_burst(); + } + WCC->startmsg = 0; + WCC->maxmsgs = 0; if (WCC->summ != NULL) { DeleteHash(&WCC->summ); } @@ -1624,6 +1640,31 @@ void h_readfwd(void) { readloop(readfwd);} void h_headers(void) { readloop(headers);} void h_do_search(void) { readloop(do_search);} +void jsonMessageListHdr(void) { + // TODO: make a generic function + hprintf("HTTP/1.1 200 OK\r\n"); + hprintf("Content-type: application/json; charset=utf-8\r\n"); + hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(serv_info.serv_software)); + hprintf("Connection: close\r\n"); + hprintf("Pragma: no-cache\r\nCache-Control: no-store\r\nExpires:-1\r\n"); + begin_burst(); +} +// Spit out the new summary view. This is basically a static page, so clients can cache the layout, all the dirty work is javascript :) +void new_summary_view(void) { + output_headers(1,1,1,0,0,1); + begin_burst(); + DoTemplate(HKEY("msg_listview"),NULL,&NoCtx); + DoTemplate(HKEY("trailing"),NULL,&NoCtx); + end_burst(); +} +/** Output message list in JSON-format */ +void jsonMessageList(void) { + StrBuf *room = sbstr("room"); + WC->is_ajax = 1; + smart_goto(room); + WC->is_ajax = 0; +} + void InitModule_MSG (void) @@ -1668,5 +1709,13 @@ InitModule_MSG WebcitAddUrlHandler(HKEY("postpart"), view_postpart, NEED_URL); WebcitAddUrlHandler(HKEY("postpart_download"), download_postpart, NEED_URL); + // json + WebcitAddUrlHandler(HKEY("roommsgs"), jsonMessageList,0); + + WebcitAddUrlHandler(HKEY("mimepart"), view_mimepart, NEED_URL); + WebcitAddUrlHandler(HKEY("mimepart_download"), download_mimepart, NEED_URL); + WebcitAddUrlHandler(HKEY("postpart"), view_postpart, NEED_URL); + WebcitAddUrlHandler(HKEY("postpart_download"), download_postpart, NEED_URL); + return ; } diff --git a/webcit/msg_renderers.c b/webcit/msg_renderers.c index c8f367627..f6d31e90f 100644 --- a/webcit/msg_renderers.c +++ b/webcit/msg_renderers.c @@ -403,9 +403,33 @@ void tmplput_MAIL_SUMM_ALLRCPT(StrBuf *Target, WCTemplputParams *TP) HashList *iterate_get_mailsumm_All(StrBuf *Target, WCTemplputParams *TP) { - return WC->summ; + return WC->summ; +} +int Conditional_ROOM_DISPLAY_MSG(StrBuf *Target, WCTemplputParams *TP) { + //message_summary *Msg = (message_summary *) CTX; + wcsubst *subst; + wcsession *WCC = WC; + GetHash(WCC->vars, HKEY("ITERATE:N"), (void *)&subst); + long num_inset = subst->lvalue; + if ((num_inset >= WC->startmsg) && (WCC->num_displayed <= WCC->maxmsgs)) { + WCC->num_displayed = WCC->num_displayed+1; + return 1; // Pass GO, collect $200 + } + return 0; +} +int Conditional_MAIL_SUMM_LASTMSG(StrBuf *Target, WCTemplputParams *TP) { + wcsubst *nsubst, *n_dsubst; + long is_last_n; + + GetHash(WC->vars, HKEY("ITERATE:LASTN"), (void *)&nsubst); + is_last_n = nsubst->lvalue; + + //GetHash(WC->vars, HKEY("ITERATE:N"), (void *)&n_dsubst); + //num_inset = n_dsubst->lvalue; + + // Is the num_displayed higher than maxmsgs? OR last in iterator + return ((WC->num_displayed > WC->maxmsgs) || (is_last_n == 1)); } - void examine_time(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) { Msg->date = StrTol(HdrLine); @@ -622,7 +646,6 @@ void examine_msg4_partnum(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCh StrBufTrim(Msg->MsgBody->PartNum); } - void examine_content_lengh(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) { Msg->MsgBody->length = StrTol(HdrLine); @@ -717,7 +740,7 @@ int Conditional_MAIL_MIME_ATTACH(StrBuf *Target, WCTemplputParams *TP) /*----------------------------------------------------------------------------*/ void tmplput_QUOTED_MAIL_BODY(StrBuf *Target, WCTemplputParams *TP) { - long MsgNum; + long MsgNum; StrBuf *Buf; MsgNum = LBstr(TKEY(0)); @@ -1083,7 +1106,6 @@ InitModule_MSGRENDERERS RegisterIterator("MAIL:SUMM:MSGS", 0, NULL, iterate_get_mailsumm_All, NULL,NULL, CTX_MAILSUM, CTX_NONE, IT_NOFLAG); - /* render parts of the message struct */ RegisterNamespace("MAIL:SUMM:DATEBRIEF", 0, 0, tmplput_MAIL_SUMM_DATE_BRIEF, CTX_MAILSUM); RegisterNamespace("MAIL:SUMM:DATEFULL", 0, 0, tmplput_MAIL_SUMM_DATE_FULL, CTX_MAILSUM); RegisterNamespace("MAIL:SUMM:DATENO", 0, 0, tmplput_MAIL_SUMM_DATE_NO, CTX_MAILSUM); @@ -1102,7 +1124,8 @@ InitModule_MSGRENDERERS RegisterNamespace("MAIL:SUMM:INREPLYTO", 0, 2, tmplput_MAIL_SUMM_INREPLYTO, CTX_MAILSUM); RegisterNamespace("MAIL:BODY", 0, 2, tmplput_MAIL_BODY, CTX_MAILSUM); RegisterNamespace("MAIL:QUOTETEXT", 1, 2, tmplput_QUOTED_MAIL_BODY, CTX_NONE); - + RegisterConditional(HKEY("COND:ROOM:DISPLAYMSG"), 0, Conditional_ROOM_DISPLAY_MSG, CTX_MAILSUM); + RegisterConditional(HKEY("COND:MAIL:SUMM:LASTMSG"), 0, Conditional_MAIL_SUMM_LASTMSG, CTX_MAILSUM); RegisterConditional(HKEY("COND:MAIL:SUMM:RFCA"), 0, Conditional_MAIL_SUMM_RFCA, CTX_MAILSUM); RegisterConditional(HKEY("COND:MAIL:SUMM:UNREAD"), 0, Conditional_MAIL_SUMM_UNREAD, CTX_MAILSUM); RegisterConditional(HKEY("COND:MAIL:SUMM:H_NODE"), 0, Conditional_MAIL_SUMM_H_NODE, CTX_MAILSUM); diff --git a/webcit/roomops.c b/webcit/roomops.c index 8fd6dc5f2..e7a8441b9 100644 --- a/webcit/roomops.c +++ b/webcit/roomops.c @@ -10,6 +10,22 @@ char floorlist[MAX_FLOORS][SIZ]; /**< list of our floor names */ char *viewdefs[9]; /**< the different kinds of available views */ +/** See GetFloorListHash and GetRoomListHash for info on these. Basically we pull LFLR/LKRA etc. and set up a room HashList with these keys. */ +const char FLOOR_PARAM_NAMES[(FLOOR_PARAM_LEN + 1)][15] = {"ID", + "NAME", + "ROOMS"}; +const char ROOM_PARAM_NAMES[(ROOM_PARAM_LEN + 1)][20] = {"NAME", + "FLAG", + "FLOOR", + "LISTORDER", + "ACL", + "CURVIEW", + "DEFVIEW", + "LASTCHANGE"}; +// Because avoiding strlen at run time is a Good Thing(TM) +const int FLOOR_PARAM_NAMELEN[(FLOOR_PARAM_LEN +1)] = {2, 4, 5}; +const int ROOM_PARAM_NAMELEN[(ROOM_PARAM_LEN +1)] = {4, 4, 5, 9, 3, 7, 7, 8}; + void display_whok(void); /* @@ -436,7 +452,7 @@ void embed_search_o_matic(StrBuf *Target, WCTemplputParams *TP) wprintf(_("Search: ")); wprintf("\n" ); wprintf("\n"); @@ -608,12 +624,12 @@ void embed_room_banner(char *got, int navbar_style) { case VIEW_MAILBOX: wprintf( "
  • " - "" + "" "" "" "%s" - "
  • \n", _("View message list") + "\n", _("Refresh message list") ); break; case VIEW_WIKI: @@ -1131,7 +1147,7 @@ void display_editroom(void) char node[256]; char remote_room[128]; char recp[1024]; - char er_name[128] = ""; + char er_name[128]; char er_password[10]; char er_dirname[15]; char er_roomaide[26]; @@ -3282,7 +3298,6 @@ void do_iconbar_view(struct folder *fold, int max_folders, int num_floors) { char floordiv_id[32]; int levels, oldlevels; int i, t; - int num_drop_targets = 0; char *icon = NULL; strcpy(floor_name, ""); @@ -3381,30 +3396,6 @@ void do_iconbar_view(struct folder *fold, int max_folders, int num_floors) { wprintf("\n"); /** floordiv */ - /** BEGIN: The old invisible pixel trick, to get our JavaScript to initialize */ - wprintf(" 1) { - wprintf("drop_targets_elements[%d]=$('roomdiv%d');\n", num_drop_targets, i); - wprintf("drop_targets_roomnames[%d]='", num_drop_targets); - jsescputs(fold[i].room); - wprintf("';\n"); - ++num_drop_targets; - } - } - - wprintf("num_drop_targets = %d;\n", num_drop_targets); - if ((ChrPtr(WC->floordiv_expanded)[0] != '\0')&& - (ChrPtr(WC->floordiv_expanded)[1] != '\0')){ - wprintf("which_div_expanded = '%s';\n", ChrPtr(WC->floordiv_expanded)); - } - - wprintf("\">\n"); - /** END: The old invisible pixel trick, to get our JavaScript to initialize */ } @@ -3715,7 +3706,108 @@ void set_room_policy(void) { display_editroom(); } - +HashList *GetFloorListHash(StrBuf *Target, WCTemplputParams *TP) { + // todo: check context + const char *Err; + StrBuf *Buf; + StrBuf *Buf2; + HashList *floors; + HashList *floor; + floors = NewHash(1, NULL); + Buf = NewStrBuf(); + serv_puts("LFLR"); // get floors + StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err); // '100', we hope + if (ChrPtr(Buf)[0] == '1') while(StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err), strcmp(ChrPtr(Buf), "000")) { + floor = NewHash(1, NULL); + int a; + const char *floorNum; + for(a=0; aContext); + void *value; + GetHash(floor, TKEY(0), &value); + StrBuf *val = (StrBuf *)value; + StrECMAEscAppend(TemplBuffer, val, 0); +} +HashList *GetRoomListHashLKRA(StrBuf *Target, WCTemplputParams *TP) { + serv_puts("LKRA"); + return GetRoomListHash(Target, TP); +} +HashList *GetRoomListHash(StrBuf *Target, WCTemplputParams *TP) { + // TODO: Check context + HashList *rooms; + HashList *room; + StrBuf *buf; + StrBuf *buf2; + const char *Err; + buf = NewStrBuf(); + rooms = NewHash(1, NULL); + StrBufTCP_read_line(buf, &WC->serv_sock, 0, &Err); + if (ChrPtr(buf)[0] == '1') while(StrBufTCP_read_line(buf, &WC->serv_sock, 0, &Err), strcmp(ChrPtr(buf), "000")) { + room = NewHash(1, NULL); + int i; + const char *rmName; + for(i=0; i l2) return +1; + else return 0; +} +void tmplput_ROOM_Value(StrBuf *TemplBuffer, WCTemplputParams *TP) { + HashList *room = (HashList *)(TP->Context); + void *value; + GetHash(room, TKEY(0), &value); + StrBuf *val = (StrBuf *)value; + StrECMAEscAppend(TemplBuffer, val, 0); +} +void jsonRoomFlr(void) { + // Send as our own (application/json) content type + hprintf("HTTP/1.1 200 OK\r\n"); + hprintf("Content-type: application/json; charset=utf-8\r\n"); + hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(serv_info.serv_software)); + hprintf("Connection: close\r\n"); + hprintf("Pragma: no-cache\r\nCache-Control: no-store\r\nExpires:-1\r\n"); + begin_burst(); + DoTemplate(HKEY("json_roomflr"),NULL,&NoCtx); + end_burst(); +} void tmplput_RoomName(StrBuf *Target, WCTemplputParams *TP) { StrBufAppendTemplate(Target, TP, WC->wc_roomname, 0); @@ -3893,11 +3985,11 @@ void InitModule_ROOMOPS (void) { - RegisterPreference(HKEY("roomlistview"), - _("Room list view"), - PRF_STRING, - NULL); - RegisterPreference(HKEY("emptyfloors"), _("Show empty floors"), PRF_YESNO, NULL); + RegisterPreference(HKEY("roomlistview"), + _("Room list view"), + PRF_STRING, + NULL); + RegisterPreference(HKEY("emptyfloors"), _("Show empty floors"), PRF_YESNO, NULL); RegisterNamespace("ROOMNAME", 0, 1, tmplput_RoomName, 0); @@ -3924,6 +4016,7 @@ InitModule_ROOMOPS WebcitAddUrlHandler(HKEY("set_floordiv_expanded"), set_floordiv_expanded, NEED_URL|AJAX); WebcitAddUrlHandler(HKEY("changeview"), change_view, 0); WebcitAddUrlHandler(HKEY("toggle_self_service"), toggle_self_service, 0); + WebcitAddUrlHandler(HKEY("json_roomflr"), jsonRoomFlr, 0); RegisterNamespace("ROOMBANNER", 0, 1, tmplput_roombanner, 0); RegisterConditional(HKEY("COND:ROOM:FLAGS:QR_PERMANENT"), 0, ConditionalRoomHas_QR_PERMANENT, CTX_NONE); @@ -3946,6 +4039,10 @@ InitModule_ROOMOPS RegisterConditional(HKEY("COND:ROOM:EDITACCESS"), 0, ConditionalHaveRoomeditRights, CTX_NONE); RegisterNamespace("ROOM:UNGOTO", 0, 0, tmplput_ungoto, 0); + RegisterIterator("FLOORS", 0, NULL, GetFloorListHash, NULL, DeleteHash, CTX_FLOORS, CTX_NONE, IT_NOFLAG); + RegisterNamespace("FLOOR:INFO", 1, 2, tmplput_FLOOR_Value, CTX_FLOORS); + RegisterIterator("LKRA", 0, NULL, GetRoomListHashLKRA, NULL, NULL, CTX_ROOMS, CTX_NONE, IT_NOFLAG); + RegisterNamespace("ROOM:INFO", 1, 2, tmplput_ROOM_Value, CTX_ROOMS); } /*@}*/ diff --git a/webcit/static/dragdrop.js b/webcit/static/dragdrop.js index bf429c261..81fca6b12 100644 --- a/webcit/static/dragdrop.js +++ b/webcit/static/dragdrop.js @@ -36,8 +36,9 @@ var Droppables = { } if(options.accept) options.accept = [options.accept].flatten(); - + if (Prototype.Browser.IE) { Element.makePositioned(element); // fix IE +} options.element = element; this.drops.push(options); diff --git a/webcit/static/iconbaricns.css b/webcit/static/iconbaricns.css index 438c54627..395b70668 100644 --- a/webcit/static/iconbaricns.css +++ b/webcit/static/iconbaricns.css @@ -1,9 +1,9 @@ -#button > li { +#button > li , #ib_logoff { min-height: 32px; background-repeat: no-repeat !important; vertical-align: middle; } -#button > li > a { +#button > li > a , #ib_logoff > a { padding-top: 6px; padding-left: 35px; min-height: 25px; /* Makes all of the 'button' to be clickable */ diff --git a/webcit/static/summaryview.js b/webcit/static/summaryview.js new file mode 100644 index 000000000..f9932eb23 --- /dev/null +++ b/webcit/static/summaryview.js @@ -0,0 +1,478 @@ +/** Webcit Summary View v2 + All comments, flowers and death threats to Mathew McBride + / +*/ +document.observe("dom:loaded", createMessageView); + +var message_view = null; +var loadingMsg = null; +var rowArray = null; +var currentSortMode = null; + +// Header elements +var mlh_date = null; +var mlh_subject = null; +var mlh_from = null; +var currentSorterToggle = null; +var query = ""; +var currentlyMarkedRows = new Object(); + +var mouseDownEvent = null; +var exitedMouseDown = false; + +var sortModes = { + "rdate" : sortRowsByDateDescending, + "date" : sortRowsByDateAscending, + // "reverse" : sortRowsByDateDescending, + "subj" : sortRowsBySubjectAscending, + "rsubj" : sortRowsBySubjectDescending, + "sender": sortRowsByFromAscending, + "rsender" : sortRowsByFromDescending +}; +var toggles = {}; +window.console = window.console || {}; +var opera = opera || null; +if (opera && opera.postError) { + console.log = opera.postError; +} +var nummsgs = 0; +var startmsg = 0; +function createMessageView() { + message_view = document.getElementById("message_list_body"); + loadingMsg = document.getElementById("loading"); + getMessages(); + mlh_date = $("mlh_date"); + mlh_subject = $('mlh_subject'); + mlh_from = $('mlh_from'); + toggles["rdate"] = mlh_date; + toggles["date"] = mlh_date; + // toggles["reverse"] = mlh_date; + toggles["subj"] = mlh_subject; + toggles["rsubj"] = mlh_subject; + toggles["sender"] = mlh_from; + toggles["rsender"] = mlh_from; + mlh_date.observe('click',ApplySort); + mlh_subject.observe('click',ApplySort); + mlh_from.observe('click',ApplySort); + $(document).observe('keyup',CtdlMessageListKeyUp,false); + window.oncontextmenu = function() { return false; }; + $('resize_msglist').observe('mousedown', CtdlResizeMouseDown); + $('m_refresh').observe('click', getMessages); + document.getElementById('m_refresh').setAttribute("href","#"); + Event.observe(document.onresize ? document : window, "resize", normalizeHeaderTable); + sizePreviewPane(); + Event.observe(document.onresize ? document : window, "resize", sizePreviewPane); + $('summpage').observe('change', getPage); + takeOverSearchOMatic(); +} +function getMessages() { + if (loadingMsg.parentNode == null) { + message_view.innerHTML = ""; + message_view.appendChild(loadingMsg); + } +roomName = getTextContent(document.getElementById("rmname")); + var parameters = {'room':roomName, 'startmsg': startmsg}; + if (is_safe_mode) { + parameters['maxmsgs'] = 500; + if (currentSortMode != null) { + var SortBy = currentSortMode[0]; + if (SortBy.charAt(0) == 'r') { + SortBy = SortBy.substr(1); + parameters["SortOrder"] = "2"; + } + parameters["SortBy"] = SortBy; + } + } + if (query.length > 0) { + parameters["query"] = query; + } +new Ajax.Request("roommsgs", { + method: 'get', + onSuccess: loadMessages, + parameters: parameters, + sanitize: false, + evalJSON: false, + onFailure: function(e) { alert("Failure: " + e);} + }); +} +function loadMessages(transport) { + try { + var data = eval('('+transport.responseText+')'); + if (!!data && transport.responseText.length < 2) { + alert("Message loading failed"); + } + nummsgs = data['nummsgs']; + var msgs = data['msgs']; + var length = msgs.length; + rowArray = new Array(); // store so they can be sorted + var start = new Date(); + for(var i=0; i + + + + + > + + >
    + Safe mode is less intensive on your web browser, but not as fully featured. + + diff --git a/webcit/static/t/head.html b/webcit/static/t/head.html index a57700d03..1a4ba1700 100644 --- a/webcit/static/t/head.html +++ b/webcit/static/t/head.html @@ -10,14 +10,26 @@ - + + +stylesheet" type="text/css" id="style_iconbar_icns" title="Default iconbar"> +stylesheet" type="text/css" id="style_iconbar_piconly" title="Iconbar without text"> + + + + + + + +
    diff --git a/webcit/static/t/iconbar.html b/webcit/static/t/iconbar.html index 974e6a78a..80a4f861a 100644 --- a/webcit/static/t/iconbar.html +++ b/webcit/static/t/iconbar.html @@ -47,6 +47,7 @@ now")>"> +
    • @@ -65,15 +66,15 @@ now")>"> ">
    • -
    • + +
    • +
      + +
      + -
      -
      \ No newline at end of file diff --git a/webcit/static/t/load_attachments.html b/webcit/static/t/load_attachments.html index 6f6313f81..2e89c639c 100644 --- a/webcit/static/t/load_attachments.html +++ b/webcit/static/t/load_attachments.html @@ -1 +1,3 @@ +-------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- diff --git a/webcit/static/t/login.html b/webcit/static/t/login.html index 0dddc2daa..3657a3ea6 100644 --- a/webcit/static/t/login.html +++ b/webcit/static/t/login.html @@ -1,22 +1,25 @@ +
      +
      - +
      -
      +



      +
      " class="logbutton"> @@ -32,18 +35,20 @@
      -
      + - + +
      + diff --git a/webcit/static/t/mailsummary_json.html b/webcit/static/t/mailsummary_json.html new file mode 100644 index 000000000..d5a4eabf5 --- /dev/null +++ b/webcit/static/t/mailsummary_json.html @@ -0,0 +1,5 @@ +{ "nummsgs": , +"startmsg": , +"roomname": "", +"msgs": [ ] +} \ No newline at end of file diff --git a/webcit/static/t/mailsummary_json_section.html b/webcit/static/t/mailsummary_json_section.html new file mode 100644 index 000000000..7f6e00363 --- /dev/null +++ b/webcit/static/t/mailsummary_json_section.html @@ -0,0 +1,3 @@ + +[,"","",,"", ] , + \ No newline at end of file diff --git a/webcit/static/t/msg_listview.html b/webcit/static/t/msg_listview.html index 666daf2f7..60c99b077 100644 --- a/webcit/static/t/msg_listview.html +++ b/webcit/static/t/msg_listview.html @@ -1,32 +1,33 @@ - + - -
      - - - - - - SortByStrings[SubjectInvertSortString[SortBy]], - SortIcons[SortSubjectToIcon[SortBy]], - SortByStrings[SenderInvertSortString[SortBy]], - SortIcons[SortSenderToIcon[SortBy]], - SortByStrings[DateInvertSortString[SortBy]], - SortIcons[SortDateToIcon[SortBy]], -
      %> - -%> - -%> - -  - "> -
      -
      -
      - - +
      +
      + + + + + +
      +
      +
      +
      +
      +

      Loading animation

      +

      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      \ No newline at end of file diff --git a/webcit/static/t/richedit.html b/webcit/static/t/richedit.html index b09bc62ed..e71c5934a 100644 --- a/webcit/static/t/richedit.html +++ b/webcit/static/t/richedit.html @@ -1,5 +1,5 @@ - - +
      + \ No newline at end of file diff --git a/webcit/static/wclib.js b/webcit/static/wclib.js index 1d04a9e50..b2d62e1a7 100644 --- a/webcit/static/wclib.js +++ b/webcit/static/wclib.js @@ -9,24 +9,51 @@ var browserType; var room_is_trash = 0; -if (document.layers) { - browserType = "nn4"; -} -if (document.all) { - browserType = "ie"; -} +var currentlyExpandedFloor = null; +var roomlist = null; + +var _switchToRoomList = "switch to room list"; +var _switchToMenu = "switch to menu"; + +var currentDropTarget = null; + +var supportsAddEventListener = (!!document.addEventListener); +var today = new Date(); + +if (document.all) {browserType = "ie"} if (window.navigator.userAgent.toLowerCase().match("gecko")) { browserType= "gecko"; } - var ns6=document.getElementById&&!document.all; Event.observe(window, 'load', ToggleTaskDateOrNoDateActivate); Event.observe(window, 'load', taskViewActivate); +//document.observe("dom:loaded", setupPrefEngine); +document.observe("dom:loaded", setupIconBar); function CtdlRandomString() { return((Math.random()+'').substr(3)); } - +function emptyElement(element) { + childNodes = element.childNodes; + for(var i=0; i 0) { - for (i=0; i 0) ) { - for (i=0; i 0) { - for (i=0; i 0) { - new Ajax.Request( - 'ajax_servcmd', { - method: 'post', - parameters: 'g_cmd=DELE ' + CtdlMsgsSelected[i], - onComplete: CtdlClearDeletedMsg(CtdlMsgsSelected[i]) - } - ); - } - else { - new Ajax.Request( - 'ajax_servcmd', { - method: 'post', - parameters: 'g_cmd=MOVE ' + CtdlMsgsSelected[i] + '|_TRASH_|0', - onComplete: CtdlClearDeletedMsg(CtdlMsgsSelected[i]) - } - ); - } - } - CtdlNumMsgsSelected = 0; - - // Clear the preview pane too. - $('preview_pane').innerHTML = ''; -} - - -// Move selected messages. -function CtdlMoveSelectedMessages(evt, target_roomname) { - - if (CtdlNumMsgsSelected < 1) { - // Nothing to delete, so exit silently. - return false; - } - for (i=0; i
      "; - for (i=0; i'; - } - drag_o_text = drag_o_text + "
      "; - - mm_div = document.createElement("DIV"); - mm_div.style.position='absolute'; - mm_div.style.top = y + 'px'; - mm_div.style.left = x + 'px'; - mm_div.style.pixelHeight = '300'; - mm_div.style.pixelWidth = '300'; - mm_div.innerHTML = drag_o_text; - document.body.appendChild(mm_div); - } - else { - mm_div.style.top = y + 'px'; - mm_div.style.left = x + 'px'; - } - - return false; // prevent the default mouse action from happening? -} - -function CtdlMoveMsgMouseUp(evt) { - document.onmouseup = null; - document.onmousemove = null; - if (document.layers) { - document.releaseEvents(Event.MOUSEUP | Event.MOUSEMOVE); - } - - if (mm_div) { - document.body.removeChild(mm_div); - mm_div = null; - } - - if (num_drop_targets < 1) { // nowhere to drop - return true; - } - - // Did we release the mouse button while hovering over a drop target? - // NOTE: this only works cross-browser because the iconbar div is always - // positioned at 0,0. Browsers differ in whether the 'offset' - // functions return pos relative to the document or parent. - - for (i=0; i= l) && (x <= r) && (y >= t) && (y <= b) ) { - // Yes, we dropped it on a hotspot. - CtdlMoveSelectedMessages(evt, drop_targets_roomnames[i]); - return true; - } - } - - return true; -} - - function ctdl_ts_getInnerText(el) { if (typeof el == "string") return el; if (typeof el == "undefined") { return el }; @@ -798,67 +546,6 @@ function ctdl_ts_getInnerText(el) { } -function CtdlShowRaw(msgnum) { -var customnav = document.createElement("span"); -var mode_citadel = document.createElement("a"); -mode_citadel.appendChild(document.createTextNode("Citadel Source")); -var mode_rfc822 = document.createElement("a"); -mode_rfc822.appendChild(document.createTextNode(" RFC822 Source")); -mode_citadel.setAttribute("href","#"); -mode_rfc822.setAttribute("href","#"); -mode_rfc822.setAttribute("onclick","rawSwitch822('" + msgnum + "');"); -mode_citadel.setAttribute("onclick","rawSwitchCitadel('" + msgnum + "');"); -customnav.appendChild(mode_citadel); -customnav.appendChild(mode_rfc822); -customnav.setAttribute("class","floatcustomnav"); -floatwindow("headerscreen","pre",customnav); -rawSwitch822(msgnum); -} - -function rawSwitch822(msgnum) { -CtdlLoadScreen("headerscreen"); -new Ajax.Updater("headerscreen", -'ajax_servcmd_esc', - { method: 'post',parameters: 'g_cmd=MSG2 ' +msgnum } ); - -} - -function rawSwitchCitadel(msgnum) { -CtdlLoadScreen("headerscreen"); -new Ajax.Updater("headerscreen", -'ajax_servcmd_esc', - { method: 'post',parameters: 'g_cmd=MSG0 ' +msgnum } ); - -} - -function floatwindow(newdivid,contentelementtype,customnav) { -var windiv = document.createElement("div"); -windiv.setAttribute("class","floatwindow"); -var winid = newdivid+"_window"; -windiv.setAttribute("id",winid); -var nav = document.createElement("div"); -if (customnav != null) { -nav.appendChild(customnav); -} -var minimizeA = document.createElement("a"); -var minimizeButton = document.createTextNode("Close"); -minimizeA.appendChild(minimizeButton); -minimizeA.setAttribute("onclick","killFloatWindow(this);"); -minimizeA.setAttribute("href","#"); -nav.appendChild(minimizeA); -nav.setAttribute("class","floatnav"); -windiv.appendChild(nav); -var contentarea = document.createElement("pre"); -contentarea.setAttribute("class","floatcontent"); -contentarea.setAttribute("id",newdivid); -windiv.appendChild(contentarea); -document.body.appendChild(windiv); -} -function killFloatWindow(caller) { -var span = caller.parentNode; -var fwindow = span.parentNode; -fwindow.parentNode.removeChild(fwindow); -} // Place a gradient loadscreen on an element, e.g to use before Ajax.updater function CtdlLoadScreen(elementid) { var elem = document.getElementById(elementid); @@ -924,9 +611,9 @@ function HandleRSVP(question_divname, title_divname, msgnum, cal_partnum, sc) { new Ajax.Updater(title_divname, 'handle_rsvp', { method: 'post', parameters: p } ); Effect.Fade(question_divname, { duration: 0.5 }); } -var fakeMouse = document.createEvent("MouseEvents"); -fakeMouse.initMouseEvent("click", true, true, window, - 0,0,0,0,0, false, false, false, false, 0, null); +/* var fakeMouse = document.createEvent("MouseEvents"); + fakeMouse.initMouseEvent("click", true, true, window, + 0,0,0,0,0, false, false, false, false, 0, null); */ // TODO: Collapse into one function function toggleTaskDtStart(event) { var checkBox = $('nodtstart'); @@ -986,3 +673,84 @@ function eventEditAllDay() { dtend.style.textDecoration = ""; } } + + + + +// Functions which handle show/hide of various elements in the recurrence editor + +function RecurrenceShowHide() { + + if ($('is_recur').checked) { + $('rrule_div').style.display = 'block'; + } + else { + $('rrule_div').style.display = 'none'; + } + + if ($('freq_selector').selectedIndex == 4) { + $('weekday_selector').style.display = 'block'; + } + else { + $('weekday_selector').style.display = 'none'; + } + + if ($('freq_selector').selectedIndex == 5) { + $('monthday_selector').style.display = 'block'; + } + else { + $('monthday_selector').style.display = 'none'; + } + + if ($('rrend_count').checked) { + $('rrcount').disabled = false; + } + else { + $('rrcount').disabled = true; + } + + if ($('rrend_until').checked) { + $('rruntil').disabled = false; + } + else { + $('rruntil').disabled = true; + } + + if ($('rrmonthtype_mday').checked) { + $('rrmday').disabled = false; + } + else { + $('rrmday').disabled = true; + } + + if ($('rrmonthtype_wday').checked) { + $('rrmweek').disabled = false; + $('rrmweekday').disabled = false; + } + else { + $('rrmweek').disabled = true; + $('rrmweekday').disabled = true; + } + + if ($('freq_selector').selectedIndex == 6) { + $('yearday_selector').style.display = 'block'; + } + else { + $('yearday_selector').style.display = 'none'; + } + + $('ymday').innerHTML = 'XXXX-' + $('dtstart').value.substr(5); + $('rrmday').innerHTML = $('dtstart').value.substr(8); + + if ($('rryeartype_ywday').checked) { + $('rrymweek').disabled = false; + $('rrymweekday').disabled = false; + $('rrymonth').disabled = false; + } + else { + $('rrymweek').disabled = true; + $('rrymweekday').disabled = true; + $('rrymonth').disabled = true; + } + +} diff --git a/webcit/static/webcit.css b/webcit/static/webcit.css index 4ab1657a7..55797ad97 100644 --- a/webcit/static/webcit.css +++ b/webcit/static/webcit.css @@ -15,13 +15,16 @@ body { font-size: 11pt} font-size: 13pt; } -#button, #content .msgbuttons a, .button_link a, input#delbutton,.attachfile,.logbuttons input,.buttons input, .buttons a, .customize, .mailbox_summary, .menubar_link, .roomlist_floor, .ib_roomlist_floor, .roomlist_new, .ib_roomlist_new, .roomlist_old, .ib_roomlist_old, #banner ul.room_actions li, #navbar, .selector_top, .selector_bottom, .room_banner .infos,.room_banner .nummsgs,li.search,li.view, .room_actions form select option, .selectbox, #message_list_hdr table, .message_header, ul.adminitems li span { +#button, #content .msgbuttons a, .button_link a, input#delbutton,.attachfile,.logbuttons input,.buttons input, .buttons a, .customize, .mailbox_summary, .menubar_link, .roomlist_floor, .ib_roomlist_floor, .roomlist_new, .ib_roomlist_new, .roomlist_old, .ib_roomlist_old, #banner ul.room_actions li, #navbar, .selector_top, .selector_bottom, .room_banner .infos,.room_banner .nummsgs,li.search,li.view, .room_actions form select option, .selectbox, #message_list_hdr table, .message_header, ul.adminitems li span, #message_list tr > td { font-size: 10pt; } -#wholist li { +#online_users li { font-size: 8pt; } +.marked_row { + color: white; +} /* Color */ @@ -31,7 +34,7 @@ body { font-weight: 400; } -#iconbar, .boxcontent,.service form div,table.altern .odd, #message_list, .message_content, #roomlist_div,.editednode,.mailbox_summary, .auth_validate, .event_background, .calendar_background, .calendar_view_background, .graphics_background, .messages_background, .paging_background, .preferences_background, .roomops_background, .sieve_background, .siteconfig_background, .smtpqueue_background, .tabs_background, .useredit_background, .userlist_background, .downloads_background, .vcard_edit_background, div.auto_complete, div.auto_complete ul { +#iconbar, .boxcontent,.service form div,table.altern .odd, #message_list, .message_content, #roomlist_div,.editednode,.mailbox_summary, .auth_validate, .event_background, .calendar_background, .calendar_view_background, .graphics_background, .messages_background, .paging_background, .preferences_background, .roomops_background, .sieve_background, .siteconfig_background, .smtpqueue_background, .tabs_background, .useredit_background, .userlist_background, .downloads_background, .vcard_edit_background, div.auto_complete, div.auto_complete ul, #summary_view { background-color: #FFF; color: #000; } @@ -41,7 +44,7 @@ body { background-color: #CCC; } -.box, #wholist li.inactiveuser a { +.box, #online_users li.inactiveuser a { background-color: transparent; } @@ -55,7 +58,7 @@ body { text-transform: uppercase; } -#iconbar ul li a, #room_infos, #address_book_popup,.roomops_cell, .roomops_cell_edit, .mimepart { +#iconbar ul li, #room_infos, #address_book_popup,.roomops_cell, .roomops_cell_edit, .mimepart { background-color: #F0FFFF; color: #333; } @@ -76,7 +79,7 @@ body { font-weight: 700; } -#button li { +#button li, #ib_logoff { border: none; border-bottom: 2px groove #CCC; border-right: 2px groove #CCC; @@ -86,17 +89,17 @@ body { border: none; } -.logo,.logo_citadel, #button li.switch { +.logo,.logo_citadel, #switch, #customize { border: none; border-bottom: 1px solid #AAA; } -#button li a { +#button li a , #ib_logoff a{ color: #000; text-decoration: none; } -#wholist li { +#online_users li { border: none; border-top: 1px solid #AAA; } @@ -107,6 +110,8 @@ body { #banner ul.room_actions li.start_page a, #navbar, .selector_top,.selector_bottom { background-color: #022750; + border-top: 1px solid black; + border-bottom: 1px solid black; color: #FFF; } @@ -144,7 +149,7 @@ body { #resize_msglist { background-image: url(/static/resizegrippy.gif); background-position: center; - background-repeat: no-repeat; + background-repeat: no-repeat; } #resize_msglist hr { @@ -417,8 +422,15 @@ var sub { background-color: #EEEECC; } - - +.current_sort_mode { + background-color: white; +} +.marked_row { + background-color: #69aaff !important; +} +#loading { + background-color: white; +} /* Links */ a { text-decoration: none; } @@ -429,7 +441,7 @@ a:link { color: blue; } a:visited { color: purple; } -#important_message, .buttons a:hover, .msgbuttons a:hover, input:hover, #button li a:hover, #wholist li a:hover, #navbar ul li a:hover { +#important_message, .buttons a:hover, .msgbuttons a:hover, input:hover, #button > li:hover, #online_users li a:hover, #navbar ul li a:hover, #ib_logoff:hover { background-color: #AD1C00; color: #FFF; } @@ -485,7 +497,9 @@ body, #global { z-index: 2; padding: 3px; } - +#hellomsg { + text-align: center; +} #login_screen, #logout_screen { margin: 0; padding: 3% 6% 3% 6%; @@ -499,7 +513,12 @@ body, #global { position: absolute; top: 0; left: 0; + bottom: 0; width: 16%; + z-index: 0; + overflow: auto; + overflow-x: hidden !important; + } #banner { @@ -525,44 +544,49 @@ body, #global { height: 82%; overflow: auto; } - +/* Please avoid setting heights for any of the mailbox view elements (except summary_view and resize). In particular, do NOT set any for message_list_hdr as its not good feng shui */ #message_list_hdr { - position: absolute; display: block; top: 0; left: 0; width: 100%; - height: 5%; - overflow: hidden; + padding-bottom: 0; + margin-bottom: 0; + background-color: #CCCCCC; } -#message_list { - position: absolute; - top: 5%; - left: 0; - width: 100%; +#summary_view { height: 20%; overflow: auto; cursor: pointer; } - +#message_list_body { + background-color: white !important; +} +.col1 { + width: 50%; +} +.col2 { + width: 30%; +} +.col3 { + width: 20%; +} +.new_message { + font-weight: bold; !important; +} +#loading { + text-align: center; +} #resize_msglist { - position: absolute; - top: 25%; - left: 0; width: 100%; - height: 1%; overflow: hidden; cursor: s-resize; + height: 1%; } #preview_pane { - position: absolute; - top: 26%; - left: 0%; - width: 100%; - height: 74%; - overflow: auto; + overflow: auto; } .fix_scrollbar_bug { @@ -598,7 +622,25 @@ body, #global { text-align: left; } - +.ctdlTemplate { + display: none; +} +#ctdlContextMenu { + position: fixed; + background-color: white; + border: 1px solid black; +} +.draganddrop { + position: fixed; + display: block; + border: 1px solid black; + z-index: 65535; + background-color: white; + text-align: left; +} +.hidden { + display: none; +} /* Login */ #login_screen .login_message, #login_screen .login_image, .login_hello, #login_screen #login_form { @@ -649,55 +691,36 @@ body, #global { /* Iconbar */ -.logo, .logo_citadel, #iconbar #button, #button li.switch, #wholist { +.logo, .logo_citadel, #iconbar #button, #switch, #customize, #ib_logoff { margin: 0; padding: 0; } -.logo, .logo_citadel, #button li.switch, #wholist li { +.logo, #citlogo, #switch, #customize, #online_users li { text-align: center; } -.logo, .logo_citadel { - display: block; -} - #iconbar #button { width: 100%; } -#button li { +#button > li, #ib_logoff { margin: 4px 8px 4px 8px; padding: 0; + display: block; } - - - -#button img { - vertical-align: middle; - padding-left: 2px; - padding-right: 5px; - width: 32px; - height: 32px; - border: none; +#button > li > a, #ib_logoff > a { + width: 100%; + display: block; } -#button li a { - display: block; - width: 100%; -} - -html>body #button li a { - width: auto; -} - -#wholist { +#online_users { border: 0; max-height: 200px; overflow: auto; -} - -#wholist li { + padding-left: 0; +} +#online_users li { list-style: none; margin: 0; padding: 2px; @@ -764,6 +787,9 @@ html>body #button li a { margin-top: 8px; margin-right: 4px; } +#selectpage { + display: none !important; +} /* Navbar */ @@ -791,8 +817,47 @@ html>body #button li a { float: none; margin: 0 2px 0 2px; } - - +.floor { + margin-left: 0px; +} +.floor > ul { + display: none; +} +.floor-expanded > ul{ + display: block !important; +} +#roomlist > ul { + margin: 0; + padding: 0; +} +#roomlist > div > ul > li { + margin: 0; + padding: 0; +} +/** Override to disable list-style-image" */ +.room { +} +.room-private { + list-style-image: url("/static/privatemess_16x.gif"); +} +.room-addr { + list-style-image: url("/static/viewcontacts_16x.gif"); +} +.room-cal { + list-style-image: url("/static/calarea_16x.gif"); +} +.room-tasks { + list-style-image: url("/static/taskmanag_16x.gif"); +} +.room-notes { + list-style-image: url("/static/storenotes_16x.gif"); +} +.room-chat { + list-style-image: url("/static/chatrooms_16x.gif"); +} +.room-newmsgs { + font-weight: bold; +} /* Content */ .boxcontent table { @@ -822,12 +887,12 @@ html>body #button li a { } #message_list_hdr table { - position: absolute; +/* position: absolute; bottom: 0; left: 0; + top: 0; */ width: 100%; } - .selector_top, .selector_bottom { text-align: center; } @@ -970,10 +1035,6 @@ dt { clear: both; } width: 98% } -.mailbox_summary tr { - width: 100%; -} - .note { font-size: 85%; margin-left: 10%; @@ -990,7 +1051,9 @@ dt { clear: both; } .imsg { text-align: center; } - +#summary_view > table { + width: 100%; +} colgroup.entity { text-align: center; } @@ -1055,7 +1118,35 @@ div.auto_complete ul strong.highlight { display: block; } - +#citlogo { + display: none; /* Overriden later */ +} +.sort_ascending, .sort_descending { + background-repeat: no-repeat; + background-position: center right; +} +.sort_ascending { + background-image: url("/static/down_pointer.gif"); +} +.sort_descending { + background-image: url("/static/up_pointer.gif"); +} +#message_list_hdr > table { + border-collapse: collapse; +} +#message_list_hdr > table > tbody > tr > th { + border-left: 2px solid white; + border-right: 2px solid white; +} +#summary_view > table { + border-collapse: collapse; +} +th.col1 { + border-left: none !important; +} +th.col3 { + border-right: none !important; +} /* System Administration Menu */ ul.adminitems { @@ -1336,6 +1427,9 @@ li.event_unread span, a.event_read_title { vertical-align: middle; border: none; } +.table-row { + background-color: white; +} .table-alt-row { background-color: #DDDDDD; } @@ -1397,4 +1491,4 @@ li.event_unread span, a.event_read_title { .openid_urlarea { background: url('openid-small.gif') no-repeat scroll 0pt 50%; padding-left: 18px; -} +} \ No newline at end of file diff --git a/webcit/subst.c b/webcit/subst.c index 2e35216f7..1b2301d72 100644 --- a/webcit/subst.c +++ b/webcit/subst.c @@ -733,6 +733,9 @@ void StrBufAppendTemplate(StrBuf *Target, case 'X': StrEscAppend(Target, Source, NULL, 0, 0); break; + case 'J': + StrECMAEscAppend(Target, Source, NULL); + break; default: StrBufAppendBuf(Target, Source, 0); } diff --git a/webcit/subst.h b/webcit/subst.h index fa599ebcb..7a68fb1de 100644 --- a/webcit/subst.h +++ b/webcit/subst.h @@ -102,7 +102,8 @@ extern WCTemplputParams NoCtx; #define CTX_FILELIST 11 #define CTX_STRBUF 12 #define CTX_LONGVECTOR 13 - +#define CTX_ROOMS 14 +#define CTX_FLOORS 15 void RegisterNS(const char *NSName, long len, int nMinArgs, diff --git a/webcit/webcit.c b/webcit/webcit.c index 5985982bd..2be182799 100644 --- a/webcit/webcit.c +++ b/webcit/webcit.c @@ -175,11 +175,7 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers } if ( (WC->logged_in) && (!unset_cookies) ) { - wprintf("
      "); - do_selected_iconbar(); - /** check for instant messages (these display in a new window) */ - page_popup(); - wprintf("
      "); + DoTemplate(HKEY("iconbar"), NULL, &NoCtx); } if (do_room_banner == 1) { @@ -194,6 +190,13 @@ void output_headers( int do_httpheaders, /* 1 = output HTTP headers } } +void output_custom_content_header(const char *ctype) { + hprintf("HTTP/1.1 200 OK\r\n"); + hprintf("Content-type: %s; charset=utf-8\r\n",ctype); + hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(serv_info.serv_software)); + hprintf("Connection: close\r\n"); +} + /* * Generic function to do an HTTP redirect. Easy and fun. diff --git a/webcit/webcit.h b/webcit/webcit.h index 270c29343..94a922c33 100644 --- a/webcit/webcit.h +++ b/webcit/webcit.h @@ -365,6 +365,10 @@ struct wcsession { struct march *march; /**< march mode room list */ char reply_to[512]; /**< reply-to address */ HashList *summ; /**< list of messages for mailbox summary view */ + /** Perhaps these should be within a struct instead */ + long startmsg; // message number to start at + long maxmsgs; // maximum messages to display + long num_displayed; // number of messages actually displayed int is_mobile; /**< Client is a handheld browser */ HashList *urlstrings; /**< variables passed to webcit in a URL */ HashList *vars; /**< HTTP variable substitutions for this page */ @@ -385,8 +389,7 @@ struct wcsession { int cache_max_folders; /**< ??? todo */ int cache_num_floors; /**< ??? todo */ time_t cache_timestamp; /**< ??? todo */ - HashList *IconBarSetttings; /**< which icons should be shown / not shown? */ - long current_iconbar; /**< What is currently in the iconbar? */ + HashList *IconBarSettings; /**< which icons should be shown / not shown? */ const StrBuf *floordiv_expanded; /**< which floordiv currently expanded */ int selected_language; /**< Language selected by user */ time_t last_pager_check; /**< last time we polled for instant msgs */ @@ -403,6 +406,8 @@ struct wcsession { HashList *InetCfg; /**< Our inet server config for editing */ StrBuf *trailing_javascript; /**< extra javascript to be appended to page */ + int is_ajax; /** < are we doing an ajax request? */ + int downloaded_prefs; /** Has the client download its prefs yet? */ }; /* values for WC->current_iconbar */ @@ -530,6 +535,7 @@ void output_headers( int do_httpheaders, int unset_cookies, int suppress_check, int cache); +void output_custom_content_header(const char *ctype); void wprintf(const char *format,...)__attribute__((__format__(__printf__,1,2))); void hprintf(const char *format,...)__attribute__((__format__(__printf__,1,2))); void output_static(char *what); @@ -552,6 +558,9 @@ void SetAccessCommand(long Oper); void do_addrbook_view(addrbookent *addrbook, int num_ab); void fetch_ab_name(message_summary *Msg, char *namebuf); void display_vcard(StrBuf *Target, const char *vcard_source, char alpha, int full, char *storename, long msgnum); +void jsonMessageList(void); +void new_summary_view(void); +void getseen(void); void text_to_server(char *ptr); void text_to_server_qp(char *ptr); void confirm_delete_msg(void); @@ -691,7 +700,17 @@ void summary(void); int is_mobile_ua(char *user_agent); void embed_room_banner(char *, int); - +#define FLOOR_PARAM_LEN 3 +extern const char FLOOR_PARAM_NAMES[(FLOOR_PARAM_LEN + 1)][15]; +extern const int FLOOR_PARAM_NAMELEN[(FLOOR_PARAM_LEN + 1)]; +#define FPKEY(a) FLOOR_PARAM_NAMES[a], FLOOR_PARAM_NAMELEN[a] +#define ROOM_PARAM_LEN 8 +extern const char ROOM_PARAM_NAMES[(ROOM_PARAM_LEN + 1)][20]; +extern const int ROOM_PARAM_NAMELEN[(ROOM_PARAM_LEN +1)]; +#define RPKEY(a) ROOM_PARAM_NAMES[a], ROOM_PARAM_NAMELEN[a] +HashList *GetFloorListHash(StrBuf *Target, WCTemplputParams *TP); +HashList *GetRoomListHash(StrBuf *Target, WCTemplputParams *TP); +int SortRoomsByListOrder(const void *room1, const void *room2); /* navbar types that can be passed to embed_room_banner */ enum { navbar_none, @@ -748,3 +767,4 @@ void WebcitAddUrlHandler(const char * UrlString, long UrlSLen, WebcitHandlerFunc #define WC_TIMEFORMAT_24 2 +void LoadIconSettings(void); -- 2.30.2