Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: client/samples/swarm/DataSource.dart

Issue 9314024: Final CL to kill off client/samples . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « client/samples/swarm/Dart_Logo_21.png ('k') | client/samples/swarm/Decoder.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /** The top-level collection of all sections for a user. */
6 // TODO(jimhug): This is known as UserData in the server model.
7 class Sections implements Collection<Section> {
8 final List<Section> _sections;
9
10 Sections(this._sections);
11
12 operator [](int i) => _sections[i];
13
14 int get length() => _sections.length;
15
16 List<String> get sectionTitles() =>
17 CollectionUtils.map(_sections, (s) => s.title);
18
19 void refresh() {
20 // TODO(jimhug): http://b/issue?id=5351067
21 }
22
23 /**
24 * Find the Section object that has a given title.
25 * This is used to integrate well with [ConveyorView].
26 */
27 Section findSection(String name) {
28 return CollectionUtils.find(_sections, (sect) => sect.title == name);
29 }
30
31 // TODO(jimhug): Track down callers!
32 Iterator<Section> iterator() => _sections.iterator();
33
34 // TODO(jimhug): Better support for switching between local dev and server.
35 static bool get runningFromFile() {
36 return window.location.protocol.startsWith('file:');
37 }
38
39 static String get home() {
40 // TODO(jmesserly): window.location.origin not available on Safari 4.
41 // Move this workaround to the DOM code. See bug 5389503.
42 return window.location.protocol + '//' + window.location.host;
43 }
44
45 // This method is exposed for tests.
46 static void initializeFromData(String data, void callback(Sections sects)) {
47 final decoder = new Decoder(data);
48 int nSections = decoder.readInt();
49 final sections = new List<Section>();
50
51 for (int i=0; i < nSections; i++) {
52 sections.add(Section.decode(decoder));
53 }
54 callback(new Sections(sections));
55 }
56
57 static void initializeFromUrl(void callback(Sections sections)) {
58 if (Sections.runningFromFile) {
59 initializeFromData(CannedData.data['user.data'], callback);
60 } else {
61 // TODO(jmesserly): display an error if we fail here! Silent failure bad.
62 new XMLHttpRequest.getTEMPNAME('$home/data/user.data',
63 EventBatch.wrap((request) {
64 // TODO(jimhug): Nice response if get error back from server.
65 // TODO(jimhug): Might be more efficient to parse request in sections.
66 initializeFromData(request.responseText, callback);
67 }));
68 }
69 }
70
71 Section findSectionById(String id) {
72 return CollectionUtils.find(_sections, (section) => section.id == id);
73 }
74
75 /**
76 * Given the name of a section, find its index in the set.
77 */
78 int findSectionIndex(String name) {
79 for (int i = 0; i < _sections.length; i++) {
80 if (name == _sections[i].title) {
81 return i;
82 }
83 }
84 return -1;
85 }
86
87 List<Section> get sections() => _sections;
88
89 // Collection<Section> methods:
90 List map(f(Section element)) {
91 return Collections.map(this, new List(), f);
92 }
93
94 List<Section> filter(bool f(Section element)) {
95 return Collections.filter(this, new List<Section>(), f);
96 }
97 bool every(bool f(Section element)) => Collections.every(this, f);
98 bool some(bool f(Section element)) => Collections.some(this, f);
99 void forEach(void f(Section element)) { Collections.forEach(this, f); }
100
101 // TODO(jmesserly): this should be a property
102 bool isEmpty() => length == 0;
103 }
104
105
106 /** A collection of data sources representing a page in the UI. */
107 class Section {
108 final String id;
109 final String title;
110 ObservableList<Feed> feeds;
111
112 // Public for testing. TODO(jacobr): find a cleaner solution.
113 Section(this.id, this.title, this.feeds);
114
115 void refresh() {
116 for (final feed in feeds) {
117 // TODO(jimhug): http://b/issue?id=5351067
118 }
119 }
120
121 static Section decode(Decoder decoder) {
122 final sectionId = decoder.readString();
123 final sectionTitle = decoder.readString();
124
125 final nSources = decoder.readInt();
126 final feeds = new ObservableList<Feed>();
127 for (int j=0; j < nSources; j++) {
128 feeds.add(Feed.decode(decoder));
129 }
130 return new Section(sectionId, sectionTitle, feeds);
131 }
132
133 Feed findFeed(String id_) {
134 return CollectionUtils.find(feeds, (feed) => feed.id == id_);
135 }
136 }
137
138 /** Provider of a news feed. */
139 class Feed {
140 String id;
141 final String title;
142 final String iconUrl;
143 final String description;
144 ObservableList<Article> articles;
145 ObservableValue<bool> error; // TODO(jimhug): Check if dead code.
146
147 Feed(this.id, this.title, this.iconUrl, [this.description = ''])
148 : articles = new ObservableList<Article>(),
149 error = new ObservableValue<bool>(false);
150
151 static Feed decode(Decoder decoder) {
152 final sourceId = decoder.readString();
153 final sourceTitle = decoder.readString();
154 final sourceIcon = decoder.readString();
155 final feed = new Feed(sourceId, sourceTitle, sourceIcon);
156 final nItems = decoder.readInt();
157
158 for (int i=0; i < nItems; i++) {
159 feed.articles.add(Article.decodeHeader(feed, decoder));
160 }
161 return feed;
162 }
163
164 Article findArticle(String id_) {
165 return CollectionUtils.find(articles, (article) => article.id == id_);
166 }
167
168 void refresh() {}
169 }
170
171
172 /** A single article or posting to display. */
173 class Article {
174 final String id;
175 Date date;
176 final String title;
177 final String author;
178 final bool hasThumbnail;
179 String textBody; // TODO(jimhug): rename to snipppet.
180 final Feed dataSource; // TODO(jimhug): rename to feed.
181 String _htmlBody;
182 String srcUrl;
183 final ObservableValue<bool> unread; // TODO(jimhug): persist to server.
184
185 bool error; // TODO(jimhug): Check if this is dead and remove.
186
187 Article(this.dataSource, this.id, this.date, this.title, this.author,
188 this.srcUrl, this.hasThumbnail, this.textBody,
189 [this._htmlBody = null, bool unread = true, this.error = false])
190 : unread = new ObservableValue<bool>(unread);
191
192 String get htmlBody() {
193 _ensureLoaded();
194 return _htmlBody;
195 }
196
197 String get dataUri() {
198 return Uri.encodeComponent(id).replaceAll(
199 ',', '%2C').replaceAll('%2F', '/');
200 }
201
202 String get thumbUrl() {
203 if (!hasThumbnail) return null;
204
205 var home;
206 if (Sections.runningFromFile) {
207 home = 'http://dart.googleplex.com';
208 } else {
209 home = Sections.home;
210 }
211 // By default images from the real server are cached.
212 // Bump the version flag if you change the thumbnail size, and you want to
213 // get the new images. Our server ignores the query params but it gets
214 // around appengine server side caching and the client side cache.
215 return '$home/data/$dataUri.jpg?v=0';
216 }
217
218 // TODO(jimhug): need to return a lazy Observable<String> and also
219 // add support for preloading.
220 void _ensureLoaded() {
221 if (_htmlBody !== null) return;
222
223 var name = '$dataUri.html';
224 if (Sections.runningFromFile) {
225 _htmlBody = CannedData.data[name];
226 } else {
227 // TODO(jimhug): Remove this truly evil synchronoush xhr.
228 final req = new XMLHttpRequest();
229 req.open('GET', '${Sections.home}/data/$name', false);
230 req.send();
231 _htmlBody = req.responseText;
232 }
233 }
234
235 static Article decodeHeader(Feed source, Decoder decoder) {
236 final id = decoder.readString();
237 final title = decoder.readString();
238 final srcUrl = decoder.readString();
239 final hasThumbnail = decoder.readBool();
240 final author = decoder.readString();
241 final dateInSeconds = decoder.readInt();
242 final snippet = decoder.readString();
243 final date = new Date.fromEpoch(dateInSeconds*1000, new TimeZone.utc());
244 return new Article(source, id, date, title, author, srcUrl, hasThumbnail,
245 snippet);
246 }
247 }
OLDNEW
« no previous file with comments | « client/samples/swarm/Dart_Logo_21.png ('k') | client/samples/swarm/Decoder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698