jaroslav@1202: package ${package}; jaroslav@1202: jaroslav@1202: import java.util.Arrays; jaroslav@1202: import java.util.List; jaroslav@1202: import net.java.html.json.ComputedProperty; jaroslav@1202: import net.java.html.json.Context; jaroslav@1202: import net.java.html.json.Function; jaroslav@1202: import net.java.html.json.Model; jaroslav@1202: import net.java.html.json.OnPropertyChange; jaroslav@1202: import net.java.html.json.OnReceive; jaroslav@1202: import net.java.html.json.Property; jaroslav@1202: jaroslav@1202: @Model(className="TwitterModel", properties={ jaroslav@1202: @Property(name="savedLists", type=Tweeters.class, array = true), jaroslav@1202: @Property(name="activeTweetersName", type=String.class), jaroslav@1202: @Property(name="activeTweeters", type=String.class, array = true), jaroslav@1202: @Property(name="userNameToAdd", type=String.class), jaroslav@1213: @Property(name="loading", type=boolean.class), jaroslav@1202: @Property(name="currentTweets", type=Tweet.class, array = true) jaroslav@1202: }) jaroslav@1202: public class TwitterClient { jaroslav@1202: @Model(className = "Tweeters", properties = { jaroslav@1202: @Property(name="name", type = String.class), jaroslav@1202: @Property(name="userNames", type = String.class, array = true) jaroslav@1202: }) jaroslav@1202: static class Twttrs { jaroslav@1202: } jaroslav@1202: @Model(className = "Tweet", properties = { jaroslav@1202: @Property(name = "from_user", type = String.class), jaroslav@1202: @Property(name = "from_user_id", type = int.class), jaroslav@1202: @Property(name = "profile_image_url", type = String.class), jaroslav@1202: @Property(name = "text", type = String.class), jaroslav@1202: @Property(name = "created_at", type = String.class), jaroslav@1202: }) jaroslav@1202: static final class Twt { jaroslav@1202: @ComputedProperty static String html(String text) { jaroslav@1202: StringBuilder sb = new StringBuilder(320); jaroslav@1202: for (int pos = 0;;) { jaroslav@1202: int http = text.indexOf("http", pos); jaroslav@1202: if (http == -1) { jaroslav@1202: sb.append(text.substring(pos)); jaroslav@1202: return sb.toString(); jaroslav@1202: } jaroslav@1202: int spc = text.indexOf(' ', http); jaroslav@1202: if (spc == -1) { jaroslav@1202: spc = text.length(); jaroslav@1202: } jaroslav@1202: sb.append(text.substring(pos, http)); jaroslav@1202: String url = text.substring(http, spc); jaroslav@1202: sb.append("").append(url).append(""); jaroslav@1202: pos = spc; jaroslav@1202: } jaroslav@1202: } jaroslav@1202: jaroslav@1202: @ComputedProperty static String userUrl(String from_user) { jaroslav@1202: return "http://twitter.com/" + from_user; jaroslav@1202: } jaroslav@1202: } jaroslav@1202: @Model(className = "TwitterQuery", properties = { jaroslav@1202: @Property(array = true, name = "results", type = Twt.class) jaroslav@1202: }) jaroslav@1202: public static final class TwttrQr { jaroslav@1202: } jaroslav@1202: jaroslav@1202: @OnReceive(url="{root}/search.json?{query}&callback={me}", jsonp="me") jaroslav@1202: static void queryTweets(TwitterModel page, TwitterQuery q) { jaroslav@1202: page.getCurrentTweets().clear(); jaroslav@1202: page.getCurrentTweets().addAll(q.getResults()); jaroslav@1213: page.setLoading(false); jaroslav@1202: } jaroslav@1202: jaroslav@1202: @OnPropertyChange("activeTweetersName") jaroslav@1202: static void changeTweetersList(TwitterModel model) { jaroslav@1202: Tweeters people = findByName(model.getSavedLists(), model.getActiveTweetersName()); jaroslav@1202: model.getActiveTweeters().clear(); jaroslav@1202: model.getActiveTweeters().addAll(people.getUserNames()); jaroslav@1202: } jaroslav@1202: jaroslav@1202: @OnPropertyChange({ "activeTweeters", "activeTweetersCount" }) jaroslav@1202: static void refreshTweets(TwitterModel model) { jaroslav@1202: StringBuilder sb = new StringBuilder(); jaroslav@1202: sb.append("rpp=25&q="); jaroslav@1202: String sep = ""; jaroslav@1202: for (String p : model.getActiveTweeters()) { jaroslav@1202: sb.append(sep); jaroslav@1202: sb.append("from:"); jaroslav@1202: sb.append(p); jaroslav@1202: sep = " OR "; jaroslav@1202: } jaroslav@1213: model.setLoading(true); jaroslav@1202: model.queryTweets("http://search.twitter.com", sb.toString()); jaroslav@1202: } jaroslav@1202: jaroslav@1202: private static final Context DEFAULT = Context.findDefault(TwitterClient.class); jaroslav@1202: static { jaroslav@1202: final TwitterModel model = new TwitterModel(DEFAULT); jaroslav@1202: final List svdLst = model.getSavedLists(); jaroslav@1202: svdLst.add(newTweeters("API Design", "JaroslavTulach")); jaroslav@1202: svdLst.add(newTweeters("Celebrities", "JohnCleese", "MCHammer", "StephenFry", "algore", "StevenSanderson")); jaroslav@1202: svdLst.add(newTweeters("Microsoft people", "BillGates", "shanselman", "ScottGu")); jaroslav@1202: svdLst.add(newTweeters("NetBeans", "GeertjanW","monacotoni", "NetBeans", "petrjiricka")); jaroslav@1202: svdLst.add(newTweeters("Tech pundits", "Scobleizer", "LeoLaporte", "techcrunch", "BoingBoing", "timoreilly", "codinghorror")); jaroslav@1202: jaroslav@1202: model.setActiveTweetersName("NetBeans"); jaroslav@1202: jaroslav@1202: model.applyBindings(); jaroslav@1202: } jaroslav@1202: jaroslav@1202: @ComputedProperty jaroslav@1202: static boolean hasUnsavedChanges(List activeTweeters, List savedLists, String activeTweetersName) { jaroslav@1202: Tweeters tw = findByName(savedLists, activeTweetersName); jaroslav@1202: if (activeTweeters == null) { jaroslav@1202: return false; jaroslav@1202: } jaroslav@1202: return !tw.getUserNames().equals(activeTweeters); jaroslav@1202: } jaroslav@1202: jaroslav@1202: @ComputedProperty jaroslav@1202: static int activeTweetersCount(List activeTweeters) { jaroslav@1202: return activeTweeters.size(); jaroslav@1202: } jaroslav@1202: jaroslav@1202: @ComputedProperty jaroslav@1202: static boolean userNameToAddIsValid( jaroslav@1202: String userNameToAdd, String activeTweetersName, List savedLists, List activeTweeters jaroslav@1202: ) { jaroslav@1202: return userNameToAdd != null && jaroslav@1202: userNameToAdd.matches("[a-zA-Z0-9_]{1,15}") && jaroslav@1202: !activeTweeters.contains(userNameToAdd); jaroslav@1202: } jaroslav@1202: jaroslav@1202: @Function jaroslav@1202: static void deleteList(TwitterModel model) { jaroslav@1202: final List sl = model.getSavedLists(); jaroslav@1202: sl.remove(findByName(sl, model.getActiveTweetersName())); jaroslav@1202: if (sl.isEmpty()) { jaroslav@1202: final Tweeters t = new Tweeters(DEFAULT); jaroslav@1202: t.setName("New"); jaroslav@1202: sl.add(t); jaroslav@1202: } jaroslav@1202: model.setActiveTweetersName(sl.get(0).getName()); jaroslav@1202: } jaroslav@1202: jaroslav@1202: @Function jaroslav@1202: static void saveChanges(TwitterModel model) { jaroslav@1202: Tweeters t = findByName(model.getSavedLists(), model.getActiveTweetersName()); jaroslav@1202: int indx = model.getSavedLists().indexOf(t); jaroslav@1202: if (indx != -1) { jaroslav@1202: t.setName(model.getActiveTweetersName()); jaroslav@1202: t.getUserNames().clear(); jaroslav@1202: t.getUserNames().addAll(model.getActiveTweeters()); jaroslav@1202: } jaroslav@1202: } jaroslav@1202: jaroslav@1202: @Function jaroslav@1202: static void addUser(TwitterModel model) { jaroslav@1202: String n = model.getUserNameToAdd(); jaroslav@1202: model.getActiveTweeters().add(n); jaroslav@1202: } jaroslav@1202: @Function jaroslav@1202: static void removeUser(String data, TwitterModel model) { jaroslav@1202: model.getActiveTweeters().remove(data); jaroslav@1202: } jaroslav@1202: jaroslav@1202: private static Tweeters findByName(List list, String name) { jaroslav@1202: for (Tweeters l : list) { jaroslav@1202: if (l.getName() != null && l.getName().equals(name)) { jaroslav@1202: return l; jaroslav@1202: } jaroslav@1202: } jaroslav@1202: return list.isEmpty() ? new Tweeters(DEFAULT) : list.get(0); jaroslav@1202: } jaroslav@1202: jaroslav@1202: private static Tweeters newTweeters(String listName, String... userNames) { jaroslav@1202: Tweeters t = new Tweeters(DEFAULT); jaroslav@1202: t.setName(listName); jaroslav@1202: t.getUserNames().addAll(Arrays.asList(userNames)); jaroslav@1202: return t; jaroslav@1202: } jaroslav@1202: }